source: mainline/uspace/lib/c/include/adt/generic_field.h@ 48d4231

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 48d4231 was 5fe7692, checked in by Petr Koupy <petr.koupy@…>, 14 years ago

Removed side effects from map ADTs.

  • Property mode set to 100644
File size: 4.6 KB
RevLine 
[21580dd]1/*
2 * Copyright (c) 2009 Lukas Mejdrech
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[2544442]29/** @addtogroup libc
[21580dd]30 * @{
31 */
32
33/** @file
34 * Generic type field.
35 */
36
[2544442]37#ifndef LIBC_GENERIC_FIELD_H_
38#define LIBC_GENERIC_FIELD_H_
[21580dd]39
40#include <errno.h>
41#include <malloc.h>
42#include <mem.h>
43#include <unistd.h>
44
[820ab55c]45/** Internal magic value for a&nbsp;field consistency check. */
[21580dd]46#define GENERIC_FIELD_MAGIC_VALUE 0x55667788
47
[5fe7692]48/** Generic destructor function pointer. */
49#define DTOR_T(identifier) \
50 void (*identifier)(const void *)
51
[21580dd]52/** Generic type field declaration.
[820ab55c]53 *
54 * @param[in] name Name of the field.
55 * @param[in] type Inner object type.
[21580dd]56 */
[820ab55c]57#define GENERIC_FIELD_DECLARE(name, type) \
58 typedef struct name name##_t; \
59 \
60 struct name { \
61 int size; \
62 int next; \
63 type **items; \
64 int magic; \
65 }; \
66 \
[aaa3f33a]67 int name##_add(name##_t *, type *); \
68 int name##_count(name##_t *); \
[5fe7692]69 void name##_destroy(name##_t *, DTOR_T()); \
70 void name##_exclude_index(name##_t *, int, DTOR_T()); \
[aaa3f33a]71 type **name##_get_field(name##_t *); \
72 type *name##_get_index(name##_t *, int); \
73 int name##_initialize(name##_t *); \
74 int name##_is_valid(name##_t *);
[21580dd]75
76/** Generic type field implementation.
[820ab55c]77 *
78 * Should follow declaration with the same parameters.
79 *
80 * @param[in] name Name of the field.
81 * @param[in] type Inner object type.
[21580dd]82 */
[820ab55c]83#define GENERIC_FIELD_IMPLEMENT(name, type) \
[aaa3f33a]84 int name##_add(name##_t *field, type *value) \
[820ab55c]85 { \
86 if (name##_is_valid(field)) { \
87 if (field->next == (field->size - 1)) { \
88 type **tmp; \
89 tmp = (type **) realloc(field->items, \
90 sizeof(type *) * 2 * field->size); \
91 if (!tmp) \
92 return ENOMEM; \
93 field->size *= 2; \
94 field->items = tmp; \
95 } \
96 field->items[field->next] = value; \
[442ebbe]97 field->next++; \
[820ab55c]98 field->items[field->next] = NULL; \
99 return field->next - 1; \
100 } \
101 return EINVAL; \
102 } \
103 \
[aaa3f33a]104 int name##_count(name##_t *field) \
[820ab55c]105 { \
106 return name##_is_valid(field) ? field->next : -1; \
107 } \
108 \
[5fe7692]109 void name##_destroy(name##_t *field, DTOR_T(dtor)) \
[820ab55c]110 { \
111 if (name##_is_valid(field)) { \
112 int index; \
113 field->magic = 0; \
[5fe7692]114 if (dtor) { \
115 for (index = 0; index < field->next; index++) { \
116 if (field->items[index]) \
117 dtor(field->items[index]); \
118 } \
[820ab55c]119 } \
120 free(field->items); \
121 } \
122 } \
123 \
[5fe7692]124 void name##_exclude_index(name##_t *field, int index, DTOR_T(dtor)) \
[820ab55c]125 { \
126 if (name##_is_valid(field) && (index >= 0) && \
127 (index < field->next) && (field->items[index])) { \
[5fe7692]128 if (dtor) \
129 dtor(field->items[index]); \
[820ab55c]130 field->items[index] = NULL; \
131 } \
132 } \
133 \
[aaa3f33a]134 type *name##_get_index(name##_t *field, int index) \
[820ab55c]135 { \
136 if (name##_is_valid(field) && (index >= 0) && \
137 (index < field->next) && (field->items[index])) \
138 return field->items[index]; \
139 return NULL; \
140 } \
141 \
[aaa3f33a]142 type **name##_get_field(name##_t *field) \
[820ab55c]143 { \
144 return name##_is_valid(field) ? field->items : NULL; \
145 } \
146 \
[aaa3f33a]147 int name##_initialize(name##_t *field) \
[820ab55c]148 { \
149 if (!field) \
150 return EINVAL; \
151 field->size = 2; \
152 field->next = 0; \
153 field->items = (type **) malloc(sizeof(type *) * field->size); \
154 if (!field->items) \
155 return ENOMEM; \
156 field->items[field->next] = NULL; \
157 field->magic = GENERIC_FIELD_MAGIC_VALUE; \
158 return EOK; \
159 } \
160 \
[aaa3f33a]161 int name##_is_valid(name##_t *field) \
[820ab55c]162 { \
163 return field && (field->magic == GENERIC_FIELD_MAGIC_VALUE); \
164 }
[21580dd]165
166#endif
167
168/** @}
169 */
Note: See TracBrowser for help on using the repository browser.