~contact-philipashmore/treedb/master

« back to all changes in this revision

Viewing changes to treedb/array-template-impl.h

  • Committer: Philip Ashmore
  • Date: 2012-04-01 18:32:33 UTC
  • Revision ID: git-v1:2739703677c401fc0e552603449a319403922a41
Version 1.3.0-01

* Added a long description for debian/control

* Added a v3c-comet man page

* Added a treedb-malloc-daemon man page

* Lots of fiddly changes to pass Debians "lintian" checks
  All the DEBIAN*_REQUIRES have changed to DEBIAN*_DEPENDS.
  Since they go into the Build-Depends and Depends fields of the
  debian/control(.in) file, this makes more sense.

* Refactoring
  The avl, list, array, varray, handle-array headers are c-templates.
  While c-templates provide ultimate control, they aren't the most
  intuitive to use.
  Now the c-template headers all have "template" in their name and they
  all have wrapper headers providing the "common use case".

  Take a look at the tests and comet for examples.

* Nested c-template wrappers wrinkle
  One of the side-effects of this refactoring exercise is that it's now
  impossible to use a wrapper from inside the same wrapper.

  Even though this can be done using the c-templates by themselves, the
  reduction in the number of lines of hand-written code is still a win.

  The way around this is to "sed" all the avl wrapper headers to produce
  versions with a "2" at the end of their names and macros, and use
  those in the AVL two-tree allocator.

  Note that this jumping through hoops is because of deficiencies in the
  design of the "C" preprocessor - "m4" and even "make" can define
  macros that define other macros easily.

* treedb-malloc library improvements
  Instead of allocating an insanely huge mamory map, a more modest one
  is created when memory is allocated, and the rest mmapped onto
  /dev/zero.
  The idea is to preserve the start address by changing the ratio of
  read+write pages to read-only pages so the total map is fixed.

* oprofile tests added for treedb-malloc daemon + tests
  FYI

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2010  Philip Ashmore (contact@philipashmore.com)             */
 
2
/* License: LGPLv3.  See LICENSE.txt for the full license.                    */
 
3
 
 
4
#ifdef DOXYGEN_processing
 
5
{
 
6
#endif
 
7
 
 
8
#include "array-template-defines.h"
 
9
 
 
10
#ifdef DOXYGEN_processing
 
11
}
 
12
#endif
 
13
 
 
14
#ifdef __cplusplus
 
