JASSv2
slice.h
Go to the documentation of this file.
1 /*
2  SLICE.H
3  -------
4  Copyright (c) 2016 Andrew Trotman
5  Released under the 2-clause BSD license (See:https://en.wikipedia.org/wiki/BSD_licenses)
6 */
13 #pragma once
14 
15 #include <string.h>
16 
17 #include <iostream>
18 
19 #include "asserts.h"
20 #include "allocator_pool.h"
21 
22 namespace JASS
23  {
27  class slice
28  {
29  protected:
30  void *pointer;
31  size_t length;
32 
33  public:
34  /*
35  SLICE::SLICE()
36  --------------
37  */
43  slice(void *pointer = nullptr, size_t length = 0) :
44  pointer(pointer),
45  length(length)
46  {
47  /* Nothing */
48  }
49 
50  /*
51  SLICE::SLICE()
52  --------------
53  */
59  slice(void *start, void *end) :
60  pointer(start),
61  length((uint8_t *)end - (uint8_t *)start)
62  {
63  /* Nothing */
64  }
65  /*
66 
67  SLICE::SLICE()
68  --------------
69  */
74  slice(const char *message) :
75  pointer((void *)message),
76  length(strlen(message))
77  {
78  /* Nothing */
79  }
80 
81  /*
82  SLICE::SLICE()
83  --------------
84  */
91  slice(allocator &pool, void *start, void *end)
92  {
93  length = (uint8_t *)end - (uint8_t *)start;
94  pointer = (void *)pool.malloc(length);
95  memcpy(pointer, start, length);
96  }
97 
98  /*
99  SLICE::SLICE()
100  --------------
101  */
108  slice(allocator &pool, const char *start, const char *end)
109  {
110  length = end - start;
111  pointer = (void *)pool.malloc(length + 1);
112  memcpy(pointer, start, length);
113  ((char *)pointer)[length] = '\0';
114  }
115 
116  /*
117  SLICE::SLICE()
118  --------------
119  */
126  slice(allocator &pool, const unsigned char *start, const unsigned char *end)
127  {
128  length = end - start;
129  pointer = (void *)pool.malloc(length + 1);
130  memcpy(pointer, start, length);
131  ((char *)pointer)[length] = '\0';
132  }
133 
134  /*
135  SLICE::SLICE()
136  --------------
137  */
143  slice(allocator &pool, const char *start)
144  {
145  length = strlen(start);
146  pointer = (void *)pool.malloc(length + 1);
147  memcpy(pointer, start, length);
148  ((char *)pointer)[length] = '\0';
149  }
150 
151  /*
152  SLICE::SLICE()
153  --------------
154  */
160  slice(allocator &pool, const unsigned char *start)
161  {
162  length = strlen(reinterpret_cast<const char *>(start));
163  pointer = (void *)pool.malloc(length + 1);
164  memcpy(pointer, start, length);
165  ((char *)pointer)[length] = '\0';
166  }
167 
168  /*
169  SLICE::SLICE()
170  --------------
171  */
177  slice(allocator &pool, const slice &from)
178  {
179  length = from.size();
180  pointer = (void *)pool.malloc(length);
181  memcpy(pointer, from.address(), length);
182  }
183 
184  /*
185  SLICE::SLICE()
186  --------------
187  */
193  slice(allocator &pool, size_t bytes) :
194  pointer((void *)pool.malloc(bytes)),
195  length(bytes)
196  {
197  /* Nothing */
198  }
199 
200  /*
201  SLICE::SLICE()
202  --------------
203  */
208  slice(allocator &pool):
209  pointer(nullptr),
210  length(0)
211  {
212  /* Nothing */
213  }
214 
215  /*
216  SLICE::CLEAR()
217  --------------
218  */
223  void clear(void)
224  {
225  length = 0;
226  pointer = nullptr;
227  }
228 
229 
230 
231  /*
232  SLICE::OPERATOR=()
233  -------------------
234  */
240  slice &operator=(const slice &with)
241  {
242  pointer = with.pointer;
243  length = with.length;
244 
245  return *this;
246  }
247 
248  /*
249  SLICE::SIZE()
250  -------------
251  */
256  size_t size(void) const
257  {
258  return length;
259  }
260 
261  /*
262  SLICE::ADDRESS()
263  ----------------
264  */
269  void *address(void) const
270  {
271  return pointer;
272  }
273 
274  /*
275  SLICE::RESIZE()
276  ---------------
277  */
282  void resize(size_t new_size)
283  {
284  length = new_size;
285  }
286 
287  /*
288  SLICE::OPERATOR[]()
289  -------------------
290  */
297  uint8_t &operator[](size_t index) const
298  {
299  return ((uint8_t *)pointer)[index];
300  }
301 
302  /*
303  SLICE::STRICT_WEAK_ORDER_LESS_THAN()
304  ------------------------------------
305  */
313  static bool strict_weak_order_less_than(const slice &me, const slice &with)
314  {
315  if (me.size() == with.size())
316  return memcmp(me.address(), with.address(), me.size()) < 0;
317  else if (me.size() < with.size())
318  {
319  auto cmp = memcmp(me.address(), with.address(), me.size());
320  if (cmp == 0)
321  return true;
322  else
323  return cmp < 0 ? true : false;
324  }
325  else
326  {
327  auto cmp = memcmp(me.address(), with.address(), with.size());
328  if (cmp == 0)
329  return false;
330  else
331  return cmp < 0 ? true : false;
332  }
333  }
334 
335  /*
336  SLICE::OPERATOR<()
337  ------------------
338  */
345  bool operator<(const slice &with) const
346  {
347  if (size() < with.size())
348  return true;
349  if (size() > with.size())
350  return false;
351  return memcmp(address(), with.address(), size()) < 0;
352  }
353 
354  /*
355  SLICE::OPERATOR>()
356  ------------------
357  */
364  bool operator>(const slice &with) const
365  {
366  if (size() > with.size())
367  return true;
368  if (size() < with.size())
369  return false;
370  return memcmp(address(), with.address(), size()) > 0;
371  }
372 
373  /*
374  SLICE::OPERATOR==()
375  -------------------
376  */
382  bool operator==(const slice &with) const
383  {
384  if (size() != with.size())
385  return false;
386  return memcmp(address(), with.address(), size()) == 0;
387  }
388 
389  /*
390  SLICE::UNITTEST()
391  -----------------
392  */
396  static void unittest(void)
397  {
398  slice chunk1;
399  JASS_assert(chunk1.address() == nullptr && chunk1.size() == 0);
400 
401  slice chunk2((char *)unittest, (char *)unittest + 5);
402  JASS_assert(chunk2.address() == unittest && chunk2.size() == 5);
403 
404  allocator_pool pool;
405  char data[6];
406  slice chunk3(pool, (void *)data, (void *)((uint8_t *)data + 5));
407  JASS_assert(pool.size() == 5 && chunk3.size() == 5);
408 
409  const char *message = "here there and everywhere";
410  slice chunk4(pool, message, message + 4);
411  JASS_assert(pool.size() == 10 && chunk4.size() == 4);
412 
413  JASS_assert(chunk4[1] == 'e' && &chunk4[1] == (unsigned char *)chunk4.address() + 1);
414 
415  slice chunk5(pool, message);
416  JASS_assert(pool.size() == 36 && strcmp((char *)chunk5.address(), message) == 0);
417 
418  slice chunk6(pool, 10);
419  JASS_assert(pool.size() == 46 && chunk6.size() == 10);
420 
421  chunk6.resize(5);
422  JASS_assert(chunk6.size() == 5);
423 
424  JASS_assert(slice("a") < slice("b"));
425  JASS_assert(!(slice("b") < slice("a")));
426 
427  JASS_assert(!(slice("aa") < slice("b")));
428  JASS_assert(slice("b") < slice("aa"));
429 
430  JASS_assert(!(slice("a") > slice("b")));
431  JASS_assert(slice("b") > slice("a"));
432 
433  JASS_assert(slice("aa") > slice("b"));
434  JASS_assert(!(slice("b") > slice("aa")));
435 
436  JASS_assert(slice("a") == slice("a"));
437  JASS_assert(!(slice("aa") == slice("a")));
438 
439  /*
440  exhaustively test strict_weak_order_less_than() which emilates a strcmp()
441  */
442  JASS_assert(strict_weak_order_less_than(slice("aa"), slice("aa")) == false);
443  JASS_assert(strict_weak_order_less_than(slice("a"), slice("aa")) == true);
444  JASS_assert(strict_weak_order_less_than(slice("b"), slice("aa")) == false);
445  JASS_assert(strict_weak_order_less_than(slice("a"), slice("bb")) == true);
446  JASS_assert(strict_weak_order_less_than(slice("aa"), slice("a")) == false);
447  JASS_assert(strict_weak_order_less_than(slice("aa"), slice("b")) == true);
448  JASS_assert(strict_weak_order_less_than(slice("bb"), slice("a")) == false);
449 
450  puts("slice::PASSED");
451  }
452  };
453 
454  /*
455  OPERATOR<<()
456  ------------
457  */
464  inline std::ostream &operator<<(std::ostream &stream, const slice &data)
465  {
466  stream.write((char *)data.address(), data.size());
467  return stream;
468  }
469 
470  }
void resize(size_t new_size)
Change the length of the slice.
Definition: slice.h:282
slice(const char *message)
Constructor. Construct as a pointer to message and with length strlen(message). Does not copy...
Definition: slice.h:74
static bool strict_weak_order_less_than(const slice &me, const slice &with)
Return true if this < with.
Definition: slice.h:313
size_t length
The length of the data (in bytes).
Definition: slice.h:31
slice(allocator &pool, void *start, void *end)
Construct a slice by copying the data into allocator&#39;s pool of memory. This does NOT ever delete the ...
Definition: slice.h:91
bool operator<(const slice &with) const
Return true if this < with.
Definition: slice.h:345
C++ slices (string-descriptors)
Definition: slice.h:27
replacement for the C runtime library assert that also works in release.
void * address(void) const
Extract the pointer value from the slice.
Definition: slice.h:269
bool operator>(const slice &with) const
Return true if this > with.
Definition: slice.h:364
#define JASS_assert(expression)
Drop in replacement for assert() that aborts in Release as well as Debug.
Definition: asserts.h:33
slice(allocator &pool, const unsigned char *start)
Construct a slice by copying and &#39;\0&#39; termainating a string, using the allocator&#39;s pool of memory...
Definition: slice.h:160
slice(void *pointer=nullptr, size_t length=0)
Constructor.
Definition: slice.h:43
slice(allocator &pool, const char *start)
Construct a slice by copying and &#39;\0&#39; termainating a string, using the allocator&#39;s pool of memory...
Definition: slice.h:143
void clear(void)
Construct an empty slice with a pool allocator.
Definition: slice.h:223
slice(allocator &pool)
Construct an empty slice with a pool allocator.
Definition: slice.h:208
Simple block-allocator that internally allocates a large chunk then allocates smaller blocks from thi...
Definition: allocator_pool.h:61
Virtual base class for C style allocators.
Definition: allocator.h:33
virtual void * malloc(size_t bytes, size_t alignment=alignment_boundary)=0
Allocate a small chunk of memory from the internal pool and return a pointer to the caller...
slice(allocator &pool, size_t bytes)
Construct a slice by allocating bytes of memory from a pool allocator.
Definition: slice.h:193
Simple block-allocator that internally allocates a large chunk then allocates smaller blocks from thi...
slice(allocator &pool, const unsigned char *start, const unsigned char *end)
Construct a slice by copying and &#39;\0&#39; termainating a string, using the allocator&#39;s pool of memory...
Definition: slice.h:126
void * pointer
The start of the data.
Definition: slice.h:30
slice(allocator &pool, const char *start, const char *end)
Construct a slice by copying and &#39;\0&#39; termainating a string, using the allocator&#39;s pool of memory...
Definition: slice.h:108
uint8_t & operator[](size_t index) const
Return a reference to the n&#39;th byte past the start of the slice.
Definition: slice.h:297
slice & operator=(const slice &with)
Operator = (asignment operator)
Definition: slice.h:240
bool operator==(const slice &with) const
Return true if this == with.
Definition: slice.h:382
Definition: compress_integer_elias_delta_simd.c:23
static std::ostream & operator<<(std::ostream &output, JASS_anytime_stats &data)
Dump a human readable version of the data down an output stream.
Definition: JASS_anytime_stats.h:62
size_t size(void) const
Return the length of this slice.
Definition: slice.h:256
static void unittest(void)
Unit test this class.
Definition: slice.h:396
slice(allocator &pool, const slice &from)
Construct a slice by copying its contents into the pool allocator.
Definition: slice.h:177
slice(void *start, void *end)
Constructor.
Definition: slice.h:59