ARB
arb_strarray.h
Go to the documentation of this file.
1 // ============================================================ //
2 // //
3 // File : arb_strarray.h //
4 // Purpose : handle arrays of strings //
5 // //
6 // Coded by Ralf Westram (coder@reallysoft.de) in July 2011 //
7 // Institute of Microbiology (Technical University Munich) //
8 // http://www.arb-home.de/ //
9 // //
10 // ============================================================ //
11 
12 #ifndef ARB_STRARRAY_H
13 #define ARB_STRARRAY_H
14 
15 #ifndef ARBTOOLS_H
16 #include <arbtools.h>
17 #endif
18 #ifndef ARB_STRING_H
19 #include "arb_string.h"
20 #endif
21 #ifndef _GLIBCXX_ALGORITHM
22 #include <algorithm>
23 #endif
24 #ifndef _GLIBCXX_CSTDLIB
25 #include <cstdlib>
26 #endif
27 
28 
29 typedef int (*CharPtrArray_compare_fun)(const void *p0, const void *p1, void *client_data); // same as arb_sort.h@gb_compare_function
30 
31 class CharPtrArray : virtual Noncopyable {
32  size_t allocated;
33 
34 protected:
35  char **str;
36  size_t elems;
37 
38  bool ok() const {
39  if (!str) {
40  return elems == 0 && allocated == 0;
41  }
42  return !str[elems] && allocated > elems;
43  }
44 
45  bool elem_index(int i) const { return i >= 0 && size_t(i)<elems; }
46  bool allocated_index(int i) const { return i >= 0 && size_t(i)<allocated; }
47 
48  void set_space(size_t new_allocated) {
49  if (new_allocated != allocated) {
50  arb_assert(ok());
51 
52  if (str) ARB_recalloc(str, allocated, new_allocated);
53  else ARB_calloc(str, new_allocated);
54 
55  allocated = new_allocated;
56  arb_assert(ok());
57  }
58  }
59 
60  void reserve_space(size_t forElems, bool alloc_ahead) {
61  if (allocated <= forElems) {
62  forElems = alloc_ahead ? (forElems>7 ? forElems*3/2 : 10) : forElems;
63  set_space(forElems+1); // always allocate one element more (sentinel element)
64  }
65  }
66 
67  CharPtrArray() : allocated(0), str(NULp), elems(0) {}
68  virtual ~CharPtrArray() { free(str); }
69 
70  virtual void free_elem(int i) = 0;
71 
72  void erase_elems() {
73  arb_assert(ok());
74  if (!empty()) {
75  for (size_t i = 0; i<elems; ++i) free_elem(i);
76  elems = 0;
77  arb_assert(ok());
78  }
79  }
80 
81 public:
82  void reserve(size_t forElems) { reserve_space(forElems, false); }
83  void optimize_space() { set_space(elems+1); }
84 
85  size_t size() const { return elems; }
86  bool empty() const { return elems == 0; }
87 
88  const char *operator[](int i) const {
89  arb_assert(ok());
90  arb_assert(i >= 0 && size_t(i) <= elems); // allow sentinel access
91  return elems ? str[i] : NULp;
92  }
93 
94  void swap(int i1, int i2) {
95  arb_assert(ok());
98  std::swap(str[i1], str[i2]);
99  arb_assert(ok());
100  }
101  void move(int from, int to);
102 
103  void remove(int i) {
104  arb_assert(ok());
106  free_elem(i);
107  while (size_t(i) < elems) { // move elems incl. sentinel
108  str[i] = str[i+1];
109  ++i;
110  }
111  elems--;
112  arb_assert(ok());
113  }
114  void safe_remove(int i) {
116  if (elem_index(i)) remove(i);
117  }
118 
119  void resize(int newsize) {
120  // truncates array to 'newsize'
121  for (int i = size()-1; i >= newsize; i--) {
122  remove(i);
123  }
124  }
125  void clear() { resize(0); }
126 
127  void sort(CharPtrArray_compare_fun compare, void *client_data);
128  void uniq(CharPtrArray_compare_fun compare, void *client_data);
129  void sort_and_uniq(CharPtrArray_compare_fun compare, void *client_data) {
134  sort(compare, client_data);
135  uniq(compare, client_data);
136  }
137 
138  int index_of(const char *search_for) const;
139 };
140 
141 class StrArray FINAL_TYPE : public CharPtrArray {
142  void free_elem(int i) OVERRIDE {
143  freenull(str[i]);
144  }
145 
146 public:
147  StrArray() {}
148  ~StrArray() OVERRIDE { erase(); }
149 
150  void erase() { erase_elems(); }
151 
152  void put(char *elem) { // tranfers ownership!
153  int i = elems;
154  reserve_space(i+1, true);
156  str[i] = elem;
157  str[i+1] = NULp; // sentinel
158  elems++;
159  arb_assert(ok());
160  }
161  void put_before(int insert_before, char *elem) { // tranfers ownership of elem!
162  // insert a new 'name' before position 'insert_before'
163  // if 'insert_before' == -1 (or bigger than array size) -> append at end
164  put(elem);
165  if (insert_before<int(size())) {
166  move(-1, insert_before);
167  }
168  }
169 
170  char *replace(int i, char *elem) { // transfers ownership (in both directions!)
172  char *old = str[i];
173  str[i] = elem;
174  arb_assert(ok());
175  return old;
176  }
177 };
178 
179 class ConstStrArray : public CharPtrArray { // derived from a Noncopyable
180  char *memblock;
181 
182  void free_elem(int i) FINAL_OVERRIDE { str[i] = NULp; }
183 
184 public:
185  ConstStrArray() : memblock(NULp) {}
186  ~ConstStrArray() OVERRIDE { free(memblock); }
187 
188  void set_memblock(char *block) {
189  // hold one memblock until destruction
190  arb_assert(!memblock);
191  memblock = block;
192  }
193 
194  void erase() {
195  erase_elems();
196  freenull(memblock);
197  }
198 
199  void put(const char *elem) {
200  int i = elems;
201  reserve_space(i+1, true);
203  str[i] = const_cast<char*>(elem);
204  str[i+1] = NULp; // sentinel
205  elems++;
206  arb_assert(ok());
207  }
208  void put_before(int insert_before, const char *elem) {
209  // insert a new 'name' before position 'insert_before'
210  // if 'insert_before' == -1 (or bigger than array size) -> append at end
211  put(elem);
212  if (insert_before<int(size())) {
213  move(-1, insert_before);
214  }
215  }
216 
217  const char *replace(int i, const char *elem) {
219  const char *old = str[i];
220  str[i] = const_cast<char*>(elem);
221  arb_assert(ok());
222  return old;
223  }
224 
226 };
227 MARK_NONFINAL_CLASS(ConstStrArray); // @@@ unwanted. cannot be final due to DEBUG-only class StringVectorArray. fix.
228 
229 void GBT_splitNdestroy_string(ConstStrArray& names, char*& namelist, const char *separator, bool dropEmptyTokens);
230 void GBT_splitNdestroy_string(ConstStrArray& dest, char*& namelist, char separator);
231 
232 inline void GBT_split_string(ConstStrArray& dest, const char *namelist, const char *separator, bool dropEmptyTokens) {
234  char *dup = ARB_strdup(namelist);
235  GBT_splitNdestroy_string(dest, dup, separator, dropEmptyTokens);
236 }
237 inline void GBT_split_string(ConstStrArray& dest, const char *namelist, char separator) {
238  char *dup = ARB_strdup(namelist);
239  GBT_splitNdestroy_string(dest, dup, separator);
240  // cppcheck-suppress memleak (GBT_splitNdestroy_string takes ownership of 'dup')
241 }
242 
243 char *GBT_join_strings(const CharPtrArray& strings, char separator);
244 
245 #else
246 #error arb_strarray.h included twice
247 #endif // ARB_STRARRAY_H
#define arb_assert(cond)
Definition: arb_assert.h:245
void set_space(size_t new_allocated)
Definition: arb_strarray.h:48
void put(const char *elem)
Definition: arb_strarray.h:199
size_t size() const
Definition: arb_strarray.h:85
void resize(int newsize)
Definition: arb_strarray.h:119
int(* CharPtrArray_compare_fun)(const void *p0, const void *p1, void *client_data)
Definition: arb_strarray.h:29
~ConstStrArray() OVERRIDE
Definition: arb_strarray.h:186
char * ARB_strdup(const char *str)
Definition: arb_string.h:27
virtual ~CharPtrArray()
Definition: arb_strarray.h:68
void uniq(CharPtrArray_compare_fun compare, void *client_data)
const char * operator[](int i) const
Definition: arb_strarray.h:88
char ** str
Definition: arb_strarray.h:35
void set_memblock(char *block)
Definition: arb_strarray.h:188
bool allocated_index(int i) const
Definition: arb_strarray.h:46
char * replace(int i, char *elem)
Definition: arb_strarray.h:170
bool empty() const
Definition: arb_strarray.h:86
#define FINAL_OVERRIDE
Definition: cxxforward.h:95
void GBT_split_string(ConstStrArray &dest, const char *namelist, const char *separator, bool dropEmptyTokens)
Definition: arb_strarray.h:232
void erase_elems()
Definition: arb_strarray.h:72
static FullNameMap names
virtual void free_elem(int i)=0
void swap(int i1, int i2)
Definition: arb_strarray.h:94
int index_of(const char *search_for) const
size_t elems
Definition: arb_strarray.h:36
CONSTEXPR_INLINE_Cxx14 void swap(unsigned char &c1, unsigned char &c2)
Definition: ad_io_inline.h:19
void ARB_recalloc(TYPE *&tgt, size_t oelem, size_t nelem)
Definition: arb_mem.h:49
void safe_remove(int i)
Definition: arb_strarray.h:114
void put_before(int insert_before, const char *elem)
Definition: arb_strarray.h:208
void put(char *elem)
Definition: arb_strarray.h:152
void reserve_space(size_t forElems, bool alloc_ahead)
Definition: arb_strarray.h:60
void optimize_space()
Definition: arb_strarray.h:83
bool ok() const
Definition: arb_strarray.h:38
~StrArray() OVERRIDE
Definition: arb_strarray.h:148
void erase()
Definition: arb_strarray.h:150
TYPE * ARB_calloc(size_t nelem)
Definition: arb_mem.h:81
xml element
void put_before(int insert_before, char *elem)
Definition: arb_strarray.h:161
#define OVERRIDE
Definition: cxxforward.h:93
void move(int from, int to)
char * GBT_join_strings(const CharPtrArray &strings, char separator)
MARK_NONFINAL_CLASS(ConstStrArray)
void sort(CharPtrArray_compare_fun compare, void *client_data)
#define NULp
Definition: cxxforward.h:97
void reserve(size_t forElems)
Definition: arb_strarray.h:82
static ED4_block block
Definition: ED4_block.cxx:73
void GBT_splitNdestroy_string(ConstStrArray &names, char *&namelist, const char *separator, bool dropEmptyTokens)
bool elem_index(int i) const
Definition: arb_strarray.h:45
const char * replace(int i, const char *elem)
Definition: arb_strarray.h:217
PREPARE_MARK_NONFINAL_CLASS(ConstStrArray)
void sort_and_uniq(CharPtrArray_compare_fun compare, void *client_data)
Definition: arb_strarray.h:129