Evo C++ Library v0.5.1
container.h
Go to the documentation of this file.
1 // Evo C++ Library
2 /* Copyright 2019 Justin Crowell
3 Distributed under the BSD 2-Clause License -- see included file LICENSE.txt for details.
4 */
6 
7 #pragma once
8 #ifndef INCL_evo_impl_container_h
9 #define INCL_evo_impl_container_h
10 
11 #include <memory.h>
12 #include <new>
13 
14 #include "../meta.h"
15 #include "hash.h"
16 
17 #if defined(EVO_CPP11)
18  #include <initializer_list> // std::initializer_list
19  #include <utility> // std::move
20 #endif
21 
22 namespace evo {
27 
29 
30 // Internal allocation/deallocation macros -- used by containers
32 #define EVO_IMPL_CONTAINER_MEM_ALLOC1(TYPE) \
33  (TYPE*)::malloc(sizeof(TYPE));
34 #define EVO_IMPL_CONTAINER_MEM_ALLOC_BYTES(TYPE, BYTES) \
35  (TYPE*)::malloc(BYTES);
36 #define EVO_IMPL_CONTAINER_MEM_FREE(PTR) { \
37  assert( PTR != NULL ); \
38  ::free(PTR); \
39 }
40 #define EVO_IMPL_CONTAINER_SWAP(PTR1, PTR2, TYPE) { \
41  char temp[sizeof(TYPE)]; \
42  memcpy(temp, PTR1, sizeof(TYPE)); \
43  memcpy(PTR1, PTR2, sizeof(TYPE)); \
44  memcpy(PTR2, temp, sizeof(TYPE)); \
45 }
46 
48 
50 #if (defined(EVO_EXCEPTIONS_ENABLED) && !defined(EVO_EXCEPTIONS_NOGUARDS)) || defined(DOXYGEN)
51 
52  #define EVO_EXCEPTION_GUARD_START try {
53 
55  #define EVO_EXCEPTION_GUARD_END } catch (...) { abort(); }
56 #else
57  #define EVO_EXCEPTION_GUARD_START
58  #define EVO_EXCEPTION_GUARD_END
59 #endif
60 
62 
65 struct Allocator {
66  static const bool SHARED = true;
67 
69  virtual ~Allocator() { }
70 
75  virtual char* alloc(ulong bytes) = 0;
76 
82  virtual char* realloc(void* ptr, ulong bytes) = 0;
83 
87  virtual void free(void* ptr) = 0;
88 };
91 
94 class Capacity {
95 public:
96  static const ulong INIT = 64;
97  static const ulong THRESHOLD = 134217728;
98 
103  static ulong init(ulong size)
104  { return (size < INIT ? INIT : size); }
105 
113  static ulong grow(ulong size) {
114  assert( size < ULONG_MAX );
115  ulong inc = (size >> 1) + 1;
116  if (inc > THRESHOLD)
117  inc = THRESHOLD;
118  if (ULONG_MAX - inc < size)
119  size = ULONG_MAX;
120  else
121  size += inc;
122  return size;
123  }
124 };
125 
127 
131 template<class T>
132 struct DataType {
133  typedef typename RemoveConst<T>::Type Item;
134 };
135 
137 
145 template<class T, class U=typename TypeId::Get<T>::Id>
146 struct DataInit : public DataType<T> {
147 #if defined(EVO_OLDCC)
148  typedef typename DataType<T>::Item Item;
149 #else
150  using typename DataType<T>::Item;
151 #endif
152 
159  static void init_safe(Item* data, ulong size=1) {
160  assert( data != NULL );
161  assert( size > 0 );
163  for (ulong i=0; i<size; ++i)
164  new(&data[i]) Item();
166  }
167 
176  static void init_safe(Item* data, ulong size, const Item* src, ulong count) {
177  assert( data != NULL );
178  assert( size > 0 );
179  assert( src != NULL );
180  assert( count > 0 );
181  if (count > size)
182  count = size;
183  ulong i = 0;
185  for (; i<count; ++i)
186  new(&data[i]) Item(src[i]);
187  for (; i<size; ++i)
188  new(&data[i]) Item();
190  }
191 
198  static void init(Item* data, ulong size=1) {
199  assert( data != NULL );
200  assert( size > 0 );
202  for (ulong i=0; i<size; ++i)
203  new(&data[i]) Item();
205  }
206 
212  static void init(Item* data, const Item* src, ulong count) {
213  assert( data != NULL );
214  assert( src != NULL );
215  assert( count > 0 );
217  for (ulong i=0; i<count; ++i)
218  new(&data[i]) Item(src[i]);
220  }
221 
228  static void init(Item* data, ulong size, const Item* src, ulong count) {
229  assert( data != NULL );
230  assert( size > 0 );
231  assert( src != NULL );
232  assert( count > 0 );
233  if (count > size)
234  count = size;
235  ulong i = 0;
237  for (; i<count; ++i)
238  new(&data[i]) Item(src[i]);
239  for (; i<size; ++i)
240  new(&data[i]) Item();
242  }
243 
252  static void init_tail_safe(Item* data, ulong oldSize, ulong newSize) {
253  assert( data != NULL );
254  assert( oldSize >= 0 );
255  assert( newSize >= 0 );
257  for (ulong i = oldSize; i < newSize; ++i)
258  new(&data[i]) Item();
260  }
261 
270  static void init_tail_fast(Item* data, ulong oldSize, ulong newSize) {
271  assert( data != NULL );
272  assert( oldSize >= 0 );
273  assert( newSize >= 0 );
275  for (ulong i=oldSize; i<newSize; ++i)
276  new(&data[i]) Item();
278  }
279 
284  static void initcopy(Item* item, const Item* src) {
285  assert( item != NULL );
286  assert( src != NULL );
288  new(*item) Item(*src);
290  }
291 
297  static void copy(Item* dest, const Item* src, ulong size) {
298  assert( dest != NULL );
299  assert( src != NULL );
300  assert( size > 0 );
302  for (ulong i=0; i<size; ++i)
303  dest[i] = src[i];
305  }
306 
311  static void uninit(Item* data, ulong size) {
312  assert( data != NULL );
313  assert( size > 0 );
315  while (size > 0)
316  data[--size].~T();
318  }
319 
326  static void uninit_free_ptr(Item** data, ulong size) {
327  assert( data != NULL );
328  assert( size > 0 );
330  for (; size > 0; ++data, --size)
331  if (*data != NULL) {
332  (**data).~T();
333  EVO_IMPL_CONTAINER_ITEM_FREE(*data);
334  }
336  }
337 
345  static void uninit_tail(Item* data, ulong oldSize, ulong newSize) {
346  assert( data != NULL );
347  assert( oldSize >= 0 );
348  assert( newSize >= 0 );
350  while (oldSize > newSize)
351  data[--oldSize].~T();
353  }
354 };
355 
357 template<class T> struct DataInit<T, TypeId::ByteCopy> : public DataType<T> {
358 #if defined(EVO_OLDCC)
359  typedef typename DataType<T>::Item Item;
360 #else
361  using typename DataType<T>::Item;
362 #endif
363  static void init_safe(T* data, ulong size=1) {
364  assert( data != NULL );
365  assert( size > 0 );
367  for (ulong i=0; i<size; ++i)
368  new(&data[i]) T();
370  }
371  static void init_safe(T* data, ulong size, const T* src, ulong count) {
372  assert( data != NULL );
373  assert( size > 0 );
374  assert( src != NULL );
375  assert( count > 0 );
376  if (count > size)
377  count = size;
378  if (count > 0)
379  memcpy(data, src, sizeof(T)*count);
381  for (ulong i=count; i<size; ++i)
382  new(&data[i]) T();
384  }
385  static void init(T* data, ulong size=1) {
386  assert( data != NULL );
387  assert( size > 0 );
389  for (ulong i=0; i<size; ++i)
390  new(&data[i]) T();
392  }
393  static void init(T* data, const T* src, ulong count) {
394  assert( data != NULL );
395  assert( src != NULL );
396  assert( count > 0 );
397  assert( (ulong)(data < src ? (src-data) : (data-src)) >= count );
398  if (count > 0)
399  memcpy(data, src, sizeof(T)*count);
400  }
401  static void init(T* data, ulong size, const T* src, ulong count) {
402  assert( data != NULL );
403  assert( size > 0 );
404  assert( src != NULL );
405  assert( count > 0 );
406  if (count > size)
407  count = size;
408  if (count > 0)
409  memcpy(data, src, sizeof(T)*count);
411  for (ulong i=count; i<size; ++i)
412  new(&data[i]) T();
414  }
415  static void init_tail_safe(T* data, ulong oldSize, ulong newSize) {
416  assert( data != NULL );
417  assert( oldSize >= 0 );
418  assert( newSize >= 0 );
420  for (ulong i=oldSize; i<newSize; ++i)
421  new(&data[i]) T();
423  }
424  static void init_tail_fast(T* data, ulong oldSize, ulong newSize) {
425  assert( data != NULL );
426  assert( oldSize >= 0 );
427  assert( newSize >= 0 );
429  for (ulong i=oldSize; i<newSize; ++i)
430  new(&data[i]) T();
432  }
433  static void initcopy(T* item, const T* src) {
434  assert( item != NULL );
435  assert( src != NULL );
437  new(*item) T(*src);
439  }
440  static void copy(T* dest, const T* src, ulong size) {
441  assert( dest != NULL );
442  assert( src != NULL );
443  assert( size > 0 );
444  if (size > 0)
445  memcpy(dest, src, sizeof(T)*size);
446  }
447  static void uninit(T* data, ulong size) {
448  assert( data != NULL );
449  assert( size > 0 );
451  while (size > 0)
452  data[--size].~T();
454  }
455  static void uninit_tail(T* data, ulong oldSize, ulong newSize) {
456  assert( data != NULL );
457  assert( oldSize >= 0 );
458  assert( newSize >= 0 );
460  while (oldSize > newSize)
461  data[--oldSize].~T();
463  }
464 };
465 template<class T> struct DataInit<T, TypeId::Pod> : public DataType<T> {
466 #if defined(EVO_OLDCC)
467  typedef typename DataType<T>::Item Item;
468 #else
469  using typename DataType<T>::Item;
470 #endif
471  static void init_safe(T* data, ulong size=1)
472  { memset(data, 0, size*sizeof(T)); }
473  static void init_safe(T* data, ulong size, const T* src, ulong count) {
474  assert( data != NULL );
475  assert( size > 0 );
476  assert( src != NULL );
477  assert( count > 0 );
478  if (count > size)
479  count = size;
480  if (count > 0)
481  memcpy(data, src, sizeof(T)*count);
482  size -= count;
483  if (size > 0)
484  memset(data+count, 0, sizeof(T)*size);
485  }
486  static void init(T*, ulong)
487  { }
488  static void init(T* data, const T* src, ulong count) {
489  assert( data != NULL );
490  assert( src != NULL );
491  assert( count > 0 );
492  if (count > 0)
493  memcpy(data, src, sizeof(T)*count);
494  }
495  static void init(T* data, ulong size, const T* src, ulong count) {
496  assert( data != NULL );
497  assert( size > 0 );
498  assert( src != NULL );
499  assert( count > 0 );
500  if (count > size)
501  count = size;
502  if (count > 0)
503  memcpy(data, src, sizeof(T)*count);
504  }
505  static void init_tail_safe(T* data, ulong oldSize, ulong newSize) {
506  assert( data != NULL );
507  assert( oldSize >= 0 );
508  assert( newSize >= 0 );
509  if (newSize > oldSize)
510  memset(data+oldSize, 0, (newSize-oldSize)*sizeof(T));
511  }
512  static void init_tail_fast(T*, ulong, ulong)
513  { }
514  static void initcopy(T* item, const T* src) {
515  assert( item != NULL );
516  assert( src != NULL );
517  memcpy(item, src, sizeof(T));
518  }
519  static void copy(T* dest, const T* src, ulong size) {
520  assert( dest != NULL );
521  assert( src != NULL );
522  assert( size > 0 );
523  if (size > 0)
524  memcpy(dest, src, sizeof(T)*size);
525  }
526  static void uninit(T*, ulong)
527  { }
528  static void uninit_tail(T*, ulong, ulong)
529  { }
530 };
533 
542 template<class T, class U=typename TypeId::Get<T>::Id>
543 struct DataCopy : public DataType<T> {
544 #if defined(EVO_OLDCC)
545  typedef typename DataType<T>::Item Item;
546 #else
547  using typename DataType<T>::Item;
548 #endif
549 
551  typedef typename AddConst<T>::Type& PassType;
552 
559  static void set_default(T& val)
560  { static const T DEFAULT; val = DEFAULT; }
561 
568 #if defined(DOXYGEN)
569  static void set_default_pod(T& val)
570 #else
571  static void set_default_pod(T&)
572 #endif
573  { }
574 };
575 
577 template<class T> struct DataCopy<T, TypeId::Pod> : public DataType<T> {
578 #if defined(EVO_OLDCC)
579  typedef typename DataType<T>::Item Item;
580 #else
581  using typename DataType<T>::Item;
582 #endif
583 
584 #if EVO_UNIT_TEST_ITEMARG_REF
585  typedef typename AddConst<Item>::Type& PassType; // Always pass by-reference so unit tests can detect constructor calls
586 #else
587  typedef Item PassType;
588 #endif
589 
590  static void set_default(Item& val)
591  { memset(&val, 0, sizeof(Item)); }
592  static void set_default_pod(Item& val)
593  { memset(&val, 0, sizeof(Item)); }
594 };
597 
606 template<class T, class U=typename TypeId::GetFill<T>::Id>
607 struct DataFill : public DataType<T> {
608 #if defined(EVO_OLDCC)
609  typedef typename DataType<T>::Item Item;
610 #else
611  using typename DataType<T>::Item;
612 #endif
613 
621  static void fill(T* dest, ulong size, const T& value) {
623  for (T* end = dest + size; dest < end; ++dest)
624  *dest = value;
626  }
627 
639  static void fillends(T* dest, ulong size, const T& value, ulong start, ulong end) {
640  assert( sizeof(T) > 1 );
641  assert( dest != NULL );
642  assert( start < end );
644  while (start > 0)
645  dest[--start] = value;
646  for (; end < size; ++end)
647  dest[end] = value;
649  }
650 };
651 
653 template<class T> struct DataFill<T, TypeId::ByteCopy> : public DataType<T> {
654 #if defined(EVO_OLDCC)
655  typedef typename DataType<T>::Item Item;
656 #else
657  using typename DataType<T>::Item;
658 #endif
659  typedef typename DataCopy<T>::PassType PassType;
660  static void fill(T* dest, ulong size, PassType value) {
661  assert( sizeof(T) > 1 );
662  for (T* end = dest + size; dest < end; ++dest)
663  memcpy(dest, &value, sizeof(T));
664  }
665  static void fillends(T* dest, ulong size, PassType value, ulong start, ulong end) {
666  assert( sizeof(T) > 1 );
667  assert( dest != NULL );
668  assert( start < end );
669  while (start > 0)
670  memcpy(dest + (--start), &value, sizeof(T));
671  for (; end < size; ++end)
672  memcpy(dest + end, &value, sizeof(T));
673  }
674 };
675 template<class T> struct DataFill<T, TypeId::Pod> : public DataType<T> {
676 #if defined(EVO_OLDCC)
677  typedef typename DataType<T>::Item Item;
678 #else
679  using typename DataType<T>::Item;
680 #endif
681  typedef typename DataCopy<T>::PassType PassType;
682  static void fill(T* dest, ulong size, PassType value) {
683  assert( sizeof(T) == 1 );
684  uchar cval;
685  memcpy(&cval, &value, 1);
686  memset(dest, (int)cval, size);
687  }
688  static void fillends(T* dest, ulong size, PassType value, ulong start, ulong end) {
689  assert( sizeof(T) == 1 );
690  assert( dest != NULL );
691  assert( start < end );
692  uchar cval;
693  memcpy(&cval, &value, 1);
694  if (start > 0)
695  memset(dest, cval, start);
696  if (end < size)
697  memset(dest+end, cval, size-end);
698  }
699 };
702 
711 template<class T, bool B=IsPodType<T>::value>
712 struct DataEqual {
721  static bool equal(const T* data1, const T* data2, ulong size) {
722  assert( data1 != NULL || size == 0 );
723  assert( data2 != NULL || size == 0 );
724  if (data1 != data2)
725  for (ulong i = 0; i < size; ++i)
726  if (!(data1[i] == data2[i]))
727  return false;
728  return true;
729  }
730 };
731 
733 template<class T> struct DataEqual<T,true> {
734  static bool equal(const T* data1, const T* data2, ulong size) {
735  assert( data1 != NULL || size == 0 );
736  assert( data2 != NULL || size == 0 );
737  return (size == 0 || memcmp(data1, data2, size * sizeof(T)) == 0);
738  }
739 };
742 
752 template<class T, bool B1=IsPodType<T>::value, bool B2=sizeof(T) == 1>
753 struct DataCompare : public DataType<T> {
754 #if defined(EVO_OLDCC)
755  typedef typename DataType<T>::Item Item;
756 #else
757  using typename DataType<T>::Item;
758 #endif
759 
769  static int compare(const T* data1, ulong size1, const T* data2, ulong size2) {
770  assert( data1 != NULL || size1 == 0 );
771  assert( data2 != NULL || size2 == 0 );
772  const ulong size = (size1 < size2 ? size1 : size2);
773  int result;
774  for (ulong i = 0; i < size; ++i) {
775  result = data1[i].compare(data2[i]);
776  if (result != 0)
777  return result;
778  }
779  if (size1 < size2)
780  result = -1;
781  else if (size2 < size1)
782  result = 1;
783  else
784  result = 0;
785  return result;
786  }
787 
795  static int compare(const T& item1, const T& item2)
796  { return item1.compare(item2); }
797 };
798 
800 template<class T> struct DataCompare<T,true,false> : public DataType<T> {
801 #if defined(EVO_OLDCC)
802  typedef typename DataType<T>::Item Item;
803 #else
804  using typename DataType<T>::Item;
805 #endif
806 
807  static int compare(const T* data1, ulong size1, const T* data2, ulong size2) {
808  assert( data1 != NULL || size1 == 0 );
809  assert( data2 != NULL || size2 == 0 );
810  int result;
811  if (data1 == data2) {
812  if (size1 == size2)
813  result = 0;
814  else
815  result = (size1 < size2 ? -1 : 1);
816  } else {
817  const T* end = data1 + (size1 < size2 ? size1 : size2);
818  for (result = 0; data1 < end; ++data1, ++data2) {
819  if (*data1 < *data2) {
820  result = -1;
821  break;
822  } else if (*data1 > *data2) {
823  result = 1;
824  break;
825  }
826  }
827  if (result == 0 && (size1 != size2 || data1 != end))
828  result = (size1 < size2 ? -1 : 1);
829  }
830  return result;
831  }
832 
833  static int compare(T item1, T item2)
834  { return (item1 < item2 ? -1 : (item1 == item2 ? 0 : 1)); }
835 };
836 
837 template<class T> struct DataCompare<T,true,true> : public DataType<T> {
838 #if defined(EVO_OLDCC)
839  typedef typename DataType<T>::Item Item;
840 #else
841  using typename DataType<T>::Item;
842 #endif
843 
844  static int compare(const T* data1, ulong size1, const T* data2, ulong size2) {
845  assert( data1 != NULL || size1 == 0 );
846  assert( data2 != NULL || size2 == 0 );
847  int result;
848  if (data1 == data2) {
849  if (size1 == size2)
850  result = 0;
851  else
852  result = (size1 < size2 ? -1 : 1);
853  } else if (size1 == size2) {
854  result = memcmp(data1, data2, size1);
855  } else if (size1 < size2) {
856  result = memcmp(data1, data2, size1);
857  if (result == 0)
858  result = -1;
859  } else {
860  result = memcmp(data1, data2, size2);
861  if (result == 0)
862  result = 1;
863  }
864  return result;
865  }
866 
867  static int compare(T item1, T item2)
868  { return (item1 < item2 ? -1 : (item1 == item2 ? 0 : 1)); }
869 };
872 
882 template<class T, class H=SpookyHash, bool B=IsPodType<T>::value>
883 struct DataHash : public DataType<T> {
884 #if defined(EVO_OLDCC)
885  typedef typename DataType<T>::Item Item;
886 #else
887  using typename DataType<T>::Item;
888 #endif
889  typedef H HashType;
890 
899  static ulong hash(const T* data, ulong size, ulong seed=0) {
900  for (ulong i = 0; i < size; ++size)
901  seed = data[i].hash(seed);
902  return seed;
903  }
904 
912  static ulong hash(const T& data, ulong seed=0)
913  { return data.hash(seed); }
914 };
915 
917 template<class T, class H> struct DataHash<T,H,true> : public DataType<T> {
918 #if defined(EVO_OLDCC)
919  typedef typename DataType<T>::Item Item;
920 #else
921  using typename DataType<T>::Item;
922 #endif
923  typedef H HashType;
924  static ulong hash(const T* data, ulong size, ulong seed=0)
925  { return H::hash(data, size*sizeof(T), seed); }
926  static ulong hash(const T& data, ulong seed=0)
927  { return H::hash(&data, sizeof(T), seed); }
928 };
931 
936 template<class T>
937 struct CompareBase : public DataType<T> {
938 #if defined(EVO_OLDCC)
939  typedef typename DataType<T>::Item Item;
940 #else
941  using typename DataType<T>::Item;
942 #endif
943  typedef typename DataCopy<T>::PassType PassItem;
944 
950  virtual int operator()(PassItem a, PassItem b) const = 0;
951 };
952 
964 template<class T>
965 struct Compare : public CompareBase<T> {
966 #if defined(EVO_OLDCC)
967  typedef typename DataType<T>::Item Item;
968  typedef typename CompareBase<T>::PassItem PassItem;
969 #else
970  using typename DataType<T>::Item;
971  using typename CompareBase<T>::PassItem;
972 #endif
973 
974  int operator()(PassItem a, PassItem b) const
975  { return DataCompare<T>::compare(a, b); }
976 };
977 
989 template<class T>
990 struct CompareR : public CompareBase<T> {
991 #if defined(EVO_OLDCC)
992  typedef typename DataType<T>::Item Item;
993  typedef typename CompareBase<T>::PassItem PassItem;
994 #else
995  using typename DataType<T>::Item;
996  using typename CompareBase<T>::PassItem;
997 #endif
998 
999  int operator()(PassItem a, PassItem b) const
1000  { return DataCompare<T>::compare(b, a); }
1001 };
1002 
1011 template<class T>
1012 struct CompareI : public CompareBase<T> {
1013 #if defined(EVO_OLDCC)
1014  typedef typename DataType<T>::Item Item;
1015  typedef typename CompareBase<T>::PassItem PassItem;
1016 #else
1017  using typename DataType<T>::Item;
1018  using typename CompareBase<T>::PassItem;
1019 #endif
1020 
1021  int operator()(PassItem a, PassItem b) const
1022  { return a.comparei(b); }
1023 };
1024 
1033 template<class T>
1034 struct CompareIR : public CompareBase<T> {
1035 #if defined(EVO_OLDCC)
1036  typedef typename DataType<T>::Item Item;
1037  typedef typename CompareBase<T>::PassItem PassItem;
1038 #else
1039  using typename DataType<T>::Item;
1040  using typename CompareBase<T>::PassItem;
1041 #endif
1042 
1043  int operator()(PassItem a, PassItem b) const
1044  { return b.comparei(a); }
1045 };
1046 
1048 
1060 template<class T>
1061 struct CompareHash : public Compare<T> {
1062 #if defined(EVO_OLDCC)
1063  typedef typename DataType<T>::Item Item;
1064  typedef typename CompareBase<T>::PassItem PassItem;
1065 #else
1066  using typename DataType<T>::Item;
1067  using typename CompareBase<T>::PassItem;
1068 #endif
1070 
1071  using Compare<T>::operator();
1072 
1078  ulong hash(PassItem key, ulong seed=0) const
1079  { return DataHash<T>::hash(key, seed); }
1080 };
1081 
1083 
1106 template<class T, uint sz>
1107 static uint fixed_array_size(T(&)[sz]) {
1108  return sz;
1109 }
1110 
1112 namespace impl {
1113  template <class T, uint N> char ( &FixedArraySizeHelper(T(&array)[N]) )[N];
1114 }
1120 #define EVO_FIXED_ARRAY_SIZE(ARRAY) (sizeof(evo::impl::FixedArraySizeHelper(ARRAY)))
1121 
1123 
1124 }
1125 #endif
static void fillends(T *dest, ulong size, const T &value, ulong start, ulong end)
Fill each end of destination with copies of given item.
Definition: container.h:639
static void copy(Item *dest, const Item *src, ulong size)
Copy already initialized data (assignment operator).
Definition: container.h:297
Base type for comparison types.
Definition: container.h:937
#define EVO_EXCEPTION_GUARD_START
Start exception guard (try block).
Definition: container.h:52
Optimized data hash helpers.
Definition: container.h:883
static void init_tail_safe(Item *data, ulong oldSize, ulong newSize)
Initialize new tail data (default constructor).
Definition: container.h:252
static ulong grow(ulong size)
Grow data size.
Definition: container.h:113
Comparison object used with containers that order/sort items.
Definition: container.h:965
int operator()(PassItem a, PassItem b) const
Comparison method.
Definition: container.h:999
static void uninit_free_ptr(Item **data, ulong size)
Uninitialize and free array of pointers (destructor).
Definition: container.h:326
RemoveConst< T >::Type Item
Item type (const removed)
Definition: container.h:133
Comparison object used with containers that order/sort items (case-insensitive).
Definition: container.h:1012
DataCopy< T >::PassType PassItem
Best type for passing Item, either const Item& (by reference) or Item (by value) for POD types...
Definition: container.h:943
#define EVO_EXCEPTION_GUARD_END
End exception guard, catch and abort().
Definition: container.h:55
Evo implementation detail: Hashing support.
Comparison object used with containers that order/sort items (reverse).
Definition: container.h:990
Optimized container size and capacity calculation.
Definition: container.h:94
Optimized data copy helpers.
Definition: container.h:543
Optimized data initialization and uninitialization helpers.
Definition: container.h:146
static void init_tail_fast(Item *data, ulong oldSize, ulong newSize)
Initialize new tail data (default constructor).
Definition: container.h:270
const T Type
Translated type.
Definition: meta.h:325
static int compare(const T &item1, const T &item2)
Compare items.
Definition: container.h:795
static uint fixed_array_size(T(&)[sz])
Get size of fixed-length array.
Definition: container.h:1107
Data comparison helpers.
Definition: container.h:753
H HashType
Hash class type
Definition: container.h:889
Data equality helper.
Definition: container.h:712
int operator()(PassItem a, PassItem b) const
Comparison method.
Definition: container.h:1043
T Type
Translated type.
Definition: meta.h:331
static void init_safe(Item *data, ulong size, const Item *src, ulong count)
Initialize data using copy constructor and default constructor.
Definition: container.h:176
static void set_default_pod(T &val)
Set new POD value to default value (0).
Definition: container.h:569
static void initcopy(Item *item, const Item *src)
Initialize new item as copy of src (copy constructor).
Definition: container.h:284
Hash object used with containers that hash items.
Definition: container.h:1061
static void set_default(T &val)
Set value to default.
Definition: container.h:559
static ulong hash(const T *data, ulong size, ulong seed=0)
Compute hash value from data.
Definition: container.h:899
ulong hash(PassItem key, ulong seed=0) const
Hash function method.
Definition: container.h:1078
Evo C++ Library namespace.
Definition: alg.h:11
int operator()(PassItem a, PassItem b) const
Comparison method.
Definition: container.h:974
int operator()(PassItem a, PassItem b) const
Comparison method.
Definition: container.h:1021
static bool equal(const T *data1, const T *data2, ulong size)
Compare array data for equality.
Definition: container.h:721
Base data type for optimizated data helpers.
Definition: container.h:132
static void uninit(Item *data, ulong size)
Uninitialize data (destructor).
Definition: container.h:311
static int compare(const T *data1, ulong size1, const T *data2, ulong size2)
Compare data.
Definition: container.h:769
Optimized data fill helpers.
Definition: container.h:607
AddConst< T >::Type & PassType
Most efficient type for passing as parameter (const-reference or POD value).
Definition: container.h:551
static void init(Item *data, ulong size=1)
Initialize data using default constructor.
Definition: container.h:198
Compare< T > CompareBase
Base compare type.
Definition: container.h:1069
static void fill(T *dest, ulong size, const T &value)
Fill with copies of given item.
Definition: container.h:621
static void init(Item *data, const Item *src, ulong count)
Initialize data using copy constructor.
Definition: container.h:212
static void init_safe(Item *data, ulong size=1)
Initialize data using default constructor.
Definition: container.h:159
static ulong init(ulong size)
Get initial data size.
Definition: container.h:103
static void init(Item *data, ulong size, const Item *src, ulong count)
Initialize data using copy constructor and default constructor.
Definition: container.h:228
static void uninit_tail(Item *data, ulong oldSize, ulong newSize)
Uninitialize old tail data (destructor).
Definition: container.h:345
static ulong hash(const T &data, ulong seed=0)
Compute hash value from data.
Definition: container.h:912
Comparison object used with containers that order/sort items (case-insensitive, reverse).
Definition: container.h:1034