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