8 #ifndef INCL_evo_ptrlist_h 9 #define INCL_evo_ptrlist_h 17 #pragma warning(disable:4457) 29 #define EVO_IMPL_PTRLIST_ITEMS_ALLOC_COPY(DEST, SRC, FIRST, LAST) { \ 31 for (Size i=FIRST; i<=LAST; ++i) { \ 32 if (SRC[i] == NULL) { \ 35 DEST[i] = item = EVO_IMPL_CONTAINER_MEM_ALLOC1(Value); \ 36 new(item) T(*SRC[i]); \ 41 #define EVO_IMPL_PTRLIST_ITEMS_ALLOC_COPY_ZERO_NEW(FIRST, LAST) { \ 43 memset(data_, 0, sizeof(Item*)*FIRST); \ 44 Size end = LAST + 1; \ 46 memset(data_+end, 0, sizeof(Item*)*(size_-end)); \ 51 #define EVO_IMPL_PTRLIST_ALLOC(HDR, DATA, SIZE) { \ 53 HDR = (Header*)::malloc( sizeof(Header) + (SIZE*sizeof(T*)) ); \ 54 assert( HDR != NULL ); \ 57 DATA = (Item*)(HDR + 1); \ 60 #define EVO_IMPL_PTRLIST_ALLOC_COPY(SRC_HDR, SRC_DATA) { \ 61 EVO_IMPL_PTRLIST_ALLOC(header_, data_, size_); \ 62 header_->used = SRC_HDR->used; \ 63 header_->first = SRC_HDR->first; \ 64 header_->last = SRC_HDR->last; \ 65 if (header_->used > 0) { \ 66 Size last = header_->last; \ 67 EVO_IMPL_PTRLIST_ITEMS_ALLOC_COPY(data_, SRC_DATA, header_->first, last); \ 68 EVO_IMPL_PTRLIST_ITEMS_ALLOC_COPY_ZERO_NEW(header_->first, last); \ 70 memset(data_, 0, sizeof(Item*)*size_); \ 73 #define EVO_IMPL_PTRLIST_REALLOC(HDR, DATA, SIZE) { \ 74 assert( (size_t)HDR > sizeof(Header) ); \ 75 assert( DATA != NULL ); \ 77 HDR = (Header*)::realloc( HDR, sizeof(Header) + (SIZE*sizeof(T*)) ); \ 78 assert( HDR != NULL ); \ 80 DATA = (Item*)(HDR+1); \ 83 #define EVO_IMPL_PTRLIST_CLEAR(HDR) { \ 84 if (HDR->used > 0) { \ 85 assert( HDR->first <= HDR->last ); \ 86 Item* data = (Item*)(HDR+1); \ 87 Item* end = data + HDR->last; \ 88 for (data += HDR->first; data <= end; ++data) \ 89 if (*data != NULL) { \ 91 EVO_IMPL_CONTAINER_MEM_FREE(*data); \ 96 #define EVO_IMPL_PTRLIST_FREEMEM(HDR) { \ 97 assert( (size_t)HDR > sizeof(Header) ); \ 101 #define EVO_IMPL_PTRLIST_FREE(HDR) { \ 102 if (HDR != NULL && --HDR->refs == 0) { \ 103 EVO_IMPL_PTRLIST_CLEAR(HDR); \ 104 EVO_IMPL_PTRLIST_FREEMEM(HDR); \ 199 template<
class T,
class TSize=SizeT>
213 typedef Value IterItem;
232 if (data.
size_ > 0) {
245 { EVO_IMPL_PTRLIST_FREE(
header_); }
247 #if defined(EVO_CPP11) 253 resize((Size)init.size());
255 for (
const auto& val : init)
276 EVO_IMPL_PTRLIST_FREE(
header_);
305 {
return set(
data); }
323 assert(
data_ != NULL );
326 EVO_IMPL_PTRLIST_CLEAR(
header_);
327 memset(start, 0, len*
sizeof(Item*));
347 assert(
data_ != NULL );
348 EVO_IMPL_PTRLIST_CLEAR(
header_);
349 EVO_IMPL_PTRLIST_FREEMEM(
header_);
365 ThisType&
set(
const ThisType&
data) {
368 EVO_IMPL_PTRLIST_FREE(
header_);
369 if (
data.size_ > 0) {
401 {
return (
data_ == NULL); }
449 assert(
data_ != NULL );
450 assert( index <
size_ );
461 const Item
item(Key index)
const {
463 assert(
data_ != NULL );
464 assert( index <
size_ );
505 result = (data.
data_ == NULL ? 0 : -1);
506 else if (data.
data_ == NULL)
520 { result = (last1 == last2 ? 0 : -1);
break; }
522 { result = 1;
break; }
524 item2 = data.
data_[i];
527 { result = -1;
break; }
528 }
else if (item2 == NULL)
529 { result = 1;
break; }
548 result = (data.
data_ == NULL);
549 else if (data.
data_ == NULL)
565 item2 = data.
data_[i];
568 { result =
false;
break; }
569 }
else if (item2 == NULL || !(*item1 == *item2))
570 { result =
false;
break; }
587 result = (data.
data_ != NULL);
588 else if (data.
data_ == NULL)
604 item2 = data.
data_[i];
607 { result =
true;
break; }
608 }
else if (item2 == NULL || !(*item1 == *item2))
609 { result =
true;
break; }
621 {
return Iter(*
this); }
629 {
return IterM(*
this); }
633 {
return Iter(*
this); }
652 Key
find(
const Value& value, Key start=0, Key
end=
END)
const {
655 if (start < header_->
first)
660 for (; start<
end; ++start) {
662 if (item != NULL && *item == value)
663 { result = start;
break; }
682 if (start < header_->
first)
689 if (item != NULL && *item == value)
690 { result =
end;
break; }
717 Item
getitem(
const Key& key,
bool* created=NULL) {
726 if (result == NULL) {
729 data_[key] = result = EVO_IMPL_CONTAINER_MEM_ALLOC1(Value);
733 else if (key < header_->
first)
740 }
else if (created != NULL)
754 Value&
get(
const Key& key,
bool* created=NULL)
755 {
return *
getitem(key, created); }
796 Item* olddata =
data_;
797 EVO_IMPL_PTRLIST_ALLOC_COPY(oldheader, olddata);
815 if (newsize ==
size_) {
819 EVO_IMPL_PTRLIST_FREE(
header_);
824 }
else if (
size_ > 0) {
831 if (used > 0 && first < newsize) {
834 Item* olddata =
data_;
835 if (newsize >
size_) {
838 EVO_IMPL_PTRLIST_ALLOC_COPY(oldheader, olddata);
842 if (newsize <= last) {
846 if ((newsize + 1 - first) < (
size_- newsize)) {
849 for (Item* start=
data_+first; --data > start; )
864 while (--last > first &&
data_[last] == NULL)
874 EVO_IMPL_PTRLIST_ITEMS_ALLOC_COPY(
data_, olddata, first, last);
875 EVO_IMPL_PTRLIST_ITEMS_ALLOC_COPY_ZERO_NEW(first, last);
881 if (newsize >
size_) {
890 if (used > 0 && newsize <= last) {
897 EVO_IMPL_CONTAINER_MEM_FREE(*data);
906 while (--last > first &&
data_[last] == NULL)
931 memset(
data_, 0,
sizeof(Item)*newsize);
965 EVO_IMPL_PTRLIST_FREE(
header_);
966 if (data.
size_ > 0) {
987 ThisType&
remove(Key key) {
995 if (
data_[key] != NULL) {
1007 Item* olddata =
data_;
1017 for (Size i=first, last_copy=i; i<=
last; ++i) {
1023 if (olddata[i] != NULL) {
1025 data_[i] = item = EVO_IMPL_CONTAINER_MEM_ALLOC1(Value);
1026 new(
item) T(*olddata[i]);
1030 assert( i <= last );
1031 }
else if (i == last) {
1033 assert( last_copy > 0 && last_copy < last );
1036 }
else if (olddata[i] == NULL) {
1039 data_[i] = item = EVO_IMPL_CONTAINER_MEM_ALLOC1(Value);
1040 new(
item) T(*olddata[i]);
1044 EVO_IMPL_PTRLIST_ITEMS_ALLOC_COPY_ZERO_NEW(first, last);
1052 EVO_IMPL_CONTAINER_MEM_FREE(item);
1060 while (++key < last &&
data_[key] == NULL)
1066 while (--key > first &&
data_[key] == NULL)
1086 { EVO_IMPL_CONTAINER_SWAP(
this, &list, ThisType); }
1092 void iterInitMutable()
1094 const IterItem* iterFirst(IterKey& key)
const {
1095 const IterItem* result;
1098 result =
data_[key];
1105 const IterItem* iterNext(IterKey& key)
const {
1106 const IterItem* result;
1111 if (++key == last ||
data_[key] != NULL)
1112 { result =
data_[key];
break; }
1114 { key =
END; result = NULL; }
1119 const IterItem* iterNext(Size count, IterKey& key)
const {
1120 const IterItem* result;
1125 if (++key == last) {
1127 { key =
END; result = NULL;
break; }
1128 result =
data_[key];
1130 }
else if (
data_[key] != NULL && --count == 0)
1131 { result =
data_[key];
break; }
1133 { key =
END; result = NULL; }
1138 const IterItem* iterLast(IterKey& key)
const {
1139 const IterItem* result;
1142 result =
data_[key];
1149 const IterItem* iterPrev(IterKey& key)
const {
1150 const IterItem* result;
1155 if (--key == first ||
data_[key] != NULL)
1156 { result =
data_[key];
break; }
1158 { key =
END; result = NULL; }
1163 const IterItem* iterPrev(Size count, IterKey& key)
const {
1164 const IterItem* result;
1169 if (--key == first) {
1171 { key =
END; result = NULL;
break; }
1172 result =
data_[key];
1174 }
else if (
data_[key] != NULL && --count == 0)
1175 { result =
data_[key];
break; }
1177 { key =
END; result = NULL; }
1182 Size iterCount()
const 1184 const IterItem* iterSet(IterKey& key)
const {
1185 const IterItem* result;
1191 { key =
END; result = NULL;
break; }
1192 else if (
data_[key] != NULL)
1193 { result =
data_[key];
break; }
1224 #undef EVO_IMPL_PTRLIST_ITEMS_ALLOC_COPY 1225 #undef EVO_IMPL_PTRLIST_ITEMS_ALLOC_COPY_ZERO_NEW 1226 #undef EVO_IMPL_PTRLIST_ALLOC 1227 #undef EVO_IMPL_PTRLIST_ALLOC_COPY 1228 #undef EVO_IMPL_PTRLIST_REALLOC 1229 #undef EVO_IMPL_PTRLIST_CLEAR 1230 #undef EVO_IMPL_PTRLIST_FREEMEM 1231 #undef EVO_IMPL_PTRLIST_FREE 1236 #if defined(_MSC_VER) 1237 #pragma warning(pop) Iter cend() const
Get iterator at end (const).
Definition: ptrlist.h:624
Iter begin() const
Get iterator at first item (const).
Definition: ptrlist.h:632
Size used() const
Get list used size, number of non-null items.
Definition: ptrlist.h:420
T Value
Value type (Item dereferenced, same as T)
Definition: ptrlist.h:205
~PtrList()
Destructor.
Definition: ptrlist.h:244
Item getitem(const Key &key, bool *created=NULL)
Get item for key, creating if needed (mutable).
Definition: ptrlist.h:717
ThisType & resizemin(Size minsize)
Resize to minimum size while preserving existing data (modifier).
Definition: ptrlist.h:946
const Item operator[](Key index) const
Get item at position (const).
Definition: ptrlist.h:447
const ThisType & asconst() const
Explicitly use a const reference to this.
Definition: ptrlist.h:292
IterM end()
Get iterator at end.
Definition: ptrlist.h:636
Random access iterator.
Definition: iter.h:904
Item operator()(Key index)
Get item at position (mutable).
Definition: ptrlist.h:767
TSize Size
List size integer type
Definition: ptrlist.h:203
bool operator==(const ThisType &data) const
Equality operator.
Definition: ptrlist.h:545
ThisType & unshare()
Make sure data is not shared by allocating new buffer if needed (modifier).
Definition: ptrlist.h:790
Key findr(const T &value, Key start=0, Key end=END) const
Find last occurrence of item with reverse search.
Definition: ptrlist.h:679
PtrList< T, Size > ThisType
This list type.
Definition: ptrlist.h:208
PtrList()
Default constructor sets as null.
Definition: ptrlist.h:220
Basic integer type.
Definition: type.h:980
Key iend(Size offset=0) const
Get index for last item position using offset.
Definition: ptrlist.h:493
Data comparison helpers.
Definition: container.h:753
IteratorRa< ThisType > IterM
Iterator (mutable) - IteratorRa.
Definition: ptrlist.h:217
Iter cbegin() const
Get iterator at first item (const).
Definition: ptrlist.h:620
Item * data_
Data pointer, NULL if null, can be 1 if empty (size_=0)
Definition: ptrlist.h:1217
int compare(const ThisType &data) const
Comparison.
Definition: ptrlist.h:502
bool null() const
Get whether null.
Definition: ptrlist.h:400
Evo implementation detail: Container iterators.
ThisType & resize(Size newsize)
Resize while preserving existing data (modifier).
Definition: ptrlist.h:814
PtrList(std::initializer_list< T > init)
Sequence constructor (C++11).
Definition: ptrlist.h:251
ThisType & copy(const ThisType &data)
Set as full (unshared) copy using data pointer (modifier).
Definition: ptrlist.h:960
T * Item
Item type (pointer to Value)
Definition: ptrlist.h:206
void swap(ThisType &list)
Swap with another list.
Definition: ptrlist.h:1085
PtrList(const ThisType &data)
Copy constructor.
Definition: ptrlist.h:231
ThisType & setempty()
Set as empty but not null.
Definition: ptrlist.h:385
static const EndT END
Special integer value for indicating end of items or no item.
Definition: type.h:1846
Evo container foundation types and macros.
Iter end() const
Get iterator at end (const).
Definition: ptrlist.h:640
bool shared() const
Get whether shared.
Definition: ptrlist.h:428
Evo C++ Library namespace.
Definition: alg.h:11
IteratorRa< ThisType >::Const Iter
Iterator (const) - IteratorRa.
Definition: ptrlist.h:216
bool operator!=(const ThisType &data) const
Inequality operator.
Definition: ptrlist.h:584
static const EndT NONE
Special integer value for indicating no item or unknown item.
Definition: type.h:1832
ThisType & operator=(ThisType &&src)
Move assignment operator (C++11).
Definition: ptrlist.h:275
Size size_
Data size (same as header.size), 0 if empty.
Definition: ptrlist.h:1218
const Item first() const
Get first non-null item (const).
Definition: ptrlist.h:474
Item itemM(Key index)
Get item at position (mutable).
Definition: ptrlist.h:780
Size Key
Key type (item index)
Definition: ptrlist.h:204
Key find(const Value &value, Key start=0, Key end=END) const
Find first occurrence of item with forward search.
Definition: ptrlist.h:652
#define EVO_PPEMPTY
Special pointer value for empty but not NULL (used in containers).
Definition: type.h:1863
Header * header_
Data header pointer, NULL if no buffer allocated.
Definition: ptrlist.h:1216
ThisType & clear()
Clear by removing all items.
Definition: ptrlist.h:313
PtrList(ThisType &&src)
Move constructor (C++11).
Definition: ptrlist.h:262
static void init_safe(Item *data, ulong size=1)
Initialize data using default constructor.
Definition: container.h:159
const Item item(Key index) const
Get item at position (const).
Definition: ptrlist.h:461
const Item last() const
Get last non-null item (const).
Definition: ptrlist.h:483
ThisType & operator=(const ThisType &data)
Assignment operator.
Definition: ptrlist.h:304
Size size() const
Get list size.
Definition: ptrlist.h:414
const Item * data() const
Get data pointer for direct access (const).
Definition: ptrlist.h:437
Sequential list of managed pointers with random access.
Definition: ptrlist.h:200
IterM begin()
Get iterator at first item (mutable).
Definition: ptrlist.h:628
bool empty() const
Get whether empty.
Definition: ptrlist.h:408
Item * dataM()
Get data pointer (mutable).
Definition: ptrlist.h:705