47 template <
typename T,
typename ForeignIndex,
typename Alloc = std::allocator<std::pair<T, const ForeignIndex>>>
54 typedef std::pair<data_type, const foreign_index_type>
value_type;
57 typedef std::pair<const foreign_index_type, const foreign_index_type>
skip_type;
59 typedef typename std::allocator_traits<allocator_type>::pointer
pointer;
60 typedef typename std::allocator_traits<allocator_type>::const_pointer
const_pointer;
61 typedef typename std::allocator_traits<allocator_type>::size_type
size_type;
62 typedef typename std::allocator_traits<allocator_type>::difference_type
difference_type;
68 iValue{aValue}, iSkip{aSkip}
94 typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<node> node_allocator_type;
110 iContainer{}, iNode{}, iContainerPosition{ 0 }
114 iContainer{ aOther.iContainer }, iNode{ aOther.iNode }, iContainerPosition{ aOther.iContainerPosition }
119 iContainer = aOther.iContainer;
120 iNode = aOther.iNode;
121 iContainerPosition = aOther.iContainerPosition;
126 iContainer{ &aContainer }, iNode{ nullptr }, iContainerPosition{ aContainerPosition }
128 iNode = iContainer->find_node(aContainerPosition);
130 *
this = iContainer->
end();
133 iContainer{ &aContainer }, iNode{ aNode }, iContainerPosition{ iContainer->
index(*this) }
137 iContainer{ &aContainer }, iNode{ aNode }, iContainerPosition{ aContainerPosition }
144 iNode =
static_cast<node*
>(iNode->next());
145 ++iContainerPosition;
150 iNode =
static_cast<node*
>(iNode !=
nullptr ? iNode->previous() : iContainer->back_node());
151 --iContainerPosition;
160 *
this =
iterator{*iContainer, container_position() + aDifference};
167 *
this =
iterator{*iContainer, container_position() - aDifference};
176 bool operator==(
const iterator& aOther)
const {
return container_position() == aOther.container_position(); }
177 bool operator!=(
const iterator& aOther)
const {
return container_position() != aOther.container_position(); }
178 bool operator<(
const iterator& aOther)
const {
return container_position() < aOther.container_position(); }
179 bool operator<=(
const iterator& aOther)
const {
return container_position() <= aOther.container_position(); }
180 bool operator>(
const iterator& aOther)
const {
return container_position() > aOther.container_position(); }
181 bool operator>=(
const iterator& aOther)
const {
return container_position() >= aOther.container_position(); }
184 size_type container_position()
const {
return iContainerPosition; }
204 iContainer{}, iNode{}, iContainerPosition{ 0 }
208 iContainer{ aOther.iContainer }, iNode{ aOther.iNode }, iContainerPosition{ aOther.iContainerPosition }
212 iContainer{ aOther.iContainer }, iNode{ aOther.iNode }, iContainerPosition{ aOther.iContainerPosition }
217 iContainer = aOther.iContainer;
218 iNode = aOther.iNode;
219 iContainerPosition = aOther.iContainerPosition;
224 iContainer = aOther.iContainer;
225 iNode = aOther.iNode;
226 iContainerPosition = aOther.iContainerPosition;
231 iContainer{ &aContainer }, iNode{ nullptr }, iContainerPosition{ aContainerPosition }
233 iNode = iContainer->find_node(aContainerPosition);
235 *
this = iContainer->
end();
238 iContainer{ &aContainer }, iNode{ aNode }, iContainerPosition{ iContainer->
index(*this) }
242 iContainer{ &aContainer }, iNode{ aNode }, iContainerPosition{ aContainerPosition }
249 iNode =
static_cast<node*
>(iNode->next());
250 ++iContainerPosition;
255 iNode =
static_cast<node*
>(iNode !=
nullptr ? iNode->previous() : iContainer->back_node());
256 --iContainerPosition;
265 *
this =
const_iterator{*iContainer, container_position() + aDifference};
272 *
this =
const_iterator{*iContainer, container_position() - aDifference};
289 size_type container_position()
const {
return iContainerPosition; }
301 iAllocator(aAllocator), iSize(0)
305 iAllocator(aAllocator), iSize(0)
309 template <
typename InputIterator>
310 indexitor(InputIterator aFirst, InputIterator aLast,
const Alloc& aAllocator = Alloc()) :
311 iAllocator(aAllocator), iSize(0)
316 iAllocator(aAllocator), iSize(0)
327 newContents.
swap(*
this);
390 if (aPosition.iNode !=
nullptr)
392 if (aPosition.iNode->parent() !=
nullptr)
393 return do_index(aPosition.iNode);
395 return aPosition.iNode->left_size();
402 if (aPosition.iNode !=
nullptr)
404 if (aPosition.iNode->parent() !=
nullptr)
405 return do_index(aPosition.iNode);
407 return aPosition.iNode->left_size();
414 return insert(aPosition, 1, aValue, aSkip);
418 return *(
begin() + aIndex);
422 return *(
begin() + aIndex);
424 template <
class InputIterator>
425 typename std::enable_if<!std::is_integral<InputIterator>::value,
iterator>::type
428 return do_insert(aPosition, aFirst, aLast);
430 template <
class InputIterator,
class SkipIterator>
431 typename std::enable_if<!std::is_integral<InputIterator>::value,
iterator>::type
432 insert(
const_iterator aPosition, InputIterator aFirst, InputIterator aLast, SkipIterator aSkipFirst, SkipIterator aSkipSecond)
434 return do_insert(aPosition, aFirst, aLast, aSkipFirst, aSkipSecond);
439 return iterator{*
this, aPosition.iNode};
440 auto pos = aPosition.container_position();
443 aPosition =
insert(aPosition, &aValue, &aValue+1, &aSkip, &aSkip+1);
447 return iterator{*
this, pos};
463 if (
size() < aNewSize)
470 auto pos = aPosition.container_position();
471 erase(aPosition, aPosition + 1);
477 return iterator{*
this, aFirst.container_position()};
478 auto pos = aFirst.container_position();
479 for (node* n = aFirst.iNode; n != aLast.iNode;)
481 node* next =
static_cast<node*
>(n->next());
499 std::swap(iAllocator, aOther.iAllocator);
509 template <
typename Pred = std::less<foreign_index_type>>
516 !aPred(aForeignIndex - nodeForeignIndex,
static_cast<node*
>(n)->skip().first) &&
517 aPred(aForeignIndex - nodeForeignIndex,
static_cast<node*
>(n)->
foreign_index() -
static_cast<node*
>(n)->skip().second))
518 return std::make_pair(const_iterator{*
this,
static_cast<node*
>(n)}, nodeForeignIndex +
static_cast<node*
>(n)->skip().first);
522 template <
typename Pred = std::less<foreign_index_type>>
529 !aPred(aForeignIndex - nodeForeignIndex,
static_cast<node*
>(n)->skip().first) &&
530 aPred(aForeignIndex - nodeForeignIndex,
static_cast<node*
>(n)->
foreign_index() -
static_cast<node*
>(n)->skip().second))
531 return std::make_pair(iterator{*
this,
static_cast<node*
>(n)}, nodeForeignIndex +
static_cast<node*
>(n)->skip().first);
537 if (aPosition.iNode !=
nullptr)
538 return do_foreign_index(aPosition.iNode) + aPosition.iNode->skip().first;
544 if (aPosition.iNode !=
nullptr)
545 return aPosition.iNode->skip().first;
551 if (aPosition.iNode !=
nullptr)
552 return aPosition.iNode->skip().second;
558 template <
class InputIterator>
561 node* before = aPosition.iNode;
562 size_type pos = aPosition.container_position();
564 while (aFirst != aLast)
569 return iterator{*
this, pos};
571 template <
class InputIterator,
class SkipIterator>
572 iterator do_insert(const_iterator aPosition, InputIterator aFirst, InputIterator aLast, SkipIterator aSkipFirst, SkipIterator aSkipLast)
574 node* before = aPosition.iNode;
575 size_type pos = aPosition.container_position();
577 while (aFirst != aLast && aSkipFirst != aSkipLast)
582 return iterator{ *
this, pos };
584 size_type do_index(
const node* aNode)
const
588 if (aNode == aNode->parent()->left())
589 return do_index(
static_cast<const node*
>(aNode->parent())) - aNode->size() + aNode->left_size();
591 return do_index(
static_cast<const node*
>(aNode->parent())) + aNode->parent()->centre_size() + aNode->left_size();
600 if (aNode == aNode->parent()->left())
601 return do_foreign_index(
static_cast<const node*
>(aNode->parent())) - aNode->foreign_index() + aNode->left_foreign_index();
603 return do_foreign_index(
static_cast<const node*
>(aNode->parent())) + aNode->parent()->centre_foreign_index() + aNode->left_foreign_index();
608 node* find_node(
size_type aContainerPosition)
const
614 node* newNode = std::allocator_traits<node_allocator_type>::allocate(iAllocator, 1);
617 std::allocator_traits<node_allocator_type>::construct(iAllocator, newNode, node(aValue, aSkip));
621 std::allocator_traits<node_allocator_type>::deallocate(iAllocator, newNode, 1);
631 newNode->set_next(aBefore);
634 if (aBefore->previous())
636 newNode->set_previous(aBefore->previous());
637 aBefore->previous()->set_next(newNode);
639 aBefore->set_previous(newNode);
650 newNode->set_size(1);
651 newNode->set_foreign_index(aSkip.first + aValue.second + aSkip.second);
654 void free_node(node* aNode)
659 aNode->next()->set_previous(aNode->previous());
660 if (aNode->previous())
661 aNode->previous()->set_next(aNode->next());
668 std::allocator_traits<node_allocator_type>::destroy(iAllocator, aNode);
669 std::allocator_traits<node_allocator_type>::deallocate(iAllocator, aNode, 1);
673 node_allocator_type iAllocator;
void set_next(node *aNext)
foreign_index_type foreign_index() const
size_type left_size() const
foreign_index_type left_foreign_index() const
node * find_node(size_type aPosition) const
void delete_node(node *aNode)
void insert_node(node *aNode, size_type aPosition)
node * find_node_by_foreign_index(foreign_index_type aForeignIndex, size_type &aNodeIndex, foreign_index_type &aNodeForeignIndex, Pred aPred=Pred{}) const
node * front_node() const
void swap(index_array_tree &aOther)
void set_back_node(node *aBack)
void set_front_node(node *aFront)
const_iterator operator--(int)
const_reference operator[](difference_type aDifference) const
const_iterator & operator=(const typename indexitor::iterator &aOther)
const_pointer operator->() const
friend difference_type operator-(const const_iterator &aLhs, const const_iterator &aRhs)
indexitor::const_reference reference
bool operator<(const const_iterator &aOther) const
bool operator>(const const_iterator &aOther) const
bool operator<=(const const_iterator &aOther) const
const_iterator & operator+=(difference_type aDifference)
bool operator>=(const const_iterator &aOther) const
const_iterator operator-(difference_type aDifference) const
const_iterator & operator-=(difference_type aDifference)
const_iterator(const const_iterator &aOther)
const_iterator(const typename indexitor::iterator &aOther)
const_iterator operator++(int)
std::random_access_iterator_tag iterator_category
const_iterator & operator--()
const_iterator & operator=(const const_iterator &aOther)
const_iterator & operator++()
indexitor::difference_type difference_type
bool operator==(const const_iterator &aOther) const
indexitor::const_pointer pointer
bool operator!=(const const_iterator &aOther) const
const_reference operator*() const
const_iterator operator+(difference_type aDifference) const
indexitor::value_type value_type
difference_type operator-(const iterator &aOther) const
iterator & operator-=(difference_type aDifference)
bool operator>(const iterator &aOther) const
iterator(const iterator &aOther)
bool operator<(const iterator &aOther) const
iterator & operator+=(difference_type aDifference)
iterator operator-(difference_type aDifference) const
iterator operator+(difference_type aDifference) const
bool operator<=(const iterator &aOther) const
reference operator[](difference_type aDifference) const
pointer operator->() const
std::random_access_iterator_tag iterator_category
indexitor::difference_type difference_type
bool operator==(const iterator &aOther) const
bool operator>=(const iterator &aOther) const
iterator & operator=(const iterator &aOther)
indexitor::reference reference
reference operator*() const
bool operator!=(const iterator &aOther) const
indexitor::value_type value_type
indexitor::pointer pointer
std::allocator_traits< allocator_type >::difference_type difference_type
iterator insert(const_iterator aPosition, const value_type &aValue, const skip_type &aSkip=skip_type{})
iterator erase(const_iterator aPosition)
iterator insert(const_iterator aPosition, size_type aCount, const value_type &aValue, const skip_type &aSkip=skip_type{})
std::allocator_traits< allocator_type >::size_type size_type
foreign_index_type skip_after(const_iterator aPosition) const
size_type index(const_iterator aPosition) const
std::pair< const foreign_index_type, const foreign_index_type > skip_type
std::pair< data_type, const foreign_index_type > value_type
const_reverse_iterator rend() const
std::reverse_iterator< const_iterator > const_reverse_iterator
foreign_index_type skip_before(const_iterator aPosition) const
indexitor & operator=(const indexitor &aOther)
size_type index(iterator aPosition) const
const_reference operator[](size_type aIndex) const
foreign_index_type foreign_index(const_iterator aPosition) const
std::allocator_traits< allocator_type >::pointer pointer
indexitor(InputIterator aFirst, InputIterator aLast, const Alloc &aAllocator=Alloc())
std::pair< const_iterator, foreign_index_type > find_by_foreign_index(foreign_index_type aForeignIndex, Pred aPred=Pred{}) const
void resize(std::size_t aNewSize, const value_type &aValue=value_type{}, const skip_type &aSkip=skip_type{})
void push_front(const value_type &aValue, const skip_type &aSkip=skip_type{})
iterator erase(const_iterator aFirst, const_iterator aLast)
indexitor(const Alloc &aAllocator=Alloc())
std::enable_if<!std::is_integral< InputIterator >::value, iterator >::type insert(const_iterator aPosition, InputIterator aFirst, InputIterator aLast)
std::pair< iterator, foreign_index_type > find_by_foreign_index(foreign_index_type aForeignIndex, Pred aPred=Pred{})
std::allocator_traits< allocator_type >::const_pointer const_pointer
const_iterator end() const
ForeignIndex foreign_index_type
const_reference front() const
const_iterator begin() const
const value_type & const_reference
reference operator[](size_type aIndex)
std::enable_if<!std::is_integral< InputIterator >::value, iterator >::type insert(const_iterator aPosition, InputIterator aFirst, InputIterator aLast, SkipIterator aSkipFirst, SkipIterator aSkipSecond)
void update_foreign_index(const_iterator aPosition, const foreign_index_type &aForeignIndex, const skip_type &aSkip=skip_type{})
void swap(indexitor &aOther)
const_reference back() const
reverse_iterator rbegin()
std::reverse_iterator< iterator > reverse_iterator
indexitor(const indexitor &aOther, const Alloc &aAllocator=Alloc())
void push_back(const value_type &aValue, const skip_type &aSkip=skip_type{})
indexitor(const size_type aCount, const value_type &aValue, const Alloc &aAllocator=Alloc())
const_reverse_iterator rbegin() const
void swap(plf::hive< element_type, allocator_type > &a, plf::hive< element_type, allocator_type > &b) noexcept(std::allocator_traits< allocator_type >::propagate_on_container_swap::value||std::allocator_traits< allocator_type >::is_always_equal::value)