ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
list.hpp
Go to the documentation of this file.
1/** ************************************************************************************************
2 * \file
3 * This header file is part of module \alib_monomem of the \aliblong.
4 *
5 * \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6 * Published under \ref mainpage_license "Boost Software License".
7 **************************************************************************************************/
8#ifndef HPP_ALIB_MONOMEM_LIST
9#define HPP_ALIB_MONOMEM_LIST 1
10
11#if !defined (HPP_ALIB_MONOMEM_FWDS)
12# include "alib/monomem/fwds.hpp"
13#endif
14
15#if !defined (HPP_ALIB_MONOMEM_MONOALLOCATOR)
17#endif
18
19#if !defined (HPP_ALIB_MONOMEM_DETAIL_RECYCLER)
21#endif
22
23#if !defined(HPP_ALIB_LANG_BIDILIST)
24# include "alib/lang/bidilist.hpp"
25#endif
26
27namespace alib { namespace monomem {
28
29namespace detail
30{
31 /** Extents \b BidiNodeBase by an value of type \p{T}. */
32 template<typename T>
33 struct ListElement : public lang::BidiNodeBase<ListElement<T>>
34 {
35 T data; ///< The custom data object.
36 };
37
38 /**
39 * Partially specialized helper struct used to determine the recycler type for struct
40 * \alib{monomem;List}.
41 */
42 template<typename T, typename TRecycling> struct ListRecycler {};
43#if !defined(ALIB_DOX)
44 template<typename T> struct ListRecycler<T,Recycling::Private>{ using type= detail::RecyclerPrivate<detail::ListElement<T>>; };
45 template<typename T> struct ListRecycler<T,Recycling::Shared >{ using type= detail::RecyclerShared <detail::ListElement<T>>; };
46 template<typename T> struct ListRecycler<T,Recycling::None >{ using type= detail::RecyclerVoid <detail::ListElement<T>>; };
47#endif
48
49} // namespace detail
50
51
52/** ************************************************************************************************
53 * Implements a doubly linked list, likewise \c std::list does. Memory for inserted elements is
54 * allocated using the \alib{monomem;MonoAllocator} provided with the constructor.
55 *
56 * Elements that are erased from the list will be recycled with subsequent insert operations.
57 * With that, remove and insert operations do not lead to leaked memory in the monotonic allocator.
58 *
59 * It is allowed to use different allocator objects with insertions. However, the life-cycle
60 * of the allocated memory and the objects stored in this container has to be kept in sync
61 * by the user of this object. For more information on this topic see methods #Clear and #Reset.
62 *
63 * @tparam T The type of the contained objects.
64 * @tparam TRecycling Denotes the type of recycling that is to be performed. Possible values are
65 * \alib{monomem;Recycling::Private} (the default),
66 * \alib{monomem;Recycling::Shared} or \alib{monomem;Recycling::None}.
67 **************************************************************************************************/
68template<typename T, typename TRecycling>
69class List
70{
71 // #############################################################################################
72 // Node/Element type
73 // #############################################################################################
74 protected:
75 /** The list element type. */
77
78 /** The allocator assigned. */
80
81 /** The list. */
83
84 /** The recycler. Its type depends on template parameter \p{TRecycling}. */
86
87 public:
88 /** This type definition may be used to define an externally managed shared recycler,
89 * which can be passed to the alternative constructor of this class when template
90 * parameter \p{TRecycling} equals \alib{monomem;Recycling::Shared}.
91 * \see
92 * Chapter \ref alib_monomem_containers_recycling_shared of the Programmer's Manual
93 * for this \alibmod. */
95
96 // #############################################################################################
97 // Helpers
98 // #############################################################################################
99 protected:
100 /** Returns either a recycled or newly allocated element.
101 * @return A pointer to the element created or recycled. */
103 {
104 Element* elem= recycler.get();
105 if( elem != nullptr )
106 return elem;
107
108 return allocator->Alloc<Element>();
109 }
110
111 // #############################################################################################
112 // std::iterator_traits
113 // #############################################################################################
114 protected:
115
116 /** ****************************************************************************************
117 * Implementation of \c std::iterator_traits for this container.
118 *
119 * As the name of the class indicates, this iterator satisfies the C++ standard library
120 * concept
121 * \https{BidirectionalIterator,en.cppreference.com/w/cpp/named_req/BidirectionalIterator}.
122 *
123 * @tparam TConstOrMutableElement The custom data type as either <c>const</c> or mutable.
124 ******************************************************************************************/
125 template<typename TConstOrMutableElement>
127 {
128 using iterator_category = std::bidirectional_iterator_tag; ///< Implementation of <c>std::iterator_traits</c>.
129 using value_type = TConstOrMutableElement ; ///< Implementation of <c>std::iterator_traits</c>.
130 using difference_type = integer ; ///< Implementation of <c>std::iterator_traits</c>.
131 using pointer = TConstOrMutableElement* ; ///< Implementation of <c>std::iterator_traits</c>.
132 using reference = TConstOrMutableElement& ; ///< Implementation of <c>std::iterator_traits</c>.
133
134 private:
135 Element* element; ///< The actual element of the list.
136
137 #if !defined(ALIB_DOX)
138 friend class List<T, TRecycling>;
139 #endif
140
141
142 public:
143
144 /** Default constructor creating an invalid iterator. */
145 TIterator() = default;
146
147 /** Constructor.
148 * @param start Pointer to the initial element. */
149 explicit TIterator( Element* start )
150 : element( start )
151 {}
152
153 #if defined(ALIB_DOX)
154 /** Copy constructor accepting a mutable iterator.
155 * Available only for the constant version of this iterator.
156 * @tparam TMutable The type of this constructor's argument.
157 * @param mutableIt Mutable iterator to copy from. */
158 template<typename TMutable>
159 TIterator( const TMutable& mutableIt );
160 #else
161 ATMP_SELECT_IF_1TP( typename TMutable,
162 ATMP_EQ( TMutable,
163 TIterator<typename std::remove_const<TConstOrMutableElement>::type> ) )
164 TIterator( const TMutable& mutableIt )
165 : element( mutableIt.element )
166 {}
167 #endif
168
169 // ###################### To satisfy concept of InputIterator ######################
170
171 /** Prefix increment operator.
172 * @return A reference to this object. */
174 {
175 element= element->next();
176 return *this;
177 }
178
179 /** Postfix increment operator.
180 * @return An iterator value that is not increased, yet. */
182 {
183 auto result= TIterator(element);
184 element= element->next();
185 return result;
186 }
187
188 /** Comparison operator.
189 * @param other The iterator to compare ourselves to.
190 * @return \c true if this and the given iterator are pointing to the same element,
191 * \c false otherwise. */
192 bool operator==(TIterator other) const
193 {
194 return element == other.element;
195 }
196
197 /** Comparison operator.
198 * @param other The iterator to compare ourselves to.
199 * @return \c true if this and given iterator are not equal, \c false otherwise. */
200 bool operator!=(TIterator other) const
201 {
202 return !(*this == other);
203 }
204
205 //################## To satisfy concept of BidirectionalIterator ##################
206
207 /** Prefix decrement operator.
208 * @return A reference to this object. */
210 {
211 element= element->prev();
212 return *this;
213 }
214
215 /** Postfix decrement operator.
216 * @return The iterator value prior the decrement operation. */
218 {
219 auto result= TIterator(element);
220 element= element->prev();
221 return result;
222 }
223
224 // ###################### Member access ######################
225
226 /** Retrieves a reference to the referred element.
227 * @return A reference to the referred element. */
228 TConstOrMutableElement& operator*() const
229 {
230 return element->data;
231 }
232
233 /** Retrieves a pointer to the referred element.
234 * @return A pointer to the referred element. */
235 TConstOrMutableElement* operator->() const
236 {
237 return &element->data;
238 }
239
240 }; // struct TIterator
241
242 public:
243 /** The constant iterator exposed by this container. */
245
246 /** The mutable iterator exposed by this container. */
248
249 /** The constant iterator exposed by this container. */
250 using ConstReverseIterator = std::reverse_iterator<ConstIterator>;
251
252 /** The mutable iterator exposed by this container. */
253 using ReverseIterator = std::reverse_iterator<Iterator>;
254
255 /** ############################################################################################
256 * @name std::iterator_traits Interface
257 #############################################################################################*/
258 /** Returns an iterator pointing to a mutable value at the start of this list.
259 * @return The start of this list. */
260 Iterator begin() { return Iterator( list.first() ); }
261
262 /** Returns an iterator pointing to the first element behind this list.
263 * @return The end of this list. */
264 Iterator end() { return Iterator( list.end() ); }
265
266 /** Returns an iterator pointing to a constant value at the start of this list.
267 * @return The start of this list. */
268 ConstIterator begin() const { return ConstIterator( list.first() ); }
269
270 /** Returns an iterator pointing to the first element behind this list.
271 * @return The end of this list. */
272 ConstIterator end() const { return ConstIterator( list.end() ); }
273
274 /** Returns an iterator pointing to a constant value at the start of this list.
275 * @return The start of this list. */
276 ConstIterator cbegin() const { return ConstIterator( list.first() ); }
277
278 /** Returns an iterator pointing to the first element behind this list.
279 * @return The end of this list. */
280 ConstIterator cend() const { return ConstIterator( list.end() ); }
281
282 /** Returns a reverse iterator pointing to a mutable value at the end of this list.
283 * @return The start of this list. */
285
286 /** Returns a reverse iterator pointing to the first element behind the start of this list.
287 * @return The end of this list. */
289
290 /** Returns a reverse iterator pointing to a constant value at the end of this list.
291 * @return The start of this list. */
293
294 /** Returns a reverse iterator pointing to the first element behind the start of this list.
295 * @return The end of this list. */
297
298 /** Returns a reverse iterator pointing to a constant value at the end of this list.
299 * @return The start of this list. */
301
302 /** Returns a reverse iterator pointing to the first element behind the start of this list.
303 * @return The end of this list. */
305
306
307 /** ############################################################################################
308 * @name Construction/Destruction
309 #############################################################################################*/
310 public:
311 /** ****************************************************************************************
312 * Copy constructor.
313 * Invokes implementation dependent copy constructor of recycler, copies the pointer to the
314 * allocator and then copies each element.
315 * @param copy The list to copy.
316 ******************************************************************************************/
317 List( const List& copy)
318 : allocator ( copy.allocator )
319 , recycler ( copy.recycler )
320 {
321 for( auto& element : copy )
322 PushBack( element );
323 }
324
325 /** ****************************************************************************************
326 * Move constructor.
327 * Invokes implementation dependent move constructor of recycler, moves the pointer to the
328 * allocator and then copies each element.
329 * @param move The private recycler to move.
330 ******************************************************************************************/
331 List( List&& move)
332 : allocator ( std::move( move.allocator ) )
333 , recycler ( std::move( move.recycler ) )
334 , list ( std::move( move.list ) )
335 {}
336
337 #if defined(ALIB_DOX)
338 /** ****************************************************************************************
339 * Constructor accepting a pointer to the allocator.
340 *
341 * \note
342 * This cnstructor is not available if template argument \p{TRecycling} equals
343 * type \alib{monomem;Recycling::Shared}.
344 *
345 * @param pAllocator The monotonic allocator to use.
346 ******************************************************************************************/
347 List( MonoAllocator* pAllocator )
348 : allocator( pAllocator )
349 {}
350 #else
351 template<typename TEnableIf= TRecycling,
352 ATMP_T_IF(int, !ATMP_EQ(TEnableIf, Recycling::Shared)) = 0 >
353 explicit
354 List( MonoAllocator* pAllocator )
355 : allocator( pAllocator )
356 {}
357 #endif // defined(ALIB_DOX)
358
359 /** ****************************************************************************************
360 * Constructor taking a shared recycler.
361 * @param pAllocator The monotonic allocator to use.
362 * @param pRecycler The shared recycler.
363 ******************************************************************************************/
364 explicit
365 List( MonoAllocator* pAllocator, TSharedRecycler& pRecycler )
366 : allocator( pAllocator )
367 , recycler( pRecycler )
368 {}
369
370
371 /** ****************************************************************************************
372 * Destructor. Invokes #Clear.
373 ******************************************************************************************/
375 {
376 if constexpr( !std::is_trivially_destructible<T>::value )
377 Clear();
378 }
379
380 /** ############################################################################################
381 * @name Allocation
382 #############################################################################################*/
383 /** ****************************************************************************************
384 * Returns the allocator of this object. Usually the allocator might be used to perform
385 * allocations in respect to data found in objects stored in this object.
386 * However, such allowance is dependent on the use case and not part of this class's
387 * contract.
388 *
389 * @return The allocator that was provided in the constructor.
390 ******************************************************************************************/
392 {
393 return allocator;
394 }
395
396 /** ****************************************************************************************
397 * Counts the number of currently allocated but unused (not contained) list elements
398 * that will be recycled with upcoming insertions.
399 *
400 * \note
401 * This method is provided for completeness and unit-testing. It should not be of
402 * relevance for common usage.<br>
403 * Furthermore, this method is not available (aka does not compile) with instantiations
404 * that specify template parameter \p{TRecycling} as \alib{monomem;Recycling::None}.
405 *
406 * @return The number of removed and not yet recycled elements.
407 ******************************************************************************************/
409 {
410 return recycler.count();
411 }
412
413
414 /** ############################################################################################
415 * @name Size and Capacity
416 #############################################################################################*/
417 /** ****************************************************************************************
418 * Evaluates the size of the list by traversing all elements.
419 * @return The number of elements contained in this listed.
420 ******************************************************************************************/
421 integer Size() const
422 {
423 return list.count();
424 }
425
426 /** ****************************************************************************************
427 * Tests this container for emptiness.
428 * @return \c true if this list is empty, \c false otherwise.
429 ******************************************************************************************/
430 bool IsEmpty() const
431 {
432 return list.isEmpty();
433 }
434
435 /** ****************************************************************************************
436 * Tests this container for emptiness.
437 * @return \c true if this list is empty, \c false otherwise.
438 ******************************************************************************************/
439 bool IsNotEmpty() const
440 {
441 return !list.isEmpty();
442 }
443
444 /** ****************************************************************************************
445 * Invokes the destructor of all elements and empties the list.
446 * All allocated internal elements are kept for future recycling.
447 * Hence, the invocation of this method with this value implies that associated
448 * monotonic allocator is \b not reset.
449 *
450 * As the life-cycle of the monotonic allocator(s) used for insertions is not under control of
451 * this object, it is the obligation of the caller to ensure that the monotonic allocator is
452 * kept in sync with this object.
453 ******************************************************************************************/
454 void Clear()
455 {
456 if( !list.isEmpty() )
457 {
458 auto* elem= list.first();
459 while( elem != &list.hook )
460 {
461 elem->data.~T();
462 elem= elem->next();
463 }
464 recycler.recycle( list.first(), list.last() );
465 list.reset();
466 }
467 }
468
469 /** ****************************************************************************************
470 * Invokes #Clear and in case of \alib{monomem;Recycling::Private;private recycling}
471 * disposes all previously allocated recyclable instances of internal element type.
472 *
473 * Hence, the invocation of this method with this value usually implies that
474 * the monotonic allocator used is reset as well.
475 *
476 * As the life-cycle of the monotonic allocator(s) used for insertions is not under control of
477 * this object, it is the obligation of the caller to ensure that the monotonic allocator is
478 * kept in sync with this object.
479 ******************************************************************************************/
480 void Reset()
481 {
482 Clear();
483 recycler.disposeRecyclablesIfPrivate();
484 }
485
486 /** ****************************************************************************************
487 * Allocates the required memory for the number of additional elements expected.
488 *
489 * This method may be helpful if the definite number of stored elements that is never
490 * exceeded is known. In this case, a \alib{monomem;MonoAllocator::TakeSnapshot;snapshot}
491 * of the monotonic allocator could be taken after the invocation of this method and
492 * then used to reset the monotonic allocator with preserving the memory used by this container.
493 *
494 * \note
495 * This method is not available (aka does not compile) with instantiations
496 * that specify template parameter \p{TRecycling} as \alib{monomem;Recycling::None}.
497 *
498 * @param expectedSize The expected number of elements to be stored in the hash table.
499 ******************************************************************************************/
500 void ReserveRecyclables( integer expectedSize )
501 {
502 auto requiredRecyclables= (expectedSize - Size()) - RecyclablesCount();
503 if( requiredRecyclables > 0 )
504 {
506 Element* newElements= allocator->template AllocArray<Element>( requiredRecyclables );
507 for( auto i= requiredRecyclables -2; i >= 0 ; --i )
508 newElements[i].next( &newElements[i + 1] );
509
510 recycler.recycle( &newElements[0], &newElements[requiredRecyclables - 1] );
512 }
513 }
514
515 /** ############################################################################################
516 * @name Element Access
517 #############################################################################################*/
518
519 /** ****************************************************************************************
520 * Traverses the list to return the item with the given \p{idx}.
521 * (Executes in linear time <b>O(N)</b>.)
522 *
523 * @param idx The index of the element to retrieve.
524 * @return A mutable reference to \p{T}.
525 ******************************************************************************************/
527 {
528 ALIB_ASSERT_ERROR( !list.isEmpty(), "MONOMEM/LIST",
529 "Reference to element requested on empty monomem::List")
530
531 Element* act= list.first();
532 for( integer i= 0 ; i < idx ; ++i )
533 {
534 act= act->next();
535 ALIB_ASSERT_ERROR( act != nullptr, "MONOMEM/LIST", "Element index out of bounds")
536 }
537 return act->data;
538 }
539
540 /** ****************************************************************************************
541 * Traverses the list to return the item with the given \p{idx}.
542 * (Executes in linear time <b>O(N)</b>.)
543 *
544 * @param idx The index of the element to retrieve.
545 * @return A constant reference to \p{T}.
546 ******************************************************************************************/
547 const T& ElementAt(integer idx) const
548 {
549 ALIB_ASSERT_ERROR( list.isNotEmpty(), "MONOMEM/LIST",
550 "Reference to element requested on empty monomem::List")
551
552 Element* act= list.first();
553 for( integer i= 0 ; i < idx ; ++i )
554 {
555 act= act->next();
556 ALIB_ASSERT_ERROR( act != nullptr, "MONOMEM/LIST", "Element index out of bounds")
557 }
558 return act->data;
559 }
560
561 /** ****************************************************************************************
562 * Returns a non-constant reference to the first object of the list.
563 * @return A mutable reference to \p{T}.
564 ******************************************************************************************/
565 T& Front()
566 {
567 ALIB_ASSERT_ERROR( !list.isEmpty(), "MONOMEM/LIST",
568 "Reference to element requested on empty monomem::List")
569 return list.first()->data;
570 }
571
572
573 /** ****************************************************************************************
574 * Returns a constant reference to the first object of the list.
575 * @return A constant reference to \p{T}.
576 ******************************************************************************************/
577 const T& Front() const
578 {
579 ALIB_ASSERT_ERROR( !list.isEmpty(), "MONOMEM/LIST",
580 "Reference to element requested on empty monomem::List")
581 return list.first()->data;
582 }
583
584 /** ****************************************************************************************
585 * Returns a non-constant reference to the last object of the list.
586 * @return A mutable reference to \p{T}.
587 ******************************************************************************************/
588 T& Back()
589 {
590 ALIB_ASSERT_ERROR( !list.isEmpty(), "MONOMEM/LIST",
591 "Reference to element requested on empty monomem::List")
592 return list.last()->data;
593 }
594
595 /** ****************************************************************************************
596 * Returns a constant reference to the last object of the list.
597 * @return A constant reference to \p{T}.
598 ******************************************************************************************/
599 const T& Back() const
600 {
601 ALIB_ASSERT_ERROR( list.isNotEmpty(), "MONOMEM/LIST",
602 "Reference to element requested on empty monomem::List")
603 return list.last()->data;
604 }
605
606 /** ############################################################################################
607 * @name Element Insertion
608 #############################################################################################*/
609 /** ****************************************************************************************
610 * Adds a new element before the given \p{position}.
611 * @param position The position to emplace the new element.
612 * @param copy The value to copy and insert.
613 * @return A constant reference to the element added.
614 ******************************************************************************************/
615 Iterator Insert(ConstIterator position, const T& copy)
616 {
617 Element* elem= allocElement();
618 new (&elem->data) T(copy);
619 position.element->addBefore( elem );
620
621 return Iterator(elem);
622 }
623
624 /** ****************************************************************************************
625 * Moves a value into this container before the given \p{position}.
626 * @param position The position to emplace the new element.
627 * @param move The value to move into this container.
628 * @return A constant reference to the element moved.
629 ******************************************************************************************/
630 Iterator Insert(ConstIterator position, T&& move)
631 {
632 Element* elem= allocElement();
633 new (&elem->data) T(std::move(move));
634 position.element->addBefore( elem );
635
636 return Iterator(elem);
637 }
638
639 /** ****************************************************************************************
640 * Adds a new element at the end of the list.
641 * @param copy The value to copy and insert.
642 * @return A reference to the element added.
643 ******************************************************************************************/
644 T& PushBack(const T& copy)
645 {
646 Element* elem= allocElement();
647
648 new (&elem->data) T(copy);
649 list.pushEnd( elem );
650 return elem->data;
651 }
652
653 /** ****************************************************************************************
654 * Moves a value to the end of this list.
655 * @param move The value to move into this container.
656 * @return A reference to the element moved.
657 ******************************************************************************************/
658 T& PushBack(T&& move)
659 {
660 Element* elem= allocElement();
661
662 new (&elem->data) T(std::move(move));
663 list.pushEnd( elem );
664 return elem->data;
665 }
666
667 /** ****************************************************************************************
668 * Adds a new element at the start of the list.
669 * @param copy The value to copy and insert.
670 * @return A reference to the element added.
671 ******************************************************************************************/
672 T& PushFront(const T& copy)
673 {
674 Element* elem= allocElement();
675 new (&elem->data) T(copy);
676 list.pushFront( elem );
677 return elem->data;
678 }
679
680 /** ****************************************************************************************
681 * Moves a value to the start of this list.
682 * @param move The value to move into this container.
683 * @return A reference to the element moved.
684 ******************************************************************************************/
685 T& PushFront(T&& move)
686 {
687 Element* elem= allocElement();
688
689 new (&elem->data) T(std::move(move));
690 list.pushFront( elem );
691 return elem->data;
692 }
693
694 /** ****************************************************************************************
695 * Adds a new element before the given \p{position}.
696 * @tparam TArgs Types of variadic parameters given with parameter \p{args}.
697 * @param position The position to emplace the new element.
698 * @param args Variadic parameters to be forwarded to constructor of type \p{T}.
699 * @return A constant reference to the element added.
700 ******************************************************************************************/
701 template<typename... TArgs>
702 Iterator Emplace(ConstIterator position, TArgs&&... args)
703 {
704 Element* elem= allocElement();
705 new (&elem->data) T( std::forward<TArgs>(args)... );
706 position.element->addBefore( elem );
707
708 return Iterator(elem);
709 }
710
711 /** ****************************************************************************************
712 * Adds a new element at the end of the list.
713 * @tparam TArgs Types of variadic parameters given with parameter \p{args}.
714 * @param args Variadic parameters to be forwarded to constructor of type \p{T}.
715 * @return A reference to the element added.
716 ******************************************************************************************/
717 template<typename... TArgs>
718 T& EmplaceBack(TArgs&&... args)
719 {
720 Element* elem= allocElement();
721
722 new (&elem->data) T( std::forward<TArgs>(args)... );
723 list.pushEnd( elem );
724 return elem->data;
725 }
726
727 /** ****************************************************************************************
728 * Adds a new element at the end of the list.
729 * @tparam TArgs Types of variadic parameters given with parameter \p{args}.
730 * @param args Variadic parameters to be forwarded to constructor of type \p{T}.
731 * @return A reference to the element added.
732 ******************************************************************************************/
733 template<typename... TArgs>
734 T& EmplaceFront(TArgs&&... args)
735 {
736 Element* elem= allocElement();
737
738 new (&elem->data) T( std::forward<TArgs>(args)... );
739 list.pushFront( elem );
740 return elem->data;
741 }
742
743 /** ############################################################################################
744 * @name Element Removal
745 #############################################################################################*/
746 /** ****************************************************************************************
747 * Removes an element at the given position.
748 *
749 * @param position A constant iterator pointing to the element to be removed.
750 * Mutable iterators are inherently converted with the invocation of this
751 * method.
752 * @return A mutable iterator pointing behind the removed element.
753 * If \p{position} refers to the last element of the list, iterator #end() is
754 * returned.
755 ******************************************************************************************/
757 {
758 ALIB_ASSERT_ERROR( !list.isEmpty(), "MONOMEM/LIST",
759 "Erase requested on empty monomem::List")
760 ALIB_ASSERT_ERROR( position != end(), "MONOMEM/LIST",
761 "Iterator end() given with monomem::List::Erase")
762
763
764 Element* next = position.element->next();
765 position.element->remove();
766 monomem::Destruct(&position.element->data);
767 recycler.recycle( position.element );
768
769 return Iterator(next);
770 }
771
772 /** ****************************************************************************************
773 * Removes a range of elements defined by iterators \p{first} and \p{last}.
774 *
775 * @param first The start of the range to remove.
776 * @param last The first element behind the range to remove.
777 * @return A mutable iterator referring to the given \p{last}.
778 ******************************************************************************************/
780 {
781 ALIB_ASSERT_ERROR( !list.isEmpty() || ( first == begin() && last == end() ),
782 "MONOMEM/LIST", "Erase requested on empty monomem::List")
783 if( first == last )
784 return Iterator(const_cast<Element*>( last.element ));
785
786 // destruct objects
787 Element* elem = const_cast<Element*>( first.element );
788 do
789 {
790 monomem::Destruct(&elem->data);
791 elem= elem->next();
792 }
793 while ( elem != last.element );
794
795 Element* lastElem= last.element->prev();
796 first.element->remove( lastElem );
797 recycler.recycle( first.element, lastElem );
798
799 return Iterator( last.element );
800 }
801
802 /** ****************************************************************************************
803 * Removes the first element.
804 ******************************************************************************************/
805 void PopFront()
806 {
807 ALIB_ASSERT_ERROR( !IsEmpty(), "MONOMEM/LIST", "PopFront called on empty List instance." )
808 Element* element= list.popFront();
809 element->data.~T();
810 recycler.recycle( element );
811 }
812
813 /** ****************************************************************************************
814 * Removes the last element.
815 ******************************************************************************************/
816 void PopBack()
817 {
818 ALIB_ASSERT_ERROR( !IsEmpty(), "MONOMEM/LIST", "PopBack called on empty List instance." )
819 Element* element= list.popEnd();
820 monomem::Destruct(&element->data);
821 recycler.recycle( element );
822 }
823}; // class List
824
825} // namespace alib[::monomem]
826
827/// Type alias in namespace \b alib.
828template<typename T, typename TRecycling = monomem::Recycling::Private>
830
831} // namespace [alib]
832
833#endif // HPP_ALIB_MONOMEM_LIST
ConstIterator cend() const
Definition list.hpp:280
Iterator Insert(ConstIterator position, T &&move)
Definition list.hpp:630
List(MonoAllocator *pAllocator, TSharedRecycler &pRecycler)
Definition list.hpp:365
Iterator begin()
Definition list.hpp:260
std::reverse_iterator< Iterator > ReverseIterator
Definition list.hpp:253
integer RecyclablesCount() const
Definition list.hpp:408
ConstReverseIterator crbegin() const
Definition list.hpp:300
const T & Back() const
Definition list.hpp:599
integer Size() const
Definition list.hpp:421
T & EmplaceFront(TArgs &&... args)
Definition list.hpp:734
ConstReverseIterator rend() const
Definition list.hpp:296
Iterator Emplace(ConstIterator position, TArgs &&... args)
Definition list.hpp:702
detail::ListRecycler< T, TRecycling >::type recycler
Definition list.hpp:85
ConstIterator end() const
Definition list.hpp:272
bool IsNotEmpty() const
Definition list.hpp:439
Iterator Insert(ConstIterator position, const T &copy)
Definition list.hpp:615
ConstReverseIterator rbegin() const
Definition list.hpp:292
T & PushBack(const T &copy)
Definition list.hpp:644
bool IsEmpty() const
Definition list.hpp:430
ConstIterator cbegin() const
Definition list.hpp:276
ReverseIterator rend()
Definition list.hpp:288
TIterator< const T > ConstIterator
Definition list.hpp:244
T & ElementAt(integer idx)
Definition list.hpp:526
void ReserveRecyclables(integer expectedSize)
Definition list.hpp:500
T & PushFront(const T &copy)
Definition list.hpp:672
MonoAllocator * allocator
Definition list.hpp:79
List(List &&move)
Definition list.hpp:331
Iterator end()
Definition list.hpp:264
const T & ElementAt(integer idx) const
Definition list.hpp:547
std::reverse_iterator< ConstIterator > ConstReverseIterator
Definition list.hpp:250
List(MonoAllocator *pAllocator)
Definition list.hpp:347
ConstReverseIterator crend() const
Definition list.hpp:304
Iterator Erase(ConstIterator first, ConstIterator last)
Definition list.hpp:779
ConstIterator begin() const
Definition list.hpp:268
const T & Front() const
Definition list.hpp:577
T & EmplaceBack(TArgs &&... args)
Definition list.hpp:718
Element * allocElement()
Definition list.hpp:102
ReverseIterator rbegin()
Definition list.hpp:284
Iterator Erase(ConstIterator position)
Definition list.hpp:756
MonoAllocator * GetAllocator() const
Definition list.hpp:391
lang::BidiListHelper< Element > list
Definition list.hpp:82
T & PushFront(T &&move)
Definition list.hpp:685
T & PushBack(T &&move)
Definition list.hpp:658
List(const List &copy)
Definition list.hpp:317
TIterator< T > Iterator
Definition list.hpp:247
ALIB_FORCE_INLINE char * Alloc(size_t size, size_t alignment)
#define ALIB_WARNINGS_RESTORE
Definition alib.hpp:715
#define ATMP_EQ( T, TEqual)
Definition tmp.hpp:32
#define ALIB_ASSERT_ERROR(cond,...)
Definition alib.hpp:984
#define ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE
Definition alib.hpp:644
#define ATMP_SELECT_IF_1TP(TParam, ...)
Definition tmp.hpp:57
#define ATMP_T_IF(T, Cond)
Definition tmp.hpp:53
static ALIB_FORCE_INLINE void Destruct(T *object)
Definition alib.cpp:57
monomem::List< T, TRecycling > List
Type alias in namespace alib.
Definition list.hpp:829
lang::integer integer
Type alias in namespace alib.
Definition integers.hpp:286
void addBefore(TElement *elem)
Definition bidilist.hpp:93
TElement * prev() const
Definition bidilist.hpp:85
void next(SidiNodeBase *p)
Definition sidilist.hpp:107
TIterator operator--(int)
Definition list.hpp:217
std::bidirectional_iterator_tag iterator_category
Implementation of std::iterator_traits.
Definition list.hpp:128
TConstOrMutableElement * operator->() const
Definition list.hpp:235
TIterator(const TMutable &mutableIt)
TConstOrMutableElement value_type
Implementation of std::iterator_traits.
Definition list.hpp:129
TIterator operator++(int)
Definition list.hpp:181
bool operator==(TIterator other) const
Definition list.hpp:192
bool operator!=(TIterator other) const
Definition list.hpp:200
Element * element
The actual element of the list.
Definition list.hpp:135
TConstOrMutableElement * pointer
Implementation of std::iterator_traits.
Definition list.hpp:131
TConstOrMutableElement & operator*() const
Definition list.hpp:228
integer difference_type
Implementation of std::iterator_traits.
Definition list.hpp:130
TConstOrMutableElement & reference
Implementation of std::iterator_traits.
Definition list.hpp:132
TIterator(Element *start)
Definition list.hpp:149
T data
The custom data object.
Definition list.hpp:35