15
extern "C" {
 
16
#endif
 
17
 
 
18
/* 10. pointer pack / unpack */
 
19
#ifndef ARRAY_TMPL_omit_unpack_array
 
20
  #define ARRAY_TMPL_unpack_array(x) ARRAY_TMPL_NS(unpack_array)(runtime, x)
 
21
ARRAY_TMPL_prefix ARRAY_TMPL_array_ptr_t
 
22
ARRAY_TMPL_NS(unpack_array)
 
23
( ARRAY_TMPL_runtime_ptr_t runtime
 
24
, ARRAY_TMPL_packed_array_ptr_t p
 
25
) {
 
26
        ARRAY_TMPL_array_ptr_t ret
 
27
                = (ARRAY_TMPL_array_ptr_t)ARRAY_TMPL_unpack_pointer(p);
 
28
        TREEDB_printf8("array::unpack_array : %lu[0x%lx] -> %p\n"
 
29
                , (uintptr_t)p
 
30
                , (uintptr_t)p, (void *)(uintptr_t)ret);
 
31
        return ret;
 
32
}
 
33
#endif
 
34
#ifndef ARRAY_TMPL_omit_pack_array
 
35
  #define ARRAY_TMPL_pack_array(x) ARRAY_TMPL_NS(pack_array)(runtime, x)
 
36
ARRAY_TMPL_prefix ARRAY_TMPL_packed_array_ptr_t
 
37
ARRAY_TMPL_NS(pack_array)
 
38
( ARRAY_TMPL_runtime_ptr_t runtime
 
39
, ARRAY_TMPL_array_ptr_t p
 
40
) {
 
41
        ARRAY_TMPL_packed_array_ptr_t ret = ARRAY_TMPL_pack_pointer(p);
 
42
        TREEDB_printf8("array::pack_array : %p -> %lu[0x%lx]\n"
 
43
                , (void *)(uintptr_t)p, (uintptr_t)ret
 
44
                , (uintptr_t)ret);
 
45
        return ret;
 
46
}
 
47
#endif
 
48
#ifndef ARRAY_TMPL_omit_pack_data
 
49
  #define ARRAY_TMPL_pack_data(x) ARRAY_TMPL_NS(pack_data)(runtime, x)
 
50
ARRAY_TMPL_prefix ARRAY_TMPL_packed_data_ptr_t
 
51
ARRAY_TMPL_NS(pack_data)
 
52
( ARRAY_TMPL_runtime_ptr_t runtime
 
53
, ARRAY_TMPL_data_t * p
 
54
) {
 
55
        ARRAY_TMPL_packed_data_ptr_t ret = ARRAY_TMPL_pack_pointer(p);
 
56
        TREEDB_printf8("handle_array::pack_data : %p -> %lu[0x%lx]\n"
 
57
                , (void *)(uintptr_t)p, (uintptr_t)ret
 
58
                , (uintptr_t)ret);
 
59
        return ret;
 
60
}
 
61
#endif
 
62
#ifndef ARRAY_TMPL_omit_unpack_data
 
63
  #define ARRAY_TMPL_unpack_data(x) ARRAY_TMPL_NS(unpack_data)(runtime, x)
 
64
ARRAY_TMPL_prefix ARRAY_TMPL_data_t *
 
65
ARRAY_TMPL_NS(unpack_data)
 
66
( ARRAY_TMPL_runtime_ptr_t runtime
 
67
, ARRAY_TMPL_packed_data_ptr_t p
 
68
) {
 
69
        ARRAY_TMPL_data_t * ret = (ARRAY_TMPL_data_t *)ARRAY_TMPL_unpack_pointer(p);
 
70
        TREEDB_printf8("handle_array::unpack_data : %lu[0x%lx] -> %p\n"
 
71
                , (uintptr_t)p
 
72
                , (uintptr_t)p, (void *)(uintptr_t)ret);
 
73
        return ret;
 
74
}
 
75
#endif
 
76
 
 
77
/**
 
78
Allocate array item storage.
 
79
 
 
80
The storage used must be write locked.
 
81
*/
 
82
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(init)
 
83
( ARRAY_TMPL_runtime_ptr_t runtime
 
84
, ARRAY_TMPL_packed_array_ptr_t ha
 
85
, ARRAY_TMPL_size_t reserve
 
86
, ARRAY_TMPL_size_t increment
 
87
) {
 
88
        if(!ha)
 
89
                return 1;
 
90
        if(!increment)
 
91
                increment = 1;
 
92
        else if(ARRAY_TMPL_exceeds_count_limit(increment))
 
93
                return 2;
 
94
        if(ARRAY_TMPL_exceeds_count_limit(reserve))
 
95
                return 2;
 
96
        ARRAY_TMPL_count_t nitems = V3C_ROUND_UP_T(ARRAY_TMPL_count_t, reserve, increment);
 
97
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_unpack_array(ha);
 
98
        ARRAY_TMPL_data_t * pd;
 
99
        if(nitems) {
 
100
                pd = (ARRAY_TMPL_data_t *)ARRAY_TMPL_alloc(nitems * ARRAY_TMPL_entry_size);
 
101
                pa = ARRAY_TMPL_unpack_array(ha);
 
102
        }else
 
103
                pd = 0;
 
104
        ARRAY_TMPL_count_MEMBER_SET(pa, 0);
 
105
        ARRAY_TMPL_reserve_MEMBER_SET(pa, nitems);
 
106
        ARRAY_TMPL_increment_MEMBER_SET(pa, increment);
 
107
        ARRAY_TMPL_items_MEMBER_SET(pa, ARRAY_TMPL_pack_data(pd));
 
108
        if(nitems)
 
109
                return pd ? 0 : 1;
 
110
        return 0;
 
111
}
 
112
#ifndef ARRAY_TMPL_omit_init_empty_ptr
 
113
/**
 
114
Set up an empty array.
 
115
 
 
116
The storage used must be write locked.
 
117
*/
 
118
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(init_empty_ptr)
 
119
( ARRAY_TMPL_runtime_ptr_t runtime
 
120
, ARRAY_TMPL_array_ptr_t pa
 
121
, ARRAY_TMPL_size_t increment
 
122
) {
 
123
        if(!increment)
 
124
                increment = 1;
 
125
        else if(ARRAY_TMPL_exceeds_count_limit(increment))
 
126
                return 1;
 
127
        ARRAY_TMPL_count_MEMBER_SET(pa, 0);
 
128
        ARRAY_TMPL_reserve_MEMBER_SET(pa, 0);
 
129
        ARRAY_TMPL_increment_MEMBER_SET(pa, increment);
 
130
        ARRAY_TMPL_items_MEMBER_SET(pa, ARRAY_TMPL_pack_data(0));
 
131
        return 0;
 
132
}
 
133
#endif
 
134
#ifndef ARRAY_TMPL_omit_init_empty
 
135
/**
 
136
Set up an empty array.
 
137
 
 
138
The storage used must be write locked.
 
139
*/
 
140
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(init_empty)
 
141
( ARRAY_TMPL_runtime_ptr_t runtime
 
142
, ARRAY_TMPL_packed_array_ptr_t ha
 
143
, ARRAY_TMPL_size_t increment
 
144
) {
 
145
        return ARRAY_TMPL_NS(init_empty_ptr)(runtime, ARRAY_TMPL_unpack_array(ha)
 
146
                , increment);
 
147
}
 
148
#endif
 
149
 
 
150
#ifndef ARRAY_TMPL_omit_new
 
151
/**
 
152
Allocate an array.
 
153
 
 
154
The storage used must be write locked.
 
155
*/
 
156
ARRAY_TMPL_prefix ARRAY_TMPL_packed_array_ptr_t ARRAY_TMPL_NS(new)
 
157
( ARRAY_TMPL_runtime_ptr_t runtime
 
158
, ARRAY_TMPL_size_t reserve
 
159
, ARRAY_TMPL_size_t increment
 
160
) {
 
161
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_alloc_array;
 
162
        if(!pa)
 
163
                return 0;
 
164
        ARRAY_TMPL_packed_array_ptr_t ha = ARRAY_TMPL_pack_array(pa);
 
165
        if(ARRAY_TMPL_NS(init)(runtime, ha, reserve, increment)) {
 
166
                ARRAY_TMPL_free(ARRAY_TMPL_unpack_array(ha));
 
167
                return 0;
 
168
        }
 
169
        return ha;
 
170
}
 
171
#endif
 
172
 
 
173
/**
 
174
Free an array's entries.
 
175
 
 
176
The storage used must be write locked.
 
177
*/
 
178
static void ARRAY_TMPL_NS(reset)
 
179
( ARRAY_TMPL_runtime_ptr_t runtime
 
180
, ARRAY_TMPL_packed_array_ptr_t ha
 
181
) {
 
182
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_unpack_array(ha);
 
183
        (void)pa;
 
184
        if(ARRAY_TMPL_items_MEMBER(pa)) {
 
185
                if(ARRAY_TMPL_count_MEMBER(pa)) {
 
186
                        if(ARRAY_TMPL_clear_entries(ha, 0, ARRAY_TMPL_count_MEMBER(pa)))
 
187
                                pa = ARRAY_TMPL_unpack_array(ha);
 
188
                        ARRAY_TMPL_count_MEMBER_SET(pa, 0);
 
189
                }
 
190
                ARRAY_TMPL_free(ARRAY_TMPL_unpack_data(ARRAY_TMPL_items_MEMBER(pa)));
 
191
                pa = ARRAY_TMPL_unpack_array(ha);
 
192
                ARRAY_TMPL_items_MEMBER(pa) = ARRAY_TMPL_pack_data(0);
 
193
        }
 
194
        ARRAY_TMPL_reserve_MEMBER_SET(pa, 0);
 
195
        ARRAY_TMPL_items_MEMBER_SET(pa, 0);
 
196
}
 
197
 
 
198
#ifndef ARRAY_TMPL_omit_free
 
199
/**
 
200
Free an array.
 
201
 
 
202
The storage used must be write locked.
 
203
*/
 
204
ARRAY_TMPL_prefix void ARRAY_TMPL_NS(free)
 
205
( ARRAY_TMPL_runtime_ptr_t runtime
 
206
, ARRAY_TMPL_packed_array_ptr_t ha
 
207
) {
 
208
        ARRAY_TMPL_NS(reset)(runtime, ha);
 
209
        ARRAY_TMPL_free(ARRAY_TMPL_unpack_array(ha));
 
210
}
 
211
#endif
 
212
 
 
213
/**
 
214
Clear (empty) the array.
 
215
 
 
216
The storage used must be write locked.
 
217
*/
 
218
ARRAY_TMPL_prefix void ARRAY_TMPL_NS(clear)
 
219
( ARRAY_TMPL_runtime_ptr_t runtime
 
220
, ARRAY_TMPL_packed_array_ptr_t ha
 
221
) {
 
222
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_unpack_array(ha);
 
223
        ARRAY_TMPL_NS(remove_many)(runtime, ha, 0, ARRAY_TMPL_count_MEMBER(pa));
 
224
}
 
225
/** Make a copy (clone) of another array.
 
226
 
 
227
The storage used must be write locked.
 
228
 
 
229
The destination array must be initialised first.
 
230
 
 
231
If the destination array isn't empty, it is cleared.
 
232
 
 
233
If the allocator runs out of memory, the copy is cleared and clone() fails.
 
234
 
 
235
This is a "shallow copy" of the raw array data.
 
236
 
 
237
You may need to take extra steps to ensure that the copy is a consistant shallow
 
238
or deep copy.
 
239
*/
 
240
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(clone)
 
241
( ARRAY_TMPL_runtime_ptr_t runtime
 
242
, ARRAY_TMPL_packed_array_ptr_t ha_to
 
243
, ARRAY_TMPL_packed_array_ptr_t ha_from
 
244
) {
 
245
        ARRAY_TMPL_array_ptr_t pa_to = ARRAY_TMPL_unpack_array(ha_to);
 
246
        if(ARRAY_TMPL_items_MEMBER(pa_to))
 
247
                ARRAY_TMPL_NS(clear)(runtime, ha_to);
 
248
        ARRAY_TMPL_array_ptr_t pa_from = ARRAY_TMPL_unpack_array(ha_from);
 
249
        if(ARRAY_TMPL_NS(init)(runtime, ha_to, ARRAY_TMPL_count_MEMBER(pa_from)
 
250
                        , ARRAY_TMPL_increment_MEMBER(pa_to)))
 
251
                return 1;
 
252
        pa_to = ARRAY_TMPL_unpack_array(ha_to);
 
253
        pa_from = ARRAY_TMPL_unpack_array(ha_from);
 
254
        ARRAY_TMPL_memcopy(ARRAY_TMPL_item_ptr(pa_to, 0)
 
255
                , ARRAY_TMPL_item_ptr(pa_from, 0)
 
256
                , ARRAY_TMPL_count_MEMBER(pa_from) * ARRAY_TMPL_entry_size);
 
257
        return 0;
 
258
}
 
259
#ifndef ARRAY_TMPL_omit_insert
 
260
/**
 
261
Insert an item.
 
262
 
 
263
The storage used must be write locked.
 
264
*/
 
265
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(insert)
 
266
( ARRAY_TMPL_runtime_ptr_t runtime
 
267
, ARRAY_TMPL_packed_array_ptr_t ha
 
268
, ARRAY_TMPL_size_t where
 
269
, ARRAY_TMPL_input_t d
 
270
) {
 
271
        if(ARRAY_TMPL_exceeds_count_limit(where))
 
272
                return 1;
 
273
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_unpack_array(ha);
 
274
        if(where > ARRAY_TMPL_count_MEMBER(pa))
 
275
                return 1;
 
276
        if(ARRAY_TMPL_count_MEMBER(pa) < ARRAY_TMPL_reserve_MEMBER(pa)) {
 
277
                ; /* We have room to expand */
 
278
        }else{
 
279
                ARRAY_TMPL_count_t nitems
 
280
                        = V3C_ROUND_UP_T(ARRAY_TMPL_count_t, ARRAY_TMPL_count_MEMBER(pa) + 1
 
281
                                , ARRAY_TMPL_increment_MEMBER(pa));
 
282
                if(ARRAY_TMPL_realloc_packed(ha, nitems))
 
283
                        return 1;
 
284
                pa = ARRAY_TMPL_unpack_array(ha);
 
285
                ARRAY_TMPL_reserve_MEMBER_SET(pa, nitems);
 
286
        }
 
287
        if(where != ARRAY_TMPL_count_MEMBER(pa))
 
288
                ARRAY_TMPL_memmove(ARRAY_TMPL_item_ptr(pa, where + 1)
 
289
                        , ARRAY_TMPL_item_ptr(pa, where)
 
290
                        , (ARRAY_TMPL_count_MEMBER(pa) - where) * ARRAY_TMPL_entry_size);
 
291
        ARRAY_TMPL_assign(ARRAY_TMPL_item(pa, where), d);
 
292
        ARRAY_TMPL_count_MEMBER_INCREMENT(pa);
 
293
        return 0;
 
294
}
 
295
#endif
 
296
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(insert_many)
 
297
( ARRAY_TMPL_runtime_ptr_t runtime
 
298
, ARRAY_TMPL_packed_array_ptr_t ha
 
299
, ARRAY_TMPL_size_t where
 
300
, ARRAY_TMPL_size_t count
 
301
) {
 
302
        if(!count)
 
303
                return 0;
 
304
        if(ARRAY_TMPL_exceeds_count_limit(where + count - 1))
 
305
                return 1;
 
306
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_unpack_array(ha);
 
307
        if(where > ARRAY_TMPL_count_MEMBER(pa))
 
308
                return 2;
 
309
        if((ARRAY_TMPL_count_MEMBER(pa) + count) <= ARRAY_TMPL_reserve_MEMBER(pa)) {
 
310
                ; /* We have room to expand */
 
311
        }else{
 
312
                ARRAY_TMPL_count_t nitems
 
313
                        = V3C_ROUND_UP_T(ARRAY_TMPL_count_t
 
314
                                , ARRAY_TMPL_count_MEMBER(pa) + count
 
315
                                , ARRAY_TMPL_increment_MEMBER(pa));
 
316
                if(ARRAY_TMPL_realloc_packed(ha, nitems))
 
317
                        return 3;
 
318
                pa = ARRAY_TMPL_unpack_array(ha);
 
319
                ARRAY_TMPL_reserve_MEMBER_SET(pa, nitems);
 
320
        }
 
321
        if(where != ARRAY_TMPL_count_MEMBER(pa))
 
322
                ARRAY_TMPL_memmove(ARRAY_TMPL_item_ptr(pa, where + count)
 
323
                        , ARRAY_TMPL_item_ptr(pa, where)
 
324
                        , (ARRAY_TMPL_count_MEMBER(pa) - where) * ARRAY_TMPL_entry_size);
 
325
        ARRAY_TMPL_count_MEMBER_ADD(pa, count);
 
326
        return 0;
 
327
}
 
328
#ifndef ARRAY_TMPL_omit_remove
 
329
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(remove)
 
330
( ARRAY_TMPL_runtime_ptr_t runtime
 
331
, ARRAY_TMPL_packed_array_ptr_t ha
 
332
, ARRAY_TMPL_size_t where
 
333
) {
 
334
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_unpack_array(ha);
 
335
        if(where >= ARRAY_TMPL_count_MEMBER(pa))
 
336
                return 1;
 
337
        if(ARRAY_TMPL_clear_entries(ha, where, 1))
 
338
                pa = ARRAY_TMPL_unpack_array(ha); /* Just in case. */
 
339
        if((where + 1) != ARRAY_TMPL_count_MEMBER(pa))
 
340
                ARRAY_TMPL_memmove(ARRAY_TMPL_item_ptr(pa, where), ARRAY_TMPL_item_ptr(pa, where + 1)
 
341
                        , (ARRAY_TMPL_count_MEMBER(pa) - where - 1) * ARRAY_TMPL_entry_size);
 
342
        if(ARRAY_TMPL_count_MEMBER(pa) % ARRAY_TMPL_increment_MEMBER(pa)) {
 
343
                ; /* We have room to shrink */
 
344
        }else{
 
345
                ARRAY_TMPL_count_t nitems
 
346
                        = V3C_ROUND_UP_T(ARRAY_TMPL_count_t, ARRAY_TMPL_count_MEMBER(pa) - 1
 
347
                                , ARRAY_TMPL_increment_MEMBER(pa));
 
348
                if(nitems) {
 
349
                        if(ARRAY_TMPL_realloc_packed(ha, nitems))
 
350
                                return 1;
 
351
                        pa = ARRAY_TMPL_unpack_array(ha);
 
352
                }else{
 
353
                        ARRAY_TMPL_free(ARRAY_TMPL_unpack_data(ARRAY_TMPL_items_MEMBER(pa)));
 
354
                        pa = ARRAY_TMPL_unpack_array(ha);
 
355
                        ARRAY_TMPL_items_MEMBER(pa) = ARRAY_TMPL_pack_data(0);
 
356
                }
 
357
                ARRAY_TMPL_reserve_MEMBER_SET(pa, nitems);
 
358
        }
 
359
        ARRAY_TMPL_count_MEMBER_DECREMENT(pa);
 
360
        return 0;
 
361
}
 
362
#endif
 
363
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(remove_many)
 
364
( ARRAY_TMPL_runtime_ptr_t runtime
 
365
, ARRAY_TMPL_packed_array_ptr_t ha
 
366
, ARRAY_TMPL_size_t where
 
367
, ARRAY_TMPL_size_t count
 
368
) {
 
369
        if(!count)
 
370
                return 0;
 
371
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_unpack_array(ha);
 
372
        if((where + count) > ARRAY_TMPL_count_MEMBER(pa))
 
373
                return 1;
 
374
        if(ARRAY_TMPL_clear_entries(ha, where, count))
 
375
                pa = ARRAY_TMPL_unpack_array(ha); /* Just in case. */
 
376
        if((where + count) != ARRAY_TMPL_count_MEMBER(pa))
 
377
                ARRAY_TMPL_memmove(ARRAY_TMPL_item_ptr(pa, where)
 
378
                        , ARRAY_TMPL_item_ptr(pa, where + count)
 
379
                        , (ARRAY_TMPL_count_MEMBER(pa) - where - count) * ARRAY_TMPL_entry_size);
 
380
        if(((ARRAY_TMPL_count_MEMBER(pa) - count) / ARRAY_TMPL_increment_MEMBER(pa))
 
381
                        == (ARRAY_TMPL_count_MEMBER(pa) / ARRAY_TMPL_increment_MEMBER(pa))) {
 
382
                ; /* We have room to shrink */
 
383
        }else{
 
384
                ARRAY_TMPL_count_t nitems = V3C_ROUND_UP_T(ARRAY_TMPL_count_t
 
385
                        , ARRAY_TMPL_count_MEMBER(pa) - count, ARRAY_TMPL_increment_MEMBER(pa));
 
386
                if(nitems) {
 
387
                        if(ARRAY_TMPL_realloc_packed(ha, nitems))
 
388
                                return 1;
 
389
                        pa = ARRAY_TMPL_unpack_array(ha);
 
390
                }else{
 
391
                        ARRAY_TMPL_free(ARRAY_TMPL_unpack_data(ARRAY_TMPL_items_MEMBER(pa)));
 
392
                        pa = ARRAY_TMPL_unpack_array(ha);
 
393
                        ARRAY_TMPL_items_MEMBER(pa) = ARRAY_TMPL_pack_data(0);
 
394
                }
 
395
                ARRAY_TMPL_reserve_MEMBER_SET(pa, nitems);
 
396
        }
 
397
        ARRAY_TMPL_count_MEMBER_SUBTRACT(pa, count);
 
398
        return 0;
 
399
}
 
400
#ifndef ARRAY_TMPL_omit_push_back
 
401
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(push_back)
 
402
( ARRAY_TMPL_runtime_ptr_t runtime
 
403
, ARRAY_TMPL_packed_array_ptr_t ha
 
404
, ARRAY_TMPL_input_t d
 
405
) {
 
406
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_unpack_array(ha);
 
407
        return ARRAY_TMPL_NS(insert)(runtime, ha, ARRAY_TMPL_count_MEMBER(pa), d);
 
408
}
 
409
#endif
 
410
#ifndef ARRAY_TMPL_omit_push_back_many
 
411
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(push_back_many)
 
412
( ARRAY_TMPL_runtime_ptr_t runtime
 
413
, ARRAY_TMPL_packed_array_ptr_t ha
 
414
, ARRAY_TMPL_size_t count
 
415
) {
 
416
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_unpack_array(ha);
 
417
        return ARRAY_TMPL_NS(insert_many)(runtime, ha, ARRAY_TMPL_count_MEMBER(pa), count);
 
418
}
 
419
#endif
 
420
#ifndef ARRAY_TMPL_omit_push_front
 
421
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(push_front)
 
422
( ARRAY_TMPL_runtime_ptr_t runtime
 
423
, ARRAY_TMPL_packed_array_ptr_t ha
 
424
, ARRAY_TMPL_input_t d
 
425
) {
 
426
        return ARRAY_TMPL_NS(insert)(runtime, ha, 0, d);
 
427
}
 
428
#endif
 
429
#ifndef ARRAY_TMPL_omit_push_front_many
 
430
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(push_front_many)
 
431
( ARRAY_TMPL_runtime_ptr_t runtime
 
432
, ARRAY_TMPL_packed_array_ptr_t ha
 
433
, ARRAY_TMPL_size_t count
 
434
) {
 
435
        return ARRAY_TMPL_NS(insert_many)(runtime, ha, 0, count);
 
436
}
 
437
#endif
 
438
#ifndef ARRAY_TMPL_omit_pop_back
 
439
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(pop_back)
 
440
( ARRAY_TMPL_runtime_ptr_t runtime
 
441
, ARRAY_TMPL_packed_array_ptr_t ha
 
442
) {
 
443
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_unpack_array(ha);
 
444
        return ARRAY_TMPL_NS(remove)(runtime, ha, ARRAY_TMPL_count_MEMBER(pa) - 1);
 
445
}
 
446
#endif
 
447
#ifndef ARRAY_TMPL_omit_pop_back_many
 
448
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(pop_back_many)
 
449
( ARRAY_TMPL_runtime_ptr_t runtime
 
450
, ARRAY_TMPL_packed_array_ptr_t ha
 
451
, ARRAY_TMPL_size_t count
 
452
) {
 
453
        ARRAY_TMPL_array_ptr_t pa = ARRAY_TMPL_unpack_array(ha);
 
454
        return ARRAY_TMPL_NS(remove_many)(runtime, ha, ARRAY_TMPL_count_MEMBER(pa) - count
 
455
                , count);
 
456
}
 
457
#endif
 
458
#ifndef ARRAY_TMPL_omit_pop_front
 
459
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(pop_front)
 
460
( ARRAY_TMPL_runtime_ptr_t runtime
 
461
, ARRAY_TMPL_packed_array_ptr_t ha
 
462
) {
 
463
        return ARRAY_TMPL_NS(remove)(runtime, ha, 0);
 
464
}
 
465
#endif
 
466
#ifndef ARRAY_TMPL_omit_pop_front_many
 
467
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(pop_front_many)
 
468
( ARRAY_TMPL_runtime_ptr_t runtime
 
469
, ARRAY_TMPL_packed_array_ptr_t ha
 
470
, ARRAY_TMPL_size_t count
 
471
) {
 
472
        return ARRAY_TMPL_NS(remove_many)(runtime, ha, 0, count);
 
473
}
 
474
#endif
 
475
#ifndef ARRAY_TMPL_omit_reverse_some
 
476
/** ARRAY_TMPL_NS(reverse_some)
 
477
 
 
478
Unfortunately there's no equivalent for ARRAY_TMPL_clear_entries here.
 
479
*/
 
480
ARRAY_TMPL_prefix int ARRAY_TMPL_NS(reverse_some)
 
481
( ARRAY_TMPL_runtime_ptr_t runtime
 
482
, ARRAY_TMPL_array_ptr_t pa
 
483
, ARRAY_TMPL_size_t lower
 
484
, ARRAY_TMPL_size_t count
 
485
) {
 
486
        (void)runtime;
 
487
        /* count includes the first item. */
 
488
        if((lower + count) > ARRAY_TMPL_count_MEMBER(pa))
 
489
                return 1;
 
490
        ARRAY_TMPL_count_t n, num = count/2, upper = lower + count - 1;
 
491
        for(n = 0; n < num; ++n) {
 
492
                ARRAY_TMPL_auto_data(item1);
 
493
                ARRAY_TMPL_auto_data(item2);
 
494
                ARRAY_TMPL_assign_to_auto(item1, ARRAY_TMPL_item(pa, lower));
 
495
                ARRAY_TMPL_assign_to_auto(item2, ARRAY_TMPL_item(pa, upper));
 
496
                /*printf("swapping %lu[%u] and %lu[%u].\n", (size_t)(lower)
 
497
                        , item1, (size_t)(upper), item2);*/
 
498
                ARRAY_TMPL_assign_from_auto(ARRAY_TMPL_item(pa, lower), item2);
 
499
                ARRAY_TMPL_assign_from_auto(ARRAY_TMPL_item(pa, upper), item1);
 
500
                ++lower, --upper;
 
501
        }
 
502
        /*fflush(stdout);*/
 
503
        return 0;
 
504
}
 
505
#endif
 
506
#ifndef ARRAY_TMPL_omit_reverse
 
507
ARRAY_TMPL_prefix void ARRAY_TMPL_NS(reverse)
 
508
( ARRAY_TMPL_runtime_ptr_t runtime
 
509
, ARRAY_TMPL_array_ptr_t pa
 
510
) {
 
511
        (void)ARRAY_TMPL_NS(reverse_some)(runtime, pa, 0, ARRAY_TMPL_count_MEMBER(pa));
 
512
}
 
513
#endif
 
514
 
 
515
#ifdef __cplusplus
 
516
} /* extern "C" { */
 
517
#endif