File: dynar.h

package info (click to toggle)
simgrid 4.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 39,192 kB
  • sloc: cpp: 124,913; ansic: 66,744; python: 8,560; java: 6,773; fortran: 6,079; f90: 5,123; xml: 4,587; sh: 2,194; perl: 1,436; makefile: 111; lisp: 49; javascript: 7; sed: 6
file content (132 lines) | stat: -rw-r--r-- 5,179 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* dynar - a generic dynamic array                                          */

/* Copyright (c) 2004-2025. The SimGrid Team. All rights reserved.          */

/* This program is free software; you can redistribute it and/or modify it
 * under the terms of the license (GNU LGPL) which comes with this package. */

#ifndef XBT_DYNAR_H
#define XBT_DYNAR_H

#include <string.h>             /* memcpy */

#include <xbt/base.h> /* SG_BEGIN_DECL */
#include <xbt/function_types.h>

SG_BEGIN_DECL

/** @brief Dynar data type (opaque type)
 *
 * These are the SimGrid version of the DYNamically sized ARays, which all C programmer recode one day or another.
 * For performance concerns, the content of dynars must be homogeneous (in contrary to
 * @verbatim embed:rst:inline :cpp:type:`xbt_dict_t` @endverbatim ).
 * You thus have to provide the function which will be used to free the content at
 * structure creation (of type void_f_pvoid_t).
 */
typedef struct xbt_dynar_s *xbt_dynar_t;
/** constant dynar */
typedef const struct xbt_dynar_s* const_xbt_dynar_t;
/* @warning DO NOT USE THIS STRUCTURE DIRECTLY! Use the public interface, even if it's public for sake of inlining */
typedef struct xbt_dynar_s {
  unsigned long size;
  unsigned long used;
  unsigned long elmsize;
  void* data;
  void_f_pvoid_t free_f;
} s_xbt_dynar_t;

XBT_PUBLIC xbt_dynar_t xbt_dynar_new(const unsigned long elm_size, void_f_pvoid_t free_f);
XBT_PUBLIC void xbt_dynar_free(xbt_dynar_t* dynar);
XBT_PUBLIC void xbt_dynar_free_container(xbt_dynar_t* dynar);

/* Dynar as a regular array */
XBT_PUBLIC void xbt_dynar_get_cpy(const_xbt_dynar_t dynar, unsigned long idx, void* dst);

XBT_PUBLIC void xbt_dynar_insert_at(xbt_dynar_t dynar, int idx, const void* src);
XBT_PUBLIC void xbt_dynar_remove_at(xbt_dynar_t dynar, int idx, void* dst);

XBT_PUBLIC int xbt_dynar_member(const_xbt_dynar_t dynar, const void* elem);
XBT_PUBLIC void xbt_dynar_sort(const_xbt_dynar_t dynar, int_f_cpvoid_cpvoid_t compar_fn);

/* Dynar size */
XBT_PUBLIC void xbt_dynar_reset(xbt_dynar_t dynar);
XBT_PUBLIC unsigned long xbt_dynar_length(const_xbt_dynar_t dynar);
XBT_PUBLIC int xbt_dynar_is_empty(const_xbt_dynar_t dynar);

/* Perl-like interface */
XBT_PUBLIC void xbt_dynar_push(xbt_dynar_t dynar, const void* src);
XBT_PUBLIC void xbt_dynar_pop(xbt_dynar_t dynar, void* dst);
XBT_PUBLIC void xbt_dynar_unshift(xbt_dynar_t dynar, const void* src);
XBT_PUBLIC void xbt_dynar_shift(xbt_dynar_t dynar, void* dst);
XBT_PUBLIC void xbt_dynar_map(const_xbt_dynar_t dynar, void_f_pvoid_t op);

/* Direct content manipulation*/
XBT_PUBLIC void* xbt_dynar_set_at_ptr(const xbt_dynar_t dynar, unsigned long idx);
XBT_PUBLIC void* xbt_dynar_get_ptr(const_xbt_dynar_t dynar, unsigned long idx);
XBT_PUBLIC void* xbt_dynar_insert_at_ptr(xbt_dynar_t dynar, int idx);
XBT_PUBLIC void* xbt_dynar_push_ptr(xbt_dynar_t dynar);
XBT_PUBLIC void* xbt_dynar_pop_ptr(xbt_dynar_t dynar);

/* Dynars of scalar */
/** @brief Quick retrieval of scalar content
 *  @hideinitializer */
#  define xbt_dynar_get_as(dynar,idx,type) \
          (*(type*)xbt_dynar_get_ptr((dynar),(idx)))
/** @brief Quick setting of scalar content
 *  @hideinitializer */
#define xbt_dynar_set_as(dynar, idx, type, val) (*(type*)xbt_dynar_set_at_ptr((dynar), (idx))) = (val)
/** @brief Quick retrieval of scalar content
 *  @hideinitializer */
#  define xbt_dynar_getlast_as(dynar,type) \
          (*(type*)xbt_dynar_get_ptr((dynar),xbt_dynar_length(dynar)-1))
/** @brief Quick retrieval of scalar content
 *  @hideinitializer */
#  define xbt_dynar_getfirst_as(dynar,type) \
          (*(type*)xbt_dynar_get_ptr((dynar),0))
/** @brief Quick insertion of scalar content
 *  @hideinitializer */
#define xbt_dynar_push_as(dynar, type, value) *(type*)xbt_dynar_push_ptr(dynar) = (value)
/** @brief Quick removal of scalar content
 *  @hideinitializer */
#  define xbt_dynar_pop_as(dynar,type) \
           (*(type*)xbt_dynar_pop_ptr(dynar))

/* Iterating over dynars */
static inline int _xbt_dynar_cursor_get(const_xbt_dynar_t dynar, unsigned int idx, void* dst)
{
  if (!dynar) /* iterating over a NULL dynar is a no-op */
    return 0;

  if (idx >= dynar->used)
    return 0;

  memcpy(dst, ((char *) dynar->data) + idx * dynar->elmsize, dynar->elmsize);

  return 1;
}

/** @brief Iterates over the whole dynar.
 *
 *  @param _dynar what to iterate over
 *  @param _cursor an unsigned integer used as cursor
 *  @hideinitializer
 *
 * Here is an example of usage:
 * @code
xbt_dynar_t dyn;
unsigned int cpt;
char* str;
xbt_dynar_foreach (dyn,cpt,str) {
  printf("Seen %s\n",str);
}
@endcode
 *
 * Note that underneath, that's a simple for loop with no real black  magic involved. It's perfectly safe to interrupt
 * a foreach with a break or a return statement, but inserting or removing elements during the traversal is probably a
 * bad idea (even if you can fix side effects by manually changing the counter).
 */
#define xbt_dynar_foreach(_dynar, _cursor, _data)                                                                      \
  for ((_cursor) = 0; _xbt_dynar_cursor_get((_dynar), (_cursor), &(_data)); (_cursor)++)
SG_END_DECL

#endif /* XBT_DYNAR_H */