Halide  19.0.0
Halide compiler and libraries
string_table.h
Go to the documentation of this file.
1 #ifndef HALIDE_RUNTIME_STRING_TABLE_H
2 #define HALIDE_RUNTIME_STRING_TABLE_H
3 
4 #include "../HalideRuntime.h"
5 #include "block_storage.h"
6 #include "pointer_table.h"
7 #include "string_storage.h"
8 
9 namespace Halide {
10 namespace Runtime {
11 namespace Internal {
12 
13 // Storage class for an array of strings (based on block storage)
14 // -- Intended for building and maintaining tables of strings
15 class StringTable {
16 public:
17  // Disable copy constructors
18  StringTable(const StringTable &) = delete;
19  StringTable &operator=(const StringTable &) = delete;
20 
22  StringTable(void *user_context, size_t capacity, const SystemMemoryAllocatorFns &allocator = StringStorage::default_allocator());
23  StringTable(void *user_context, const char **array, size_t count, const SystemMemoryAllocatorFns &allocator = StringStorage::default_allocator());
24  ~StringTable();
25 
26  void resize(void *user_context, size_t capacity);
27  void destroy(void *user_context);
28  void clear(void *user_context);
29 
30  // fills the contents of the table (copies strings from given array)
31  void fill(void *user_context, const char **array, size_t count);
32 
33  // assign the entry at given index the given string
34  void assign(void *user_context, size_t index, const char *str, size_t length = 0); // if length is zero, strlen is used
35 
36  // appends the given string to the end of the table
37  void append(void *user_context, const char *str, size_t length = 0); // if length is zero, strlen is used
38 
39  // prepend the given string to the end of the table
40  void prepend(void *user_context, const char *str, size_t length = 0); // if length is zero, strlen is used
41 
42  // parses the given c-string based on given delimiter, stores each substring in the resulting table
43  size_t parse(void *user_context, const char *str, const char *delim);
44 
45  // index-based access operator
46  const char *operator[](size_t index) const;
47 
48  // returns the raw string table pointer
49  const char **data() const;
50 
51  // scans the table for existance of the given string within any entry (linear scan w/string compare!)
52  bool contains(const char *str) const;
53 
54  size_t size() const {
55  return contents.size();
56  }
57 
58 private:
59  PointerTable contents; //< owns string data
60  PointerTable pointers; //< pointers to raw string data
61 };
62 
63 // --
64 
66  : contents(nullptr, 0, sma),
67  pointers(nullptr, 0, sma) {
68  // EMPTY!
69 }
70 
71 StringTable::StringTable(void *user_context, size_t capacity, const SystemMemoryAllocatorFns &sma)
72  : contents(user_context, capacity, sma),
73  pointers(user_context, capacity, sma) {
74  if (capacity) {
75  resize(user_context, capacity);
76  }
77 }
78 
79 StringTable::StringTable(void *user_context, const char **array, size_t count, const SystemMemoryAllocatorFns &sma)
80  : contents(user_context, count, sma),
81  pointers(user_context, count, sma) {
82  fill(user_context, array, count);
83 }
84 
86  destroy(nullptr);
87 }
88 
89 void StringTable::resize(void *user_context, size_t capacity) {
90  pointers.resize(user_context, capacity);
91  contents.resize(user_context, capacity);
92  for (size_t n = 0; n < contents.size(); ++n) {
93  StringStorage *storage_ptr = StringStorage::create(user_context, contents.current_allocator());
94  contents.assign(user_context, n, storage_ptr);
95  }
96 }
97 
98 void StringTable::clear(void *user_context) {
99  for (size_t n = 0; n < contents.size(); ++n) {
100  StringStorage *storage_ptr = static_cast<StringStorage *>(contents[n]);
101  StringStorage::destroy(user_context, storage_ptr);
102  contents.assign(user_context, n, nullptr);
103  }
104  contents.clear(user_context);
105  pointers.clear(user_context);
106 }
107 
108 void StringTable::destroy(void *user_context) {
109  for (size_t n = 0; n < contents.size(); ++n) {
110  StringStorage *storage_ptr = static_cast<StringStorage *>(contents[n]);
111  StringStorage::destroy(user_context, storage_ptr);
112  contents.assign(user_context, n, nullptr);
113  }
114  contents.destroy(user_context);
115  pointers.destroy(user_context);
116 }
117 
118 const char *StringTable::operator[](size_t index) const {
119  if (index < pointers.size()) {
120  return static_cast<const char *>(pointers[index]);
121  }
122  return nullptr;
123 }
124 
125 void StringTable::fill(void *user_context, const char **array, size_t count) {
126  resize(user_context, count);
127  for (size_t n = 0; n < count && n < contents.size(); ++n) {
128  StringStorage *storage_ptr = static_cast<StringStorage *>(contents[n]);
129  storage_ptr->assign(user_context, array[n]);
130  pointers.assign(user_context, n, storage_ptr->data());
131  }
132 }
133 
134 void StringTable::assign(void *user_context, size_t index, const char *str, size_t length) {
135  if (length == 0) {
136  length = strlen(str);
137  }
138  if (index < contents.size()) {
139  StringStorage *storage_ptr = static_cast<StringStorage *>(contents[index]);
140  storage_ptr->assign(user_context, str, length);
141  pointers.assign(user_context, index, storage_ptr->data());
142  }
143 }
144 
145 void StringTable::append(void *user_context, const char *str, size_t length) {
146  StringStorage *storage_ptr = StringStorage::create(user_context, contents.current_allocator());
147  storage_ptr->assign(user_context, str, length);
148  contents.append(user_context, storage_ptr);
149  pointers.append(user_context, storage_ptr->data());
150 }
151 
152 void StringTable::prepend(void *user_context, const char *str, size_t length) {
153  StringStorage *storage_ptr = StringStorage::create(user_context, contents.current_allocator());
154  storage_ptr->assign(user_context, str, length);
155  contents.prepend(user_context, storage_ptr);
156  pointers.prepend(user_context, storage_ptr->data());
157 }
158 
159 size_t StringTable::parse(void *user_context, const char *str, const char *delim) {
160  if (StringUtils::is_empty(str)) {
161  return 0;
162  }
163 
164  size_t delim_length = strlen(delim);
165  size_t total_length = strlen(str);
166  size_t entry_count = StringUtils::count_tokens(str, delim);
167  if (entry_count < 1) {
168  return 0;
169  }
170 
171  resize(user_context, entry_count);
172 
173  // save each entry into the table
174  size_t index = 0;
175  const char *ptr = str;
176  while (!StringUtils::is_empty(ptr) && (index < entry_count)) {
177  size_t ptr_offset = ptr - str;
178  const char *next_delim = strstr(ptr, delim);
179  size_t token_length = (next_delim == nullptr) ? (total_length - ptr_offset) : (next_delim - ptr);
180  if (token_length > 0 && index < contents.size()) {
181  StringStorage *storage_ptr = static_cast<StringStorage *>(contents[index]);
182  storage_ptr->assign(user_context, ptr, token_length);
183  pointers.assign(user_context, index, storage_ptr->data());
184  ++index;
185  }
186  ptr = (next_delim != nullptr) ? (next_delim + delim_length) : nullptr;
187  }
188  return entry_count;
189 }
190 
191 bool StringTable::contains(const char *str) const {
192  if (StringUtils::is_empty(str)) {
193  return false;
194  }
195  for (size_t n = 0; n < contents.size(); ++n) {
196  StringStorage *storage_ptr = static_cast<StringStorage *>(contents[n]);
197  if (storage_ptr->contains(str)) {
198  return true;
199  }
200  }
201 
202  return false;
203 }
204 
205 const char **StringTable::data() const {
206  return reinterpret_cast<const char **>(pointers.data());
207 }
208 
209 // --
210 
211 } // namespace Internal
212 } // namespace Runtime
213 } // namespace Halide
214 
215 #endif // HALIDE_RUNTIME_STRING_STORAGE_H
const SystemMemoryAllocatorFns & current_allocator() const
void prepend(void *user_context, const void *entry_ptr)
void destroy(void *user_context)
Definition: pointer_table.h:99
void resize(void *user_context, size_t entry_count, bool realloc=true)
void append(void *user_context, const void *entry_ptr)
void assign(void *user_context, size_t index, const void *entry_ptr)
void assign(void *user_context, char ch)
static const SystemMemoryAllocatorFns & default_allocator()
static StringStorage * create(void *user_context, const SystemMemoryAllocatorFns &ma)
bool contains(const char *str) const
static void destroy(void *user_context, StringStorage *string_storage)
void append(void *user_context, const char *str, size_t length=0)
Definition: string_table.h:145
StringTable(const StringTable &)=delete
size_t parse(void *user_context, const char *str, const char *delim)
Definition: string_table.h:159
StringTable & operator=(const StringTable &)=delete
void assign(void *user_context, size_t index, const char *str, size_t length=0)
Definition: string_table.h:134
void destroy(void *user_context)
Definition: string_table.h:108
const char * operator[](size_t index) const
Definition: string_table.h:118
void resize(void *user_context, size_t capacity)
Definition: string_table.h:89
void clear(void *user_context)
Definition: string_table.h:98
void prepend(void *user_context, const char *str, size_t length=0)
Definition: string_table.h:152
void fill(void *user_context, const char **array, size_t count)
Definition: string_table.h:125
bool contains(const char *str) const
Definition: string_table.h:191
size_t strlen(const char *string)
This file defines the class FunctionDAG, which is our representation of a Halide pipeline,...
@ Internal
Not visible externally, similar to 'static' linkage in C.
const char * strstr(const char *, const char *)
static size_t count_tokens(const char *str, const char *delim)
static bool is_empty(const char *str)