Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_dynDlist.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
44# ifndef TPL_DYNDLIST_H
45# define TPL_DYNDLIST_H
46
47# include <ahFunctional.H>
48# include <ahDry.H>
49# include <ah-dry.H>
50# include <ah-args-ctor.H>
51# include <ahIterator.H>
52# include <ah-iterator.H>
53# include <tpl_dnode.H>
54# include <stdexcept>
55# include <ah-errors.H>
56
57namespace Aleph {
58
115 template <typename T = int>
117 : public Dnode<T>,
118 public GenericTraverse<DynDlist<T>>,
119 public SpecialCtors<DynDlist<T>, T>,
120 public LocateFunctions<DynDlist<T>, T>,
121 public FunctionalMethods<DynDlist<T>, T>,
122 public GenericItems<DynDlist<T>, T>,
123 public StlAlephIterator<DynDlist<T>>
124{
125 size_t num_elem = 0;
126
127public:
128
131
133 using Item_Type = T;
134
136 using Key_Type = T;
137
139 const size_t & size() const noexcept { return num_elem; }
140
141 DynDlist() = default;
142
143 // using CtorBase = SpecialCtors<DynDlist<T>, T>;
144 // using CtorBase::CtorBase;
145
146 // /** Construct a new list with copies of elements of list `l`
147
148 // \param[in] l list to be copied
149 // \throw bad_alloc if there is no enough memory
150 // */
151 // DynDlist(const DynList<T> & l) : Dnode<T>(), CtorBase(l) {}
152
154
156 {
157 while (not this->is_empty())
158 delete this->Dnode<T>::remove_next();
159
160 num_elem = 0;
161 }
162
164 {
165 empty();
166 }
167
168private:
169
170 T & __insert(Dnode<T> * p) noexcept
171 {
173 ++num_elem;
174 return p->get_data();
175 }
176
177 T & __append(Dnode<T> * p) noexcept
178 {
180 ++num_elem;
181 return p->get_data();
182 }
183
184public:
185
192 T & insert(const T & item)
193 {
194 return __insert(new Dnode<T> (item));
195 }
196
203 T & insert(T && item)
204 {
205 return __insert(new Dnode<T> (std::forward<T>(item)));
206 }
207
214 T & append(const T & item)
215 {
216 return __append(new Dnode<T> (item));
217 }
218
225 T & append(T && item)
226 {
227 return __append(new Dnode<T> (std::forward<T>(item)));
228 }
229
230 private:
231
232 void __insert(DynDlist<T> & list) noexcept
233 {
234 Dlink::insert_list(&list);
235 num_elem += list.num_elem;
236 list.num_elem = 0;
237
238 assert(list.is_empty());
239 }
240
241 void __append(DynDlist<T> & list) noexcept
242 {
243 Dlink::append_list(&list);
244 num_elem += list.num_elem;
245 list.num_elem = 0;
246
247 assert(list.is_empty());
248 }
249
250 public:
251
256 void insert(const DynDlist & list)
257 {
258 auto l = list; // perform a copy of list
259 __insert(l);
260 }
261
263 void insert(DynDlist && list) noexcept
264 {
265 __insert(list);
266 }
267
272 void append(const DynDlist & list)
273 {
274 auto l = list; // perform a copy of list
275 __append(l);
276 }
277
279 void append(DynDlist && list) noexcept
280 {
281 __append(list);
282 }
283
286 {
287 return this->get_next()->get_data();
288 }
289
292 {
293 return this->get_prev()->get_data();
294 }
295
297 T & get_first() const
298 {
300 << "DynDlist is empty";
301 return get_first_ne();
302 }
303
305 T & get_last() const
306 {
308 << "DynDlist is empty";
309 return get_last_ne();
310 }
311
317 {
318 Dnode<T> * ptr = this->remove_next();
319 T retVal = ptr->get_data();
320 delete ptr;
321 --num_elem;
322
323 return retVal;
324 }
325
331 {
332 Dnode<T> * ptr = this->remove_prev();
333 T retVal = ptr->get_data();
334 delete ptr;
335 --num_elem;
336
337 return retVal;
338 }
339
346 {
348 << "DynDlist is empty";
349 return remove_first_ne();
350 }
351
358 {
360 << "DynDlist is empty";
361 return remove_last_ne();
362 }
363
365 T & put(const T & item) { return append(item); }
366
368 T & put(T && item) { return append(std::forward<T>(item)); }
369
371 T get() { return remove_first(); }
372
375 T & rear() { return get_last(); }
376
379 T & front() { return get_first(); }
380
382 T & push(const T & item) { return insert(item); }
383
385 T & push(T && item) { return insert(std::forward<T>(item)); }
386
388 T pop() { return remove_first(); }
389
391 T & top() const { return get_first(); }
392
406 void remove(T & data) noexcept
407 {
409 p->del();
410 delete p;
411 --num_elem;
412 }
413
415 void erase(T & data) noexcept
416 {
417 remove(data);
418 }
419
422 void swap(DynDlist & l) noexcept
423 {
424 std::swap(num_elem, l.num_elem);
425 this->Dlink::swap(&l);
426 }
427
439 void split_list_ne(DynDlist & l, DynDlist & r) noexcept
440 {
442
443 const auto count_nodes = [] (const DynDlist & list) noexcept -> size_t
444 {
445 size_t count = 0;
446 for (auto it = list.get_it(); it.has_curr(); it.next_ne())
447 ++count;
448 return count;
449 };
450
451 l.num_elem = count_nodes(l);
452 r.num_elem = count_nodes(r);
453 num_elem = 0;
454 }
455
468 {
470 << "lists are not empty";
471 split_list_ne(l, r);
472 }
473
477 {
478 split_list(l, r);
479 }
480
485 class Iterator : public Dnode<T>::Iterator
486 {
487 DynDlist * list_ptr; // puntero a la lista
488 long pos; // posición del elemento actual en la secuencia
489
490 using Base = typename Dnode<T>::Iterator;
491
492 public:
493
496
498 using Item_Type = T;
499
501 long get_pos() const noexcept { return pos; }
502
506 {
508 pos++;
509 }
510
513 void next()
514 {
516 pos++;
517 }
518
521 void prev()
522 {
524 pos--;
525 }
526
529 {
531 pos = 0;
532 }
533
540
543 {
544 put_itor_at_the_end(*this);
545 }
546
549 : Base(list), list_ptr(&const_cast<DynDlist&>(list)), pos(0)
550 {
551 // empty
552 }
553
554 Iterator() noexcept : list_ptr(nullptr) { /* empty */ }
555
556 Iterator & operator = (const Iterator & it) noexcept
557 {
559 list_ptr = it.list_ptr;
560 pos = it.pos;
561
562 return *this;
563 }
564
567 T & get_curr() const
568 {
569 return Dnode<T>::Iterator::get_curr()->get_data();
570 }
571
573 {
574 return Dnode<T>::Iterator::get_curr_ne()->get_data();
575 }
576
586 void insert(const T & item)
587 {
589 << "DynDlist Iterator has not current";
590
591 Dnode<T>::Iterator::get_curr()->insert(new Dnode<T>(item));
593 }
594
605 void insert(T && item)
606 {
608 << "DynDlist Iterator has not current";
609
611 insert(new Dnode<T>(std::forward<T>(item)));
613 }
614
624 void append(const T & item)
625 {
627 << "DynDlist Iterator has not current";
628
629 Dnode<T>::Iterator::get_curr()->append(new Dnode<T>(item));
631 }
632
643 void append(T && item)
644 {
646 << "DynDlist Iterator has not current";
647
649 append(new Dnode<T>(std::forward<T>(item)));
651 }
652
669 {
671 << "DynDlist Iterator has not current";
672
673 Dnode<T>::Iterator::get_curr()->insert_list(&list);
674 list_ptr->num_elem += list.num_elem;
675 list.num_elem = 0;
676
677 assert(list.is_empty());
678 }
679
696 {
698 << "DynDlist Iterator has not current";
699
700 Dnode<T>::Iterator::get_curr()->append_list(&list);
701 list_ptr->num_elem += list.num_elem;
702 list.num_elem = 0;
703
704 assert(list.is_empty());
705 }
706
714 {
716 << "DynDlist Iterator has not current";
717
719 T ret_val = ptr->get_data();
721 ptr->del();
722 delete ptr;
724 return ret_val;
725 }
726 };
727
738 {
739 if (this == &list)
740 return *this;
741
742 empty();
743
744 for (Iterator itor(const_cast<DynDlist&>(list));
745 itor.has_curr(); itor.next_ne())
746 this->append(itor.get_curr());
747
748 return *this;
749 }
750
758 DynDlist(const DynDlist & list) : DynDlist()
759 {
760 assert(this->is_empty());
761
762 for (Iterator itor(const_cast<DynDlist&>(list));
763 itor.has_curr();itor.next_ne())
764 this->append(itor.get_curr());
765 }
766
776 : DynDlist()
777 {
778 swap(list);
779 }
780
789 DynDlist<T> & operator = (DynDlist && list) noexcept
790 {
791 swap(list);
792 return *this;
793 }
794
797 T & operator [] (const size_t n) const
798 {
799 auto it = this->get_it();
800 for (size_t i = 0; i < n && it.has_curr(); ++i)
801 it.next_ne();
802
803 ah_out_of_range_error_if(not it.has_curr())
804 << "DynDlist index out of range";
805
806 return it.get_curr();
807 }
808
810 {
812 return *this;
813 }
814
815 DynDlist & rev() noexcept { return reverse(); }
816
822 {
824 for (auto it = this->get_it(); it.has_curr(); it.next_ne())
825 ret.insert(it.get_curr());
826 return ret;
827 }
828
829 DynDlist<T> rev() const { return reverse(); }
830};
831
832} // end namespace Aleph
833
834# endif /* TPL_DYNDLIST_H */
835
Variadic constructor macros for containers.
Container traversal and functional operation mixins.
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:579
#define ah_underflow_error_if(C)
Throws std::underflow_error if condition holds.
Definition ah-errors.H:368
#define ah_overflow_error_if(C)
Throws std::overflow_error if condition holds.
Definition ah-errors.H:463
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Definition ah-errors.H:522
STL-compatible iterator adapters for Aleph containers.
DRY (Don't Repeat Yourself) utilities and macros.
#define Special_Ctors(Set_Type, Type)
Generates special constructors for containers.
Definition ahDry.H:113
Functional programming utilities for Aleph-w containers.
Iterator traits and STL-compatible iterator wrappers.
void put_itor_at_the_end(Itor &it) noexcept
Definition aleph.H:54
Iterator on a list of Dnode objects.
Definition tpl_dnode.H:261
Dnode< T > * get_curr_ne() const noexcept
Return the current link guaranteeing no exception. Be careful.
Definition tpl_dnode.H:275
Dnode< T > * get_curr() const
Return a pointer to the current node.
Definition tpl_dnode.H:285
Node belonging to a double circular linked list with header node.
Definition tpl_dnode.H:106
Dnode< T > *& get_next() const noexcept
Return the next node to this
Definition tpl_dnode.H:114
Dnode< T > * remove_next() noexcept
Remove the next node to this; return its address.
Definition tpl_dnode.H:123
T & get_data() noexcept
Return a modifiable reference to the data contained in the node.
Definition tpl_dnode.H:232
Dnode< T > *& get_prev() const noexcept
Return the previous node to this
Definition tpl_dnode.H:117
static Dnode * data_to_node(T &data) noexcept
Given an reference to the data in the node, returns a pointer to the Dnode object that contains it.
Definition tpl_dnode.H:248
Dnode< T > * remove_prev() noexcept
Remove the previous node to this; return its address.
Definition tpl_dnode.H:120
Iterator dynamic list.
void append_list(DynDlist &list)
Move and append all elements of list before the current item of iterator.
T Item_Type
The type of element stored in the container.
typename Dnode< T >::Iterator Base
void next_ne() noexcept
Move the iterator one position forward guaranteeing no exception.
void insert(const T &item)
Insert by copy an item after the current item.
T & get_curr() const
Return the current item; throw overflow_error if there is no current item.
void reset_last() noexcept
Reset the iterator to the last item.
Iterator & operator=(const Iterator &it) noexcept
void end() noexcept
Put the iterator at the end state (where there is no current item)
void prev()
Move the iterator one item backward.
long get_pos() const noexcept
Return the ordinal position of current item.
void insert(T &&item)
Insert by movement an item after the current item.
T del()
Remove from the list the current node and move the iterator one position forward.
void append(T &&item)
Append by movement an item after the current item.
void insert_list(DynDlist &list)
Move and insert all elements of list after the current item of iterator.
void reset_first() noexcept
Reset the iterator to the first item.
Iterator(const DynDlist< T > &list) noexcept
Initialize the iterator to the first item of list
void append(const T &item)
Append by copy an item before the current item.
void next()
Move the iterator one item forward.
T & get_curr_ne() const noexcept
Dynamic doubly linked list with O(1) size and bidirectional access.
T & get_last() const
Return a modifiable reference to last item in the list.
void insert(DynDlist &&list) noexcept
const size_t & size() const noexcept
Return the number of elements (constant time)
DynDlist & reverse() noexcept
T Key_Type
The type of element that stores the container.
T & __insert(Dnode< T > *p) noexcept
T & front()
If this was treated as a queue, the it returns the most oldlest inserted item.
DynDlist< T > reverse() const
Return a reversed copy of this
T & push(T &&item)
T & get_first_ne() const noexcept
Return a modifiable reference to first item in the list.
T & put(T &&item)
T & operator[](const size_t n) const
Return a modifiable reference to the i-th item of the list.
void split_list(DynDlist &l, DynDlist &r)
Split the list in two.
void swap(DynDlist &l) noexcept
Swap in constant time all the items of this with all the items of l (very fast!)
T Item_Type
The type of element that stores the container.
T & push(const T &item)
T remove_last()
Remove the last item of the list; return a copy of removed item.
DynDlist()=default
DynDlist(DynDlist< T > &&list) noexcept
Move constructor; all items of list are moved.
void remove(T &data) noexcept
Assuming that data is a reference to the item in the list, it removes the item.
void insert(const DynDlist &list)
Insert all the elements of list before this.
T & put(const T &item)
void empty() noexcept
Empty the list.
T & append(const T &item)
Append a copied item at the end of the list.
void __append(DynDlist< T > &list) noexcept
T & append(T &&item)
Append a moved item at the end of the list.
DynDlist & rev() noexcept
T & rear()
If this was treated as a queue, the it returns the most recently inserted item.
void split(DynDlist &l, DynDlist &r)
This is an overloaded member function, provided for convenience. It differs from the above function o...
DynDlist< T > rev() const
T & get_first() const
Return a modifiable reference to first item in the list.
void erase(T &data) noexcept
void __insert(DynDlist< T > &list) noexcept
T & get_last_ne() const noexcept
Return a modifiable reference to last item in the list.
T & __append(Dnode< T > *p) noexcept
void append(DynDlist &&list) noexcept
T & insert(const T &item)
Insert a copy of item at the beginning of the list.
void append(const DynDlist &list)
Append all the elements of list after this.
~DynDlist()
Destructor.
T remove_first_ne() noexcept
Remove the first item of the list; return a copy of removed item.
T remove_last_ne() noexcept
Remove the last item of the list; return a copy of removed item.
DynDlist< T > & operator=(const DynDlist &list)
Assignment by copy.
T remove_first()
Remove the first item of the list; return a copy of removed item.
T & insert(T &&item)
Insert a moved item at the beginning of the list.
void split_list_ne(DynDlist &l, DynDlist &r) noexcept
Split the list in two.
DynDlist(const DynDlist &list)
Copy constructor; all items of list are copied.
T & top() const
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
Common methods to the Aleph-w ( ) containers.
Definition ah-dry.H:548
Aleph::DynList< __T > maps(Operation &op) const
Map the elements of the container.
Definition ah-dry.H:904
Common sequential searching methods on containers.
Definition ah-dry.H:164
auto get_it() const
Return a properly initialized iterator positioned at the first item on the container.
Definition ah-dry.H:190
Mixin that adds STL begin()/end() and cbegin()/cend() to Aleph containers.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
std::decay_t< typename HeadC::Item_Type > T
Definition ah-zip.H:107
Itor::difference_type count(const Itor &beg, const Itor &end, const T &value)
Count elements equal to a value.
Definition ahAlgo.H:127
Generic list of items stored in a container.
Definition ah-dry.H:1501
Generic traversal of the container through its iterator.
Definition ah-dry.H:65
Special constructors common to Aleph-w ( ) containers.
Definition ah-dry.H:492
Doubly linked list node with typed data.
DynList< int > l