56 typedef typename std::allocator_traits<allocator_type>::pointer
pointer;
57 typedef typename std::allocator_traits<allocator_type>::const_pointer
const_pointer;
58 typedef typename std::allocator_traits<allocator_type>::size_type
size_type;
59 typedef typename std::allocator_traits<allocator_type>::difference_type
difference_type;
64 typedef typename Tag::template rebind<node>::type
tag_type;
68 data(node& aNode,
const tag_type& aTag) :
73 const tag_type&
tag()
const
87 const segment_type& segment()
const
91 segment_type& segment()
96 segment_type iSegment;
102 typedef typename std::allocator_traits<allocator_type>:: template rebind_alloc<node> node_allocator_type;
118 iContainer(), iNode(), iContainerPosition(), iSegmentPosition()
122 iContainer(aOther.iContainer), iNode(aOther.iNode), iContainerPosition(aOther.iContainerPosition), iSegmentPosition(aOther.iSegmentPosition)
127 iContainer = aOther.iContainer;
128 iNode = aOther.iNode;
129 iContainerPosition = aOther.iContainerPosition;
130 iSegmentPosition = aOther.iSegmentPosition;
135 iContainer(&aContainer), iNode(0), iContainerPosition(aContainerPosition), iSegmentPosition(0)
137 iNode = iContainer->find_node(aContainerPosition, iSegmentPosition);
139 *
this = iContainer->
end();
142 iContainer(&aContainer), iNode(aNode), iContainerPosition(aContainerPosition), iSegmentPosition(aSegmentPosition)
149 ++iContainerPosition;
150 if (++iSegmentPosition ==
static_cast<node*
>(iNode)->segment().
size())
152 if (iNode != iContainer->back_node())
154 iNode =
static_cast<node*
>(iNode->next());
155 iSegmentPosition = 0;
162 --iContainerPosition;
163 if (iSegmentPosition-- == 0)
165 iNode =
static_cast<node*
>(iNode->previous());
166 iSegmentPosition =
static_cast<node*
>(iNode)->segment().
size() - 1;
176 else if (iNode ==
nullptr || aDifference >=
static_cast<difference_type>(segment().
size() - iSegmentPosition))
177 *
this =
iterator(*iContainer, iContainerPosition + aDifference);
180 iContainerPosition += aDifference;
181 iSegmentPosition += aDifference;
190 *
this =
iterator(*iContainer, iContainerPosition - aDifference);
193 iContainerPosition -= aDifference;
194 iSegmentPosition -= aDifference;
204 bool operator==(
const iterator& aOther)
const {
return iContainerPosition == aOther.iContainerPosition; }
205 bool operator!=(
const iterator& aOther)
const {
return iContainerPosition != aOther.iContainerPosition; }
206 bool operator<(
const iterator& aOther)
const {
return iContainerPosition < aOther.iContainerPosition; }
207 bool operator<=(
const iterator& aOther)
const {
return iContainerPosition <= aOther.iContainerPosition; }
208 bool operator>(
const iterator& aOther)
const {
return iContainerPosition > aOther.iContainerPosition; }
209 bool operator>=(
const iterator& aOther)
const {
return iContainerPosition >= aOther.iContainerPosition; }
212 segment_type& segment()
const {
return iNode->segment(); }
233 iContainer(), iNode(), iContainerPosition(), iSegmentPosition()
237 iContainer(aOther.iContainer), iNode(aOther.iNode), iContainerPosition(aOther.iContainerPosition), iSegmentPosition(aOther.iSegmentPosition)
241 iContainer(aOther.iContainer), iNode(aOther.iNode), iContainerPosition(aOther.iContainerPosition), iSegmentPosition(aOther.iSegmentPosition)
246 iContainer = aOther.iContainer;
247 iNode = aOther.iNode;
248 iContainerPosition = aOther.iContainerPosition;
249 iSegmentPosition = aOther.iSegmentPosition;
254 iContainer = aOther.iContainer;
255 iNode = aOther.iNode;
256 iContainerPosition = aOther.iContainerPosition;
257 iSegmentPosition = aOther.iSegmentPosition;
262 iContainer(&aContainer), iNode(nullptr), iContainerPosition(aContainerPosition), iSegmentPosition(0)
264 iNode = iContainer->find_node(aContainerPosition, iSegmentPosition);
266 *
this = iContainer->
end();
269 iContainer(&aContainer), iNode(aNode), iContainerPosition(aContainerPosition), iSegmentPosition(aSegmentPosition)
276 ++iContainerPosition;
277 if (++iSegmentPosition ==
static_cast<node*
>(iNode)->segment().
size())
279 if (iNode != iContainer->back_node())
281 iNode =
static_cast<node*
>(iNode->next());
282 iSegmentPosition = 0;
289 --iContainerPosition;
290 if (iSegmentPosition-- == 0)
292 iNode =
static_cast<node*
>(iNode->previous());
293 iSegmentPosition =
static_cast<node*
>(iNode)->segment().
size() - 1;
303 else if (iNode ==
nullptr || aDifference >=
static_cast<difference_type>(segment().
size() - iSegmentPosition))
304 *
this =
const_iterator(*iContainer, iContainerPosition + aDifference);
307 iContainerPosition += aDifference;
308 iSegmentPosition += aDifference;
317 *
this =
const_iterator(*iContainer, iContainerPosition - aDifference);
320 iContainerPosition -= aDifference;
321 iSegmentPosition -= aDifference;
339 segment_type& segment()
const {
return iNode->segment(); }
352 iAllocator(aAllocator), iSize(0)
356 iAllocator(aAllocator), iSize(0)
360 template <
typename InputIterator>
361 tag_array(
const tag_type& aTag, InputIterator aFirst, InputIterator aLast,
const Alloc& aAllocator = Alloc()) :
362 iAllocator(aAllocator), iSize(0)
384 return !(*
this == aRhs);
445 return insert(aTag, aPosition, 1, aValue);
449 return *(
begin() + aIndex);
453 return *(
begin() + aIndex);
457 auto pos = aPosition.iContainerPosition;
458 while (aFirst != aLast)
460 aPosition =
insert(aFirst.segment().
tag(), aPosition, 1, *aFirst++);
465 template <
class InputIterator>
466 typename std::enable_if<!std::is_integral<InputIterator>::value,
iterator>::type
469 return do_insert(aTag, aPosition, aFirst, aLast);
473 auto pos = aPosition.iContainerPosition;
476 aPosition =
insert(aTag, aPosition, &aValue, &aValue+1);
496 erase(aPosition, aPosition + 1);
497 return iterator(*
this, aPosition.iContainerPosition);
502 return iterator(*
this, aFirst.iNode, aFirst.iContainerPosition, aFirst.iSegmentPosition);
504 if (aFirst.iNode == aLast.iNode)
506 segmentFirst.
erase(segmentFirst.
begin() + aFirst.iSegmentPosition, segmentFirst.
begin() + aLast.iSegmentPosition);
507 iSize -= (aLast.iSegmentPosition - aFirst.iSegmentPosition);
508 aFirst.iNode->set_size(aFirst.iNode->size() - (aLast.iSegmentPosition - aFirst.iSegmentPosition));
509 if (segmentFirst.
empty())
510 free_node(aFirst.iNode);
515 for (node* inbetweenNode =
static_cast<node*
>(aFirst.iNode->next()); inbetweenNode != aLast.iNode;)
517 node* next =
static_cast<node*
>(inbetweenNode->next());
518 size_type inbetweenRemoved = inbetweenNode->segment().size();
519 free_node(inbetweenNode);
520 iSize -= inbetweenRemoved;
521 inbetweenNode = next;
523 size_type firstRemoved = segmentFirst.
size() - aFirst.iSegmentPosition;
524 size_type secondRemoved = aLast.iSegmentPosition;
525 segmentFirst.
erase(segmentFirst.
begin() + aFirst.iSegmentPosition, segmentFirst.
end());
526 segmentLast.
erase(segmentLast.
begin(), segmentLast.
begin() + aLast.iSegmentPosition);
527 if (segmentFirst.
empty())
528 free_node(aFirst.iNode);
530 aFirst.iNode->set_size(aFirst.iNode->size() - firstRemoved);
531 iSize -= firstRemoved;
532 if (segmentLast.
empty())
533 free_node(aLast.iNode);
535 aLast.iNode->set_size(aLast.iNode->size() - secondRemoved);
536 iSize -= secondRemoved;
538 return iterator(*
this, aFirst.iContainerPosition);
551 std::swap(iAllocator, aOther.iAllocator);
556 return aWhere.segment().
tag();
560 template <
class InputIterator>
561 typename std::enable_if<!std::is_same<typename std::iterator_traits<InputIterator>::iterator_category, std::input_iterator_tag>::value,
iterator>::type
566 return iterator(*
this, aPosition.iNode, aPosition.iContainerPosition, aPosition.iSegmentPosition);
567 if (aPosition.iNode !=
nullptr &&
static_cast<node*
>(aPosition.iNode)->segment().tag() != aTag &&
568 aPosition.iNode->previous() !=
nullptr &&
static_cast<node*
>(aPosition.iNode->previous())->segment().tag() == aTag &&
569 static_cast<node*
>(aPosition.iNode->previous())->segment().available() >= count &&
570 aPosition.iSegmentPosition == 0)
572 aPosition.iNode =
static_cast<node*
>(aPosition.iNode->previous());
573 aPosition.iSegmentPosition = aPosition.iNode->segment().size();
575 node* before = aPosition.iNode;
576 node* after = aPosition.iNode ?
static_cast<node*
>(aPosition.iNode->next()) : nullptr;
577 node* lastNode = aPosition.iNode;
578 if (aPosition.iNode !=
nullptr && count <=
static_cast<node*
>(aPosition.iNode)->segment().available() &&
static_cast<node*
>(aPosition.iNode)->segment().tag() == aTag)
580 segment_type& segment =
static_cast<node*
>(aPosition.iNode)->segment();
581 segment.insert(segment.begin() + aPosition.iSegmentPosition, aFirst, aLast);
583 aPosition.iNode->set_size(aPosition.iNode->size() + count);
587 lastNode = allocate_space(aTag, aPosition, count);
588 if (aPosition.iNode ==
nullptr)
590 segment_type& segment = aPosition.iNode->segment();
591 typename segment_type::const_iterator tailEnd = segment.end();
592 typename segment_type::const_iterator tailStart = tailEnd - (segment.size() - aPosition.iSegmentPosition);
593 if (tailStart != tailEnd)
595 lastNode->segment().insert(lastNode->segment().begin(), tailStart, tailEnd);
596 lastNode->set_size(lastNode->size() + (tailEnd - tailStart));
597 aPosition.iNode->set_size(aPosition.iNode->size() - (tailEnd - tailStart));
598 segment.erase(tailStart, tailEnd);
600 for (node* nextNode = segment.tag() == aTag ? aPosition.iNode :
static_cast<node*
>(aPosition.iNode->next()); count > 0 && nextNode != lastNode; nextNode =
static_cast<node*
>(nextNode->next()))
602 size_type addCount = std::min(count, nextNode->segment().available());
605 InputIterator stop = aFirst;
607 nextNode->segment().insert(nextNode->segment().begin() + (nextNode == aPosition.iNode ? aPosition.iSegmentPosition : 0), aFirst, stop);
611 nextNode->set_size(nextNode->size() + addCount);
616 InputIterator stop = aFirst;
618 lastNode->segment().insert(lastNode->segment().begin() + (lastNode == aPosition.iNode ? aPosition.iSegmentPosition : 0), aFirst, stop);
619 lastNode->set_size(lastNode->size() + count);
623 size_type index = aPosition.iContainerPosition - aPosition.iSegmentPosition;
624 for (node* newNode = aPosition.iNode;; newNode =
static_cast<node*
>(newNode->next()))
626 if (newNode != before && newNode != after)
628 index += newNode->segment().size();
629 if (newNode == lastNode)
632 if (aPosition.iNode->segment().empty())
634 auto insertionPoint = iterator(*
this,
static_cast<node*
>(aPosition.iNode->next()), aPosition.iContainerPosition, 0);
635 free_node(aPosition.iNode);
636 return insertionPoint;
638 else if (aPosition.iSegmentPosition != aPosition.iNode->segment().size())
639 return iterator(*
this, aPosition.iNode, aPosition.iContainerPosition, aPosition.iSegmentPosition);
641 return iterator(*
this,
static_cast<node*
>(aPosition.iNode->next()), aPosition.iContainerPosition, 0);
643 template <
class InputIterator>
644 typename std::enable_if<std::is_same<typename std::iterator_traits<InputIterator>::iterator_category, std::input_iterator_tag>::value, iterator>::type
645 do_insert(
const tag_type& aTag, const_iterator aPosition, InputIterator aFirst, InputIterator aLast)
647 auto pos = aPosition.iContainerPosition;
648 while (aFirst != aLast)
650 aPosition =
insert(aTag, aPosition, 1, *aFirst++);
653 return iterator(*
this, pos);
659 aSegmentPosition = aContainerPosition - nodeIndex;
662 node* allocate_space(
const tag_type& aTag, const_iterator aPosition,
size_type aCount)
665 return aPosition.iNode;
666 if (aPosition.iNode && aPosition.iNode->segment().tag() == aTag)
667 aCount -= std::min(aCount, (aPosition.iNode->segment().available()));
669 return aPosition.iNode;
670 node* lastNode =
nullptr;
671 if (aCount > 0 && aPosition.iNode && aPosition.iNode->next() !=
nullptr && aCount <=
static_cast<node*
>(aPosition.iNode->next())->segment().available() &&
static_cast<node*
>(aPosition.iNode->next())->segment().tag() == aTag)
673 if (aPosition.iNode->segment().tag() == aTag || aPosition.iSegmentPosition == aPosition.iNode->segment().size())
675 lastNode =
static_cast<node*
>(aPosition.iNode->next());
676 aCount -= std::min(aCount, lastNode->segment().available());
679 node* nextNode = aPosition.iNode;
681 aCount -= std::min(aCount, (nextNode = allocate_node(aTag, nextNode))->segment().available());
682 if (aPosition.iNode ==
nullptr)
684 segment_type& segment = aPosition.iNode->segment();
685 if (aPosition.iSegmentPosition < segment.size() && (nextNode->segment().available() < segment.size() - aPosition.iSegmentPosition || segment.tag() != aTag))
686 lastNode = allocate_node(segment.tag(), nextNode);
687 return lastNode ? lastNode : nextNode;
689 node* allocate_node(
const tag_type& aTag, node* aAfter)
691 node* newNode = iAllocator.allocate(1);
692 std::allocator_traits<
decltype(iAllocator)>::construct(iAllocator, newNode, node(aTag));
693 if (aAfter ==
nullptr)
700 newNode->set_previous(aAfter);
701 if (aAfter->next() !=
nullptr)
703 newNode->set_next(aAfter->next());
704 aAfter->next()->set_previous(newNode);
706 aAfter->set_next(newNode);
712 void free_node(node* aNode)
717 aNode->next()->set_previous(aNode->previous());
718 if (aNode->previous())
719 aNode->previous()->set_next(aNode->next());
726 std::allocator_traits<
decltype(iAllocator)>::destroy(iAllocator, aNode);
727 iAllocator.deallocate(aNode, 1);
731 node_allocator_type iAllocator;