6 #include <initializer_list>
89 : parent(nullptr), child{
nullptr,
nullptr },
90 n_children{ 0, 0 }, red(
false), value() {}
92 : parent(nullptr), child{
nullptr,
nullptr },
93 n_children{ 0, 0 }, red(is_red), value() {}
95 : parent(nullptr), child{
nullptr,
nullptr },
96 n_children{ 0, 0 }, red(is_red), value(v) {}
97 Node(
bool is_red, T && v)
98 : parent(nullptr), child{
nullptr,
nullptr },
99 n_children{ 0, 0 }, red(is_red), value(std::move(v)) {}
100 template<
class... Args>
101 Node(
bool is_red, Args... args)
102 : parent(nullptr), child{
nullptr,
nullptr },
103 n_children{ 0, 0 }, red(is_red), value(args...) {}
106 inline pNode o_root()
const {
return child[1]; }
107 inline pNode & o_root() {
return child[1]; }
108 inline pNode o_front()
const {
return parent; }
109 inline pNode & o_front() {
return parent; }
110 inline pNode o_back()
const {
return child[0]; }
111 inline pNode & o_back() {
return child[0]; }
113 void recompute_n_children(
size_type side) {
117 n_children[side] = 1 + child[side]->n_children[0] +
118 child[side]->n_children[1];
120 n_children[side] = 0;
136 return (child[1] == ch ? 1 : 0);
174 Base() : origin(new Node(true)) {}
175 ~Base() {
delete origin; }
177 bool empty()
const {
return origin->o_root() ==
nullptr; }
180 return origin->o_root()
181 ? (origin->o_root()->n_children[0] +
182 origin->o_root()->n_children[1] + 1)
190 if(n == origin)
return size();
193 while(n != origin->o_root()) {
197 moved += n->n_children[1] + 1;
199 moved -= n->n_children[0] + 1;
203 moved -= n->n_children[0];
206 return static_cast<size_type>(moved);
214 while(count > n->n_children[side]) {
225 if(side == p->side_of_child(n)) {
226 count += (n->n_children[1 - side] + 1);
228 count -= (n->n_children[side] + 1);
237 pNode c = n->child[side];
243 count -= (1 + c->n_children[1 - side]);
253 pNode neighbor(pNode n,
size_type side) {
256 pNode tmp = n->child[side];
258 while(tmp->child[1 - side]) {
259 tmp = tmp->child[1 - side];
265 if(tmp->parent == origin)
return origin;
266 if(tmp->parent->side_of_child(tmp) == 1 - side)
273 template<
class STREAM>
274 static void display_tree_main(
275 STREAM & sr,
const pNode n,
size_type depth,
279 display_tree_main(sr, n->child[0], depth + 1, offset);
284 sr <<
'<' << (n->red ?
'R' :
'B') <<
">["
285 << (offset + n->n_children[0]) <<
" this=" << n
286 <<
" parent=" << n->parent
287 <<
" children=" << n->n_children[0] <<
","
288 << n->n_children[1] <<
"] " << n->value << std::endl;
291 sr, n->child[1], depth + 1,
292 offset + n->n_children[0] + 1);
295 template<
class STREAM>
296 inline void display_tree(STREAM & sr)
const {
297 sr <<
"{LTOList Size=" << size() <<
" Origin=" << origin
298 <<
" Root=" << origin->o_root()
299 <<
" Front=" << origin->o_front()
300 <<
" Back=" << origin->o_back() <<
"}" << std::endl;
301 display_tree_main(sr, origin->o_root(), 0, 0);
305 pNode newnode =
new Node(
true, v);
306 return add_main(pos, side, newnode);
309 pNode add(pNode pos,
size_type side, T && v) {
310 pNode newnode =
new Node(
true, std::move(v));
311 return add_main(pos, side, newnode);
314 template<
class... Args>
315 pNode add_emplace(pNode pos,
size_type side, Args... args) {
316 pNode newnode =
new Node(
true, args...);
317 return add_main(pos, side, newnode);
320 pNode add_main(pNode pos,
size_type side, pNode newnode) {
332 newnode->red =
false;
333 newnode->parent = origin;
334 origin->o_root() = newnode;
335 origin->o_front() = newnode;
336 origin->o_back() = newnode;
340 if(pos == origin && side == 0) {
341 pos = origin->o_back();
345 if(pos ==
nullptr)
throw std::invalid_argument(
"Invalid iterator");
346 if(pos == origin)
throw std::invalid_argument(
"Elements cannot be inserted after the end of the list");
354 if(pos == origin->o_front() && side == 0) {
355 origin->o_front() = newnode;
356 }
else if(pos == origin->o_back() && side == 1) {
357 origin->o_back() = newnode;
367 if(pos->child[side] ==
nullptr) {
371 pos_ins = neighbor(pos, side);
376 assert(pos_ins->child[side_ins] ==
nullptr);
377 pos_ins->child[side_ins] = newnode;
378 newnode->parent = pos_ins;
379 pos_ins->n_children[side_ins] = 1;
386 rotsides[0] = side_ins;
387 while(rotpos[1]->red) {
388 assert(rotpos[0]->red);
389 if(rotpos[0] == origin->o_root()) {
391 rotpos[0]->red =
false;
394 if(rotpos[1] == origin->o_root()) {
396 rotpos[1]->red =
false;
400 rotpos[2] = rotpos[1]->parent;
401 rotpos[3] = rotpos[2]->parent;
402 rotsides[1] = rotpos[2]->side_of_child(rotpos[1]);
403 rotsides[2] = rotpos[3]->side_of_child(rotpos[2]);
405 if(rotsides[0] == rotsides[1]) {
423 rotpos[2]->child[rotsides[0]] =
424 rotpos[1]->child[1 - rotsides[0]];
425 if(rotpos[2]->child[rotsides[0]])
426 rotpos[2]->child[rotsides[0]]->parent =
429 rotpos[1]->child[1 - rotsides[0]] = rotpos[2];
430 if(rotpos[2]) rotpos[2]->parent = rotpos[1];
432 rotpos[3]->child[rotsides[2]] = rotpos[1];
433 if(rotpos[1]) rotpos[1]->parent = rotpos[3];
435 rotpos[0]->red =
false;
437 rotpos[2]->recompute_n_children(rotsides[0]);
438 rotpos[1]->recompute_n_children(0);
439 rotpos[1]->recompute_n_children(1);
458 rotpos[1]->child[rotsides[0]] =
459 rotpos[0]->child[rotsides[1]];
460 if(rotpos[0]->child[rotsides[1]])
461 rotpos[0]->child[rotsides[1]]->parent =
464 rotpos[2]->child[rotsides[1]] =
465 rotpos[0]->child[rotsides[0]];
466 if(rotpos[0]->child[rotsides[0]])
467 rotpos[0]->child[rotsides[0]]->parent =
470 rotpos[0]->child[rotsides[1]] = rotpos[1];
471 if(rotpos[1]) rotpos[1]->parent = rotpos[0];
473 rotpos[0]->child[rotsides[0]] = rotpos[2];
474 if(rotpos[2]) rotpos[2]->parent = rotpos[0];
476 rotpos[3]->child[rotsides[2]] = rotpos[0];
477 if(rotpos[0]) rotpos[0]->parent = rotpos[3];
479 rotpos[1]->red =
false;
481 rotpos[2]->recompute_n_children(1 - rotsides[0]);
482 rotpos[1]->recompute_n_children(rotsides[0]);
483 rotpos[0]->recompute_n_children(0);
484 rotpos[0]->recompute_n_children(1);
488 rotpos[0] = rotpos[3]->child[rotsides[2]];
489 rotpos[1] = rotpos[3];
490 rotsides[0] = rotsides[2];
496 pNode recpos = rotpos[0];
497 if(recpos != origin) {
499 pNode par = recpos->parent;
500 if(par == origin)
break;
502 par->side_of_child(recpos);
504 par->recompute_n_children(recpos_side);
512 pNode remove(pNode pos) {
515 if(pos ==
nullptr)
throw std::invalid_argument(
"Invalid iterator");
516 if(pos == origin)
throw std::invalid_argument(
"The end of the list cannot be deleted");
519 if(pos == origin->o_front() && pos == origin->o_back()) {
520 origin->o_root() =
nullptr;
521 origin->o_front() =
nullptr;
522 origin->o_back() =
nullptr;
527 pNode returned_pos =
nullptr;
528 pNode neighbor_pos =
nullptr;
539 if(pos == origin->o_back()) {
543 returned_pos = origin;
545 returned_pos = neighbor(pos, 1);
546 if(pos->child[0] && pos->child[1]) {
547 neighbor_pos = returned_pos;
556 pNode pos_parent = pos->parent;
557 size_t pos_parent_side =
558 pos_parent->side_of_child(pos);
559 pNode pos_lc = pos->child[0];
560 pNode pos_rc = pos->child[1];
562 pNode neighbor_pos_parent = neighbor_pos->parent;
563 size_t neighbor_pos_parent_side =
564 neighbor_pos_parent->side_of_child(neighbor_pos);
565 pNode neighbor_pos_lc = neighbor_pos->child[0];
566 pNode neighbor_pos_rc = neighbor_pos->child[1];
568 if(neighbor_pos_parent == pos) {
570 pos_parent->child[pos_parent_side] = neighbor_pos;
571 if(neighbor_pos_parent_side == 1) {
572 if(pos_lc) pos_lc->parent = neighbor_pos;
574 if(pos_rc) pos_rc->parent = neighbor_pos;
576 if(neighbor_pos_lc) neighbor_pos_lc->parent = pos;
577 if(neighbor_pos_rc) neighbor_pos_rc->parent = pos;
579 pos->parent = neighbor_pos;
580 pos->child[0] = neighbor_pos_lc;
581 pos->child[1] = neighbor_pos_rc;
582 neighbor_pos->parent = pos_parent;
583 if(neighbor_pos_parent_side == 1) {
584 neighbor_pos->child[0] = pos_lc;
585 neighbor_pos->child[1] = pos;
587 neighbor_pos->child[0] = pos;
588 neighbor_pos->child[1] = pos_rc;
591 pos_parent->child[pos_parent_side] = neighbor_pos;
592 if(pos_lc) pos_lc->parent = neighbor_pos;
593 if(pos_rc) pos_rc->parent = neighbor_pos;
595 ->child[neighbor_pos_parent_side] = pos;
596 if(neighbor_pos_lc) neighbor_pos_lc->parent = pos;
597 if(neighbor_pos_rc) neighbor_pos_rc->parent = pos;
599 pos->parent = neighbor_pos_parent;
600 pos->child[0] = neighbor_pos_lc;
601 pos->child[1] = neighbor_pos_rc;
602 neighbor_pos->parent = pos_parent;
603 neighbor_pos->child[0] = pos_lc;
604 neighbor_pos->child[1] = pos_rc;
607 pos->n_children[0], neighbor_pos->n_children[0]);
609 pos->n_children[1], neighbor_pos->n_children[1]);
610 std::swap(pos->red, neighbor_pos->red);
612 if(pos == origin->o_front()) {
614 origin->o_front() = neighbor_pos;
618 if(pos == origin->o_front()) {
620 origin->o_front() = neighbor(pos, 1);
621 }
else if(pos == origin->o_back()) {
623 origin->o_back() = neighbor(pos, 0);
627 pos->child[0] ==
nullptr || pos->child[1] ==
nullptr);
629 pNode pos_adjust = pos->parent;
630 bool adjust_needed = !(pos->red);
631 size_type side_adjust = pos_adjust->side_of_child(pos);
632 pos_adjust->child[side_adjust] =
633 (pos->child[1] ? pos->child[1] : pos->child[0]);
634 if(pos_adjust->child[side_adjust]) {
635 pos_adjust->child[side_adjust]->parent = pos_adjust;
639 pos_adjust->recompute_n_children(side_adjust);
642 while(adjust_needed && pos_adjust != origin) {
643 adjust_needed =
false;
647 pNode pos_reduced = pos_adjust->child[side_adjust];
649 pos_adjust->child[1 - side_adjust];
653 if(pos_sibling->red) {
678 pNode pos_adjust_parent = pos_adjust->parent;
680 pos_adjust_parent->side_of_child(pos_adjust);
682 pos_adjust->child[1 - side_adjust] =
683 pos_sibling->child[side_adjust];
684 if(pos_sibling->child[side_adjust])
685 pos_sibling->child[side_adjust]->parent =
687 pos_sibling->child[side_adjust] = pos_adjust;
688 pos_adjust->parent = pos_sibling;
689 pos_sibling->parent = pos_adjust_parent;
690 pos_adjust_parent->child[side_adjust_parent] =
693 pos_adjust->recompute_n_children(0);
694 pos_adjust->recompute_n_children(1);
695 pos_sibling->recompute_n_children(side_adjust);
696 pos_adjust_parent->recompute_n_children(
699 pos_adjust->red =
true;
700 pos_sibling->red =
false;
702 pos_sibling = pos_adjust->child[1 - side_adjust];
705 assert(!(pos_sibling->red));
719 pos_sibling->child[side_adjust] &&
720 pos_sibling->child[side_adjust]->red) {
738 pNode pos_adjust_parent = pos_adjust->parent;
740 pos_adjust_parent->side_of_child(pos_adjust);
743 pos_sibling->child[side_adjust];
744 pos_adjust->child[side_adjust] = pos_reduced;
745 if(pos_reduced) pos_reduced->parent = pos_adjust;
746 pos_adjust->child[1 - side_adjust] =
747 pos_nephew->child[side_adjust];
748 if(pos_nephew->child[side_adjust])
749 pos_nephew->child[side_adjust]->parent =
751 pos_sibling->child[side_adjust] =
752 pos_nephew->child[1 - side_adjust];
753 if(pos_nephew->child[1 - side_adjust])
754 pos_nephew->child[1 - side_adjust]->parent =
756 pos_nephew->child[side_adjust] = pos_adjust;
757 pos_adjust->parent = pos_nephew;
758 pos_nephew->child[1 - side_adjust] = pos_sibling;
759 pos_sibling->parent = pos_nephew;
761 pos_nephew->parent = pos_adjust_parent;
762 pos_adjust_parent->child[side_adjust_parent] =
765 pos_nephew->red = pos_adjust->red;
766 pos_adjust->red =
false;
768 pos_adjust->recompute_n_children(0);
769 pos_adjust->recompute_n_children(1);
770 pos_sibling->recompute_n_children(side_adjust);
771 pos_nephew->recompute_n_children(0);
772 pos_nephew->recompute_n_children(1);
774 pos_adjust = pos_nephew;
776 side_adjust = side_adjust_parent;
777 pos_adjust = pos_adjust_parent;
779 pos_sibling->child[1 - side_adjust] &&
780 pos_sibling->child[1 - side_adjust]->red) {
798 pNode pos_adjust_parent = pos_adjust->parent;
800 pos_adjust_parent->side_of_child(pos_adjust);
803 pos_sibling->child[1 - side_adjust];
804 pos_adjust->child[1 - side_adjust] =
805 pos_sibling->child[side_adjust];
806 if(pos_sibling->child[side_adjust])
807 pos_sibling->child[side_adjust]->parent =
809 pos_sibling->child[side_adjust] = pos_adjust;
810 pos_adjust->parent = pos_sibling;
811 pos_sibling->child[1 - side_adjust] = pos_nephew;
812 if(pos_nephew) pos_nephew->parent = pos_sibling;
814 pos_sibling->red = pos_adjust->red;
815 pos_adjust->red =
false;
816 pos_nephew->red =
false;
818 pos_sibling->parent = pos_adjust_parent;
819 pos_adjust_parent->child[side_adjust_parent] =
822 pos_adjust->recompute_n_children(0);
823 pos_adjust->recompute_n_children(1);
824 pos_sibling->recompute_n_children(0);
825 pos_sibling->recompute_n_children(1);
827 side_adjust = side_adjust_parent;
828 pos_adjust = pos_adjust_parent;
850 pos_sibling->red =
true;
851 if(!(pos_adjust->red)) {
852 adjust_needed =
true;
854 pos_adjust->red =
false;
856 pos_adjust->recompute_n_children(side_adjust);
858 pos_adjust->parent->side_of_child(pos_adjust);
859 pos_adjust = pos_adjust->parent;
863 while(pos_adjust != origin) {
864 pos_adjust->recompute_n_children(side_adjust);
866 pos_adjust->parent->side_of_child(pos_adjust);
867 pos_adjust = pos_adjust->parent;
870 origin->o_root()->red =
false;
876 if(this->empty())
return;
879 using deletion_status_t = std::pair<pNode, bool>;
880 std::stack<deletion_status_t> st;
881 st.push(std::make_pair(origin->o_root(),
false));
883 while(!(st.empty())) {
884 deletion_status_t ds = st.top();
887 if(!ds.first)
continue;
892 st.push(std::make_pair(ds.first,
true));
894 std::make_pair(ds.first->child[1],
false));
896 std::make_pair(ds.first->child[0],
false));
900 origin->o_root() =
nullptr;
901 origin->o_front() =
nullptr;
902 origin->o_back() =
nullptr;
905 void copy_from(
const Base & other) {
906 using copy_status_t = std::pair<pNode, pNode>;
909 if(other.empty())
return;
912 pNode newOrignode =
new Node();
913 *newOrignode = *(other.origin->o_root());
914 newOrignode->parent = origin;
915 origin->o_root() = newOrignode;
916 if(other.origin->o_root() == other.origin->o_front()) {
917 origin->o_front() = newOrignode;
919 if(other.origin->o_root() == other.origin->o_back()) {
920 origin->o_back() = newOrignode;
924 std::stack<copy_status_t> st;
926 std::make_pair(newOrignode, other.origin->o_root()));
928 while(!(st.empty())) {
929 copy_status_t cs = st.top();
932 for(
size_t p = 0; p <= 1; ++p) {
933 if(cs.second->child[p]) {
934 pNode newnode =
new Node();
935 *newnode = *(cs.second->child[p]);
936 newnode->parent = cs.first;
937 cs.first->child[p] = newnode;
939 cs.second->child[p] ==
940 other.origin->o_front()) {
941 origin->o_front() = newnode;
944 cs.second->child[p] ==
945 other.origin->o_back()) {
946 origin->o_back() = newnode;
949 st.push(std::make_pair(
950 newnode, cs.second->child[p]));
952 cs.first->child[p] =
nullptr;
964 class const_iterator;
975 iterator(Base & base, pNode n) : pbase_(&base), n_(n) {}
978 iterator() : pbase_(
nullptr), n_(
nullptr) {}
980 : pbase_(other.pbase_), n_(other.n_) {}
982 pbase_ = other.pbase_;
987 pointer operator->()
const {
return &(n_->value); }
988 reference operator*()
const {
return n_->value; }
990 n_ = pbase_->neighbor(n_, 1);
994 n_ = pbase_->neighbor(n_, 0);
999 n_ = pbase_->neighbor(n_, 1);
1004 n_ = pbase_->neighbor(n_, 0);
1008 n_ = pbase_->advance(n_, dir);
1012 n_ = pbase_->advance(n_, -dir);
1016 return pbase_->advance(n_, dir)->value;
1020 friend class ::LTOList<value_type>;
1024 friend std::ostream & operator<<(
1026 const typename ::LTOList<TT>::iterator & it);
1029 template<
class IT1,
class IT2>
1030 void from_same_list(
const IT1 & it1,
const IT2 & it2){
1031 if(it1.pbase_ != it2.pbase_){
1032 throw std::invalid_argument(
"The difference of iterators cannot be taken for different lists");
1055 from_same_list(it.pbase_, other.pbase_);
1056 return static_cast<difference_type>(
1057 it.pbase_->position(it.n_)) -
1058 static_cast<difference_type>(
1059 other.pbase_->position(other.n_));
1062 from_same_list(it.pbase_, other.pbase_);
1063 return it.pbase_->position(it.n_) <
1064 other.pbase_->position(other.n_);
1067 from_same_list(it.pbase_, other.pbase_);
1068 return it.pbase_->position(it.n_) <=
1069 other.pbase_->position(other.n_);
1072 from_same_list(it.pbase_, other.pbase_);
1073 return it.pbase_->position(it.n_) >
1074 other.pbase_->position(other.n_);
1077 from_same_list(it.pbase_, other.pbase_);
1078 return it.pbase_->position(it.n_) >=
1079 other.pbase_->position(other.n_);
1082 return it.n_ == other.n_;
1085 return it.n_ != other.n_;
1087 friend std::ostream &
1088 operator<<(std::ostream & out,
iterator it) {
1089 out <<
"<LTOList::iterator " << it.n_ <<
">";
1101 const Base * pbase_;
1104 : pbase_(&base), n_(n) {}
1109 : pbase_(other.pbase_), n_(other.n_) {}
1111 : pbase_(other.pbase_), n_(other.n_) {}
1113 pbase_ = other.pbase_;
1118 pbase_ = other.pbase_;
1126 n_ = pbase_->neighbor(n_, 1);
1130 n_ = pbase_->neighbor(n_, 0);
1135 n_ = pbase_->neighbor(n_, 1);
1140 n_ = pbase_->neighbor(n_, 0);
1144 n_ = pbase_->advance(n_, dir);
1148 n_ = pbase_->advance(n_, -dir);
1152 return pbase_->advance(n_, dir)->value;
1156 friend class ::LTOList<value_type>;
1159 friend std::ostream & operator<<(
1161 const typename ::LTOList<TT>::const_iterator & it);
1186 from_same_list(it.pbase_, other.pbase_);
1187 return static_cast<difference_type>(
1188 it.pbase_->position(it.n_)) -
1189 static_cast<difference_type>(
1190 other.pbase_->position(other.n_));
1194 from_same_list(it.pbase_, other.pbase_);
1195 return it.pbase_->position(it.n_) <
1196 other.pbase_->position(other.n_);
1200 from_same_list(it.pbase_, other.pbase_);
1201 return it.pbase_->position(it.n_) <=
1202 other.pbase_->position(other.n_);
1206 from_same_list(it.pbase_, other.pbase_);
1207 return it.pbase_->position(it.n_) >
1208 other.pbase_->position(other.n_);
1212 from_same_list(it.pbase_, other.pbase_);
1213 return it.pbase_->position(it.n_) >=
1214 other.pbase_->position(other.n_);
1218 return it.n_ == other.n_;
1222 return it.n_ != other.n_;
1224 friend std::ostream &
1226 out <<
"<LTOList::const_iterator " << it.n_ <<
">";
1232 from_same_list(it.pbase_, other.pbase_);
1233 return static_cast<difference_type>(
1234 it.pbase_->position(it.n_)) -
1235 static_cast<difference_type>(
1236 other.pbase_->position(other.n_));
1240 from_same_list(it.pbase_, other.pbase_);
1241 return static_cast<difference_type>(
1242 it.pbase_->position(it.n_)) -
1243 static_cast<difference_type>(
1244 other.pbase_->position(other.n_));
1247 from_same_list(it.pbase_, other.pbase_);
1248 return it.pbase_->position(it.n_) <
1249 other.pbase_->position(other.n_);
1252 from_same_list(it.pbase_, other.pbase_);
1253 return it.pbase_->position(it.n_) <
1254 other.pbase_->position(other.n_);
1257 from_same_list(it.pbase_, other.pbase_);
1258 return it.pbase_->position(it.n_) <=
1259 other.pbase_->position(other.n_);
1262 from_same_list(it.pbase_, other.pbase_);
1263 return it.pbase_->position(it.n_) <=
1264 other.pbase_->position(other.n_);
1267 from_same_list(it.pbase_, other.pbase_);
1268 return it.pbase_->position(it.n_) >
1269 other.pbase_->position(other.n_);
1272 from_same_list(it.pbase_, other.pbase_);
1273 return it.pbase_->position(it.n_) >
1274 other.pbase_->position(other.n_);
1277 from_same_list(it.pbase_, other.pbase_);
1278 return it.pbase_->position(it.n_) >=
1279 other.pbase_->position(other.n_);
1282 from_same_list(it.pbase_, other.pbase_);
1283 return it.pbase_->position(it.n_) >=
1284 other.pbase_->position(other.n_);
1287 return it.n_ == other.n_;
1290 return it.n_ == other.n_;
1293 return it.n_ != other.n_;
1296 return it.n_ != other.n_;
1310 base_.copy_from(other.base_);
1312 LTOList(std::initializer_list<T> init) : base_() {
1313 this->
insert(this->begin(), init.begin(), init.end());
1317 return iterator(base_, base_.origin->o_front());
1321 base_, base_.origin->o_front() ? base_.origin :
nullptr);
1324 return iterator(base_, base_.origin->o_front());
1328 base_, base_.origin->o_front() ? base_.origin :
nullptr);
1330 const_iterator begin()
const {
1331 return const_iterator(base_, base_.origin->o_front());
1333 const_iterator end()
const {
1334 return const_iterator(
1335 base_, base_.origin->o_front() ? base_.origin :
nullptr);
1337 const_iterator rbegin()
const {
1338 return const_iterator(base_, base_.origin->o_front());
1340 const_iterator rend()
const {
1341 return const_iterator(
1342 base_, base_.origin->o_front() ? base_.origin :
nullptr);
1344 const_iterator cbegin()
const {
1345 return const_iterator(base_, base_.origin->o_front());
1347 const_iterator cend()
const {
1348 return const_iterator(
1349 base_, base_.origin->o_front() ? base_.origin :
nullptr);
1351 const_iterator crbegin()
const {
1352 return const_iterator(base_, base_.origin->o_front());
1354 const_iterator crend()
const {
1355 return const_iterator(
1356 base_, base_.origin->o_front() ? base_.origin :
nullptr);
1359 size_type size()
const {
return base_.size(); }
1360 bool empty()
const {
return base_.empty(); }
1364 throw std::out_of_range(
1365 "reference LTOList::operator[]: Index out of range");
1368 static_cast<difference_type>(i) -
1369 static_cast<difference_type>(
1370 base_.origin->o_root()->n_children[0]);
1371 return base_.advance(base_.origin->o_root(), adpos)->value;
1376 throw std::out_of_range(
1377 "const_reference LTOList::at: Index out of range");
1380 static_cast<difference_type>(i) -
1381 static_cast<difference_type>(
1382 base_.origin->o_root()->n_children[0]);
1383 return base_.advance(base_.origin->o_root(), adpos)->value;
1391 reference front() {
return base_.origin->o_front()->value; }
1393 return base_.origin->o_front()->value;
1395 reference back() {
return base_.origin->o_back()->value; }
1397 return base_.origin->o_back()->value;
1427 return iterator(base_, base_.add(position.n_, side, val));
1458 base_, base_.add(position.n_, side, std::move(val)));
1483 template<
class... Args>
1487 base_, base_.add_emplace(position.n_, side, args...));
1499 return insert(0, position, val);
1511 return insert(0, position, std::move(val));
1522 template<
class... Args>
1524 return emplace(0, position, args...);
1591 template<
class... Args>
1595 emplace(side, position, args...);
1618 template<
class... Args>
1621 emplace(0, position, args...);
1657 template<
class InputIterator>
1660 InputIterator elem_end) {
1662 for(InputIterator it = elem_begin; it != elem_end; ++it) {
1663 tmp =
insert(side, tmp, *it);
1678 template<
class InputIterator>
1680 iterator position, InputIterator elem_begin,
1681 InputIterator elem_end) {
1682 insert(0, position, elem_begin, elem_end);
1685 iterator erase(iterator position) {
1686 return iterator(base_, base_.remove(position.n_));
1688 iterator erase(const_iterator position) {
1689 return iterator(base_, base_.remove(position.n_));
1692 iterator erase(iterator elem_begin, iterator elem_end) {
1694 while(elem_begin != elem_end) {
1695 elem_begin = erase(elem_begin);
1700 erase(const_iterator elem_begin, const_iterator elem_end) {
1701 while(elem_begin != elem_end) elem_begin = erase(elem_begin);
1705 template<
class InputIterator>
1706 void assign(InputIterator elem_begin, InputIterator elem_end) {
1708 insert(begin(), elem_begin, elem_end);
1711 void assign(
size_type n,
const T & val) {
1716 void push_front(
const T & val) {
insert(begin(), val); }
1717 void push_front(T && val) {
insert(begin(), std::move(val)); }
1718 template<
class... Args>
1719 void emplace_front(Args... args) {
1723 void push_back(
const T & val) {
insert(end(), val); }
1724 void push_back(T && val) {
insert(end(), std::move(val)); }
1725 template<
class... Args>
1726 void emplace_back(Args... args) {
1730 void pop_front() { erase(begin()); }
1731 void pop_back() { erase(--(end())); }
1733 void clear() { base_.clear(); }
1736 std::swap(base_.origin, other.base_.origin);
1741 std::ostream & operator<<(
1743 os <<
"LTOList::iterator<" << it.n_ <<
">";
1748 std::ostream & operator<<(
1750 os <<
"LTOList::const_iterator<" << it.n_ <<
">";