5#include "list_iterator.h"
10template <
typename ITEM, enum_allocate t_eallocate >
12 public ::range < ::list_iterator < ::set_node < ITEM > * > >
17 using BASE_RANGE = ::range < ::list_iterator < ::set_node < ITEM > * > >;
20 using BASE_NODE = ::set_node < ITEM > ;
21 using BASE_ITEM =
typename BASE_NODE::BASE_ITEM;
22 using HASH_TABLE = set_dynamic_hash_table < ITEM >;
23 using KEY =
typename BASE_NODE::KEY;
24 using ARG_KEY =
typename BASE_NODE::ARG_KEY;
25 using PAYLOAD =
typename BASE_NODE::PAYLOAD;
26 using ARG_PAYLOAD =
typename BASE_NODE::ARG_PAYLOAD;
27 using BASE_PAYLOAD =
typename BASE_NODE::PAYLOAD;
29 using CONST_ARG_KEY =
const non_const<typename BASE_NODE::ARG_KEY>;
31 using iterator =
typename BASE_RANGE::iterator;
32 using const_iterator =
typename BASE_RANGE::const_iterator;
34 using item_iterator = ::element1_list_iterator < BASE_NODE * >;
35 using payload_iterator = ::element2_list_iterator < BASE_NODE * >;
36 using const_item_iterator =
typename item_iterator::const_iterator;
37 using const_payload_iterator =
typename payload_iterator::const_iterator;
40 HASH_TABLE m_hashtable;
41 ::collection::count m_count;
45 template <
typename T, ::collection::count count>
46 node_set_base(
const T (&itema)[count]) :
47 node_set_base(itema, count)
51 node_set_base(BASE_ITEM * pitem, ::i32 iCount);
52 node_set_base(const ::std::initializer_list < BASE_ITEM > &
list_base);
53 node_set_base(
const node_set_base & m);
66 ::collection::count get_count()
const;
67 ::collection::count get_size()
const;
68 ::collection::count size()
const;
69 ::collection::count count()
const;
70 bool is_empty()
const;
73 bool find(ARG_KEY key, PAYLOAD &
payload)
const;
75 const_iterator find(ARG_KEY key)
const;
77 iterator get(ARG_KEY key);
79 PAYLOAD * defer_get(ARG_KEY key)
const;
81 bool should_set(ARG_KEY key)
107 template <
typename TKEY >
108 auto pop(
const TKEY & key)
111 auto p = this->find(key);
123 PAYLOAD & operator[](ARG_KEY key);
124 const PAYLOAD & operator[](ARG_KEY key)
const;
129 inline iterator set_key(ARG_KEY key);
131 iterator set_item(
const BASE_ITEM &
item)
134 return set_at((ARG_KEY)
item.key(), (ARG_PAYLOAD)
item.payload());
138 bool erase(iterator iterator);
139 bool contains(iterator iterator)
const;
141 bool toggle(ARG_KEY key)
144 auto pnode = this->find(key);
166 inline bool erase(ARG_KEY key)
169 auto p = this->find(key);
185 template <
typename iterator >
186 inline void erase_range(
const iterator & begin,
const iterator & last)
189 for(
auto it = begin; it != last; it++)
199 inline bool unhash(iterator iterator);
206 ::collection::count count(ARG_KEY key)
const;
207 bool has(ARG_KEY key)
const;
208 bool contains(ARG_KEY key)
const;
211 ::u32 GetHashTableSize()
const
214 return m_hashtable.GetHashTableSize();
219 void InitHashTable(::u32 hashSize,
bool bAllocNow =
true);
222 PAYLOAD defer_get(ARG_KEY argkey, ARG_PAYLOAD valueDefault)
const;
225 void assign(node_set_base & set)
228 auto it = set.begin();
242 BASE_NODE* __new_node(ARG_KEY key);
243 void __delete_node(BASE_NODE* pnode);
245 iterator _new(ARG_KEY key, ::u32& uiPack, ::u32& uiHash);
246 void _free(iterator pnode);
247 iterator _find(ARG_KEY key, ::u32& uiPack, ::u32& uiHash)
const;
251 template < prototype_container CONTAINER >
252 ::collection::count erase_nodes(CONTAINER container)
255 ::collection::count countRemoved = 0;
257 for(
auto & KEY : container)
274 template <
typename PRED >
275 iterator predicate_find(PRED pred)
278 auto p = this->begin();
298 node_set_base & operator = (
const node_set_base & m);
301 template <
typename TYPE >
302 ::pointer<TYPE>get_typed_ptr(::collection::index i = 0)
307 for(
auto & pvalue : *
this)
333 template < prototype_container CONTAINER >
334 void add_keys(
const CONTAINER& container)
337 for (
auto&
item : container)
347 template < prototype_container CONTAINER >
348 void erase_keys(
const CONTAINER& container)
351 for (
auto& KEY : container)
361 void container_ok()
const;
406 iterator set_at(ARG_KEY key, ARG_PAYLOAD
payload)
409 auto p = this->get(key);
424 template <
typename PAYLOAD2 >
425 iterator find_first_payload(
const PAYLOAD2 &
payload)
const;
428 template <
typename PAYLOAD2 >
429 inline bool erase_first_payload(
const PAYLOAD2
payload)
432 auto iterator = this->find_first_payload(
payload);
441 this->erase(iterator);
449 inline auto items() { return ::range<item_iterator>(*(item_iterator *)&this->begin(), *(item_iterator *)&this->end()); }
450 inline auto payloads() { return ::range<payload_iterator>(*(payload_iterator *)&this->begin(), *(payload_iterator *)&this->end()); }
451 inline auto items()
const { return ::range<const_item_iterator>((item_iterator)this->begin(), (item_iterator)this->end()); }
452 inline auto payloads()
const { return ::range<const_payload_iterator>((payload_iterator )this->begin(), (payload_iterator)this->end()); }
488 void merge_set(
const node_set_base & set)
491 for(
auto &
item : set)
494 this->set_item(
item);
501 void defer_merge(
const node_set_base& set)
504 for (
auto&
item : set)
507 if (!this->has(
item.key()))
510 this->set_item(
item);
526 inline void hash(iterator iterator, ::u32 uiPack, ::u32 uiHash);
527 void attach(iterator iterator, ::u32 uiPack, ::u32 uiHash);
529 void detach(iterator iterator);
530 void hash(::u32& uiPack, ::u32& uiHash, ARG_KEY)
const;
541 template <
class ARRAY >
542 bool erase_key_array(ARRAY a)
545 bool bRemoved =
false;
547 for(::collection::index i = 0; i < a.get_count(); i++)
550 bRemoved |= erase_key(a[i]);
559 template <
class ARRAY >
560 ::collection::count erase_node_array(ARRAY a)
563 ::collection::count countRemoved = 0;
565 for(::collection::index i = 0; i < a.get_count(); i++)
666 void transfer(iterator iterator, node_set_base * pnodesetbase =
nullptr);
667 void transfer(node_set_base * pnodesetbase, ARG_KEY key);
673template <
typename NODE, enum_allocate t_eallocate >
674inline ::collection::count node_set_base < NODE, t_eallocate >::get_count()
const
679template <
typename NODE, enum_allocate t_eallocate >
680inline ::collection::count node_set_base < NODE, t_eallocate >::get_size()
const
685template <
typename NODE, enum_allocate t_eallocate >
686inline ::collection::count node_set_base < NODE, t_eallocate >::count()
const
691template <
typename NODE, enum_allocate t_eallocate >
692inline ::collection::count node_set_base < NODE, t_eallocate >::size()
const
697template <
typename NODE, enum_allocate t_eallocate >
698node_set_base < NODE, t_eallocate > & node_set_base < NODE, t_eallocate >::operator = (
const node_set_base & m)
720template <
typename NODE, enum_allocate t_eallocate >
721inline bool node_set_base < NODE, t_eallocate >::is_empty()
const
729template <
typename NODE, enum_allocate t_eallocate >
730inline bool node_set_base < NODE, t_eallocate >::empty()
const
738template <
typename NODE, enum_allocate t_eallocate >
739inline typename node_set_base < NODE, t_eallocate >::iterator
740node_set_base < NODE, t_eallocate >::set_key(ARG_KEY key)
750template <
typename NODE, enum_allocate t_eallocate >
751void node_set_base < NODE, t_eallocate >::construct()
755 this->m_begin =
nullptr;
756 this->m_end =
nullptr;
761template <
typename NODE, enum_allocate t_eallocate >
762node_set_base < NODE, t_eallocate >::node_set_base()
770template <
typename NODE, enum_allocate t_eallocate >
771node_set_base < NODE, t_eallocate >::node_set_base(const ::std::initializer_list < BASE_ITEM > & items)
776 for(
auto &
item : items)
786template <
typename NODE, enum_allocate t_eallocate >
787node_set_base < NODE, t_eallocate >::node_set_base(BASE_ITEM * pitem, ::i32 iCount)
792 for(::i32 i = 0; i < iCount; i++)
802template <
typename NODE, enum_allocate t_eallocate >
803node_set_base < NODE, t_eallocate >::node_set_base(
const node_set_base & m)
818template <
typename NODE, enum_allocate t_eallocate >
819void node_set_base < NODE, t_eallocate >::erase_all()
830 for (
auto p = this->begin(); p; p = pnext)
842 m_hashtable.erase_all();
855 this->m_begin =
nullptr;
860template <
typename NODE, enum_allocate t_eallocate >
861inline void node_set_base < NODE, t_eallocate >::clear()
872template <
typename NODE, enum_allocate t_eallocate >
873node_set_base < NODE, t_eallocate >::~node_set_base()
876 ASSERT(m_count == 0);
879template <
typename NODE, enum_allocate t_eallocate >
880typename node_set_base < NODE, t_eallocate >::BASE_NODE*
881node_set_base < NODE, t_eallocate >::__new_node(ARG_KEY key)
884 if constexpr(t_eallocate == e_allocate_malloc)
887 auto pnode = (BASE_NODE*)::malloc(
sizeof(BASE_NODE));
889 ::new (pnode) BASE_NODE(key);
897 auto pnode = øraw_new BASE_NODE(key);
906template <
typename NODE, enum_allocate t_eallocate >
907void node_set_base < NODE, t_eallocate >::__delete_node(BASE_NODE* pnode)
910 if constexpr (t_eallocate == e_allocate_malloc)
928template <
typename NODE, enum_allocate t_eallocate >
929typename node_set_base < NODE, t_eallocate >::iterator node_set_base < NODE, t_eallocate >::_new(ARG_KEY key, ::u32& uiPack, ::u32& uiHash)
933 if (::is_null(m_hashtable.m_ppHash))
936 InitHashTable(m_hashtable.GetHashTableSize());
940 ENSURE(m_hashtable.m_ppHash);
942 auto p = this->__new_node(key);
947 this->m_begin.m_p->m_back = p;
951 if(m_hashtable.m_ppHash[uiPack])
954 m_hashtable.m_ppHash[uiPack]->m_pbackHash = &p->m_nextHash;
958 p->m_nextHash = m_hashtable.m_ppHash[uiPack];
960 m_hashtable.m_ppHash[uiPack] = p;
962 p->m_pbackHash = &m_hashtable.m_ppHash[uiPack];
964 p->m_next = this->m_begin.get();
968 this->m_begin.m_p->m_back =
nullptr;
979template <
typename NODE, enum_allocate t_eallocate >
985 auto next = pnode->m_next;
987 if(pnode->m_next !=
nullptr)
990 pnode->m_next->m_back = pnode->m_back;
994 if(pnode->m_back !=
nullptr)
997 pnode->m_back->m_next = pnode->m_next;
1001 if(this->m_begin.get() == pnode)
1004 this->m_begin = next;
1009 this->m_begin.m_p->m_back =
nullptr;
1017 this->__delete_node(pnode);
1025 ASSERT(m_count >= 0);
1038template <
typename NODE, enum_allocate t_eallocate >
1039typename node_set_base < NODE, t_eallocate >::iterator
1040node_set_base < NODE, t_eallocate >::_find(ARG_KEY key, ::u32& uiPack, ::u32& uiHash)
const
1043 uiHash = ::as_hash32(key).m_u;
1045 uiPack = uiHash % m_hashtable.GetHashTableSize();
1054 for(
auto p = m_hashtable.m_ppHash[uiPack]; p; p = p->m_nextHash)
1057 if (EqualElements<ARG_KEY>(p->key(), key))
1106template <
typename NODE, enum_allocate t_eallocate >
1107typename node_set_base < NODE, t_eallocate >::const_iterator
1108node_set_base < NODE, t_eallocate >::find(ARG_KEY key)
const
1115 auto pnode = _find(key, uiPack, uiHash);
1122template <
typename NODE, enum_allocate t_eallocate >
1123bool node_set_base < NODE, t_eallocate >::find(ARG_KEY key, PAYLOAD &
payload)
const
1142template <
typename NODE, enum_allocate t_eallocate >
1143typename node_set_base < NODE, t_eallocate >::PAYLOAD *
1144node_set_base < NODE, t_eallocate >::defer_get(ARG_KEY key)
const
1194template <
typename NODE, enum_allocate t_eallocate >
1195typename node_set_base < NODE, t_eallocate >::iterator
1196node_set_base < NODE, t_eallocate >::get(ARG_KEY key)
1199 ::u32 uiPack, uiHash;
1201 auto iterator = _find(key, uiPack, uiHash);
1206 iterator = _new(key, uiPack, uiHash);
1215template <
typename NODE, enum_allocate t_eallocate >
1216typename node_set_base < NODE, t_eallocate >::PAYLOAD & node_set_base < NODE, t_eallocate >::operator[](ARG_KEY key)
1219 return get(key)->payload();
1224template <
typename NODE, enum_allocate t_eallocate >
1225const typename node_set_base < NODE, t_eallocate >::PAYLOAD & node_set_base < NODE, t_eallocate >::operator[](ARG_KEY key)
const
1233 throw_exception(error_key_not_found);
1242template <
typename NODE, enum_allocate t_eallocate >
1246 if(
iterator.m_p->m_nextHash !=
nullptr)
1262template<
typename NODE, enum_allocate t_eallocate>
1263inline bool node_set_base<NODE, t_eallocate>::contains(
iterator iterator)
const
1280template <
typename NODE, enum_allocate t_eallocate >
1281inline ::collection::count node_set_base < NODE, t_eallocate >::count(ARG_KEY key)
const
1284 return this->find(key) ? 1 : 0;
1289template <
typename NODE, enum_allocate t_eallocate >
1290bool node_set_base < NODE, t_eallocate >::has(ARG_KEY key)
const
1293 return this->count(key) > 0;
1298template <
typename NODE, enum_allocate t_eallocate >
1299bool node_set_base < NODE, t_eallocate >::contains(ARG_KEY key)
const
1302 return this->has(key);
1341template <
typename NODE, enum_allocate t_eallocate >
1342typename node_set_base < NODE, t_eallocate >::PAYLOAD node_set_base < NODE, t_eallocate > ::defer_get(ARG_KEY key, ARG_PAYLOAD payloadDefault)
const
1350 return payloadDefault;
1373using f64_set = set < ::f64 >;
1375using dword_set = set < ::u32 >;
1377using uptr_set = set < ::uptr >;
1398template <
typename NODE, enum_allocate t_eallocate >
1399using key_set = node_set_base < NODE, t_eallocate >;
1402#define __declare_key(xkeytype, xkey) \
1403struct xkeytype : public ::KEY < xkeytype > \
1406 PAIR_DEFAULT_IMPL(xkeytype, KEY, ARG_KEY, xkey); \
1407 KEY & KEY() { return xkey; } \
1408 ARG_KEY key() const { return xkey; } \
1413#define __declare_key_tuple_size(KEY) \
1414template<> ALIENATED_ANDROID_ANARCHY ::std::tuple_size< KEY > : ::std::integral_constant<size_t, 1> {} }
1418#define __declare_set(xsettype, xkeyvaluetype, xkeytype, xkey, xvaluetype, xvalue) \
1419__declare_key_value(xkeyvaluetype, xkeytype, xkey, xvaluetype, xvalue); \
1420using xsettype = pair_set < xkeyvaluetype >
1424#define __declare_set_key_value(xsettype, xkeyvaluetype, xkeytype, xkey, xvaluetype, xvalue) \
1425__declare_set(xkeyvaluetype, xkeytype, xkey, xvaluetype, xvalue); \
1426__declare_pair_tuple_size(xsettype)
1429#define __declare_set_key_value(xsettype, xkeyvaluetype, xkeytype, xkey, xvaluetype, xvalue) \
1430__declare_set(xkeyvaluetype, xkeytype, xkey, xvaluetype, xvalue);
1435using iptr_set = set < iptr >;
1437using index_set = set < ::collection::index >;
1439using string_set = set < string >;
1447template <
typename NODE, enum_allocate t_eallocate >
1448void node_set_base < NODE, t_eallocate >::InitHashTable(
1449 ::u32 nHashSize,
bool bAllocNow)
1456 ASSERT(this->m_count == 0);
1457 ASSERT(nHashSize > 0);
1459 this->m_hashtable.InitHashTable(nHashSize,bAllocNow);
1464template <
typename NODE, enum_allocate t_eallocate >
1469 if(::is_set(
iterator.m_p->m_nextHash))
1483template <
typename ITEM, enum_allocate t_eallocate >
1484void node_set_base < ITEM, t_eallocate >::transfer(
node_set_base* pnodesetbase, ARG_KEY key)
1491 auto pnode = pnodesetbase->_find(key, uiPack, uiHash);
1496 pnodesetbase->detach(pnode);
1498 attach(pnode, uiPack, uiHash);
1505template <
typename ITEM, enum_allocate t_eallocate >
1509 if (pnodesetbase ==
this)
1516 if (::is_set(pnodesetbase))
1527 hash(uiPack, uiHash,
iterator->key());
1535template <
typename ITEM, enum_allocate t_eallocate >
1536void node_set_base < ITEM, t_eallocate >::attach(
iterator iterator, ::u32 uiPack, ::u32 uiHash)
1546 this->m_begin.m_p->m_back = pnode;
1550 pnode->m_next = this->begin().m_p;
1552 this->begin() = pnode;
1554 this->begin().m_p->m_back =
nullptr;
1558 ASSERT(this->m_count > 0);
1563template <
typename ITEM, enum_allocate t_eallocate >
1564void node_set_base < ITEM, t_eallocate >::hash(
iterator iterator, ::u32 uiPack, ::u32 uiHash)
1570 if (::is_null(this->m_hashtable.m_ppHash))
1573 InitHashTable(this->m_hashtable.GetHashTableSize());
1577 if (::is_set(this->m_hashtable.m_ppHash[uiPack]))
1580 this->m_hashtable.m_ppHash[uiPack]->m_pbackHash = &pnode->m_nextHash;
1584 pnode->m_nextHash = this->m_hashtable.m_ppHash[uiPack];
1586 this->m_hashtable.m_ppHash[uiPack] = pnode;
1588 pnode->m_pbackHash = &this->m_hashtable.m_ppHash[uiPack];
1593template <
typename ITEM, enum_allocate t_eallocate >
1594void node_set_base < ITEM, t_eallocate >::hash(::u32& uiPack, ::u32& uiHash, ARG_KEY key)
const
1597 uiHash = ::as_hash32(key).m_u;
1599 uiPack = uiHash % this->m_hashtable.GetHashTableSize();
1604template <
typename ITEM, enum_allocate t_eallocate >
1612 auto next = pnode->m_next;
1614 if (::is_set(pnode->m_next))
1617 pnode->m_next->m_back = pnode->m_back;
1621 if (::is_set(pnode->m_back))
1624 pnode->m_back->m_next = pnode->m_next;
1628 if (this->m_begin.get() == pnode)
1631 this->m_begin = next;
1633 if (::is_set(this->m_begin))
1636 this->m_begin.m_p->m_back =
nullptr;
1650 ASSERT(this->m_count >= 0);
1653 if (this->m_count == 0)
1666template <
typename ITEM, enum_allocate t_eallocate >
1667template <
typename PAYLOAD2 >
1668inline typename node_set_base < ITEM, t_eallocate >::iterator
1669node_set_base < ITEM, t_eallocate >::find_first_payload(
const PAYLOAD2 &
payload)
const
1672 auto p = this->begin();
Definition std_iterator.h:49