rippled
Loading...
Searching...
No Matches
List.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of Beast: https://github.com/vinniefalco/Beast
4 Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef BEAST_INTRUSIVE_LIST_H_INCLUDED
21#define BEAST_INTRUSIVE_LIST_H_INCLUDED
22
23#include <iterator>
24#include <type_traits>
25
26namespace beast {
27
28template <typename, typename>
29class List;
30
31namespace detail {
32
35template <typename T, typename U>
37{
38 explicit CopyConst() = default;
39
41};
42
43template <typename T, typename U>
44struct CopyConst<T const, U>
45{
46 explicit CopyConst() = default;
47
48 using type = typename std::remove_const<U>::type const;
49};
52// This is the intrusive portion of the doubly linked list.
53// One derivation per list that the object may appear on
54// concurrently is required.
55//
56template <typename T, typename Tag>
58{
59private:
60 using value_type = T;
61
62 friend class List<T, Tag>;
63
64 template <typename>
65 friend class ListIterator;
66
69};
70
71//------------------------------------------------------------------------------
72
73template <typename N>
75{
76public:
78 using value_type =
84
85 ListIterator(N* node = nullptr) noexcept : m_node(node)
86 {
87 }
88
89 template <typename M>
90 ListIterator(ListIterator<M> const& other) noexcept : m_node(other.m_node)
91 {
92 }
93
94 template <typename M>
95 bool
96 operator==(ListIterator<M> const& other) const noexcept
97 {
98 return m_node == other.m_node;
99 }
100
101 template <typename M>
102 bool
103 operator!=(ListIterator<M> const& other) const noexcept
104 {
105 return !((*this) == other);
106 }
107
109 operator*() const noexcept
110 {
111 return dereference();
112 }
113
114 pointer
115 operator->() const noexcept
116 {
117 return &dereference();
118 }
119
121 operator++() noexcept
122 {
123 increment();
124 return *this;
125 }
126
128 operator++(int) noexcept
129 {
130 ListIterator result(*this);
131 increment();
132 return result;
133 }
134
136 operator--() noexcept
137 {
138 decrement();
139 return *this;
140 }
141
143 operator--(int) noexcept
144 {
145 ListIterator result(*this);
146 decrement();
147 return result;
148 }
149
150private:
152 dereference() const noexcept
153 {
154 return static_cast<reference>(*m_node);
155 }
156
157 void
158 increment() noexcept
159 {
160 m_node = m_node->m_next;
161 }
162
163 void
164 decrement() noexcept
165 {
166 m_node = m_node->m_prev;
167 }
168
170};
171
172} // namespace detail
173
278template <typename T, typename Tag = void>
279class List
280{
281public:
283
284 using value_type = T;
287 using const_pointer = value_type const*;
291
294
297 {
298 m_head.m_prev = nullptr; // identifies the head
299 m_tail.m_next = nullptr; // identifies the tail
300 clear();
301 }
302
303 List(List const&) = delete;
304 List&
305 operator=(List const&) = delete;
306
310 bool
311 empty() const noexcept
312 {
313 return size() == 0;
314 }
315
318 size() const noexcept
319 {
320 return m_size;
321 }
322
328 front() noexcept
329 {
330 return element_from(m_head.m_next);
331 }
332
338 front() const noexcept
339 {
340 return element_from(m_head.m_next);
341 }
342
348 back() noexcept
349 {
350 return element_from(m_tail.m_prev);
351 }
352
358 back() const noexcept
359 {
360 return element_from(m_tail.m_prev);
361 }
362
367 begin() noexcept
368 {
369 return iterator(m_head.m_next);
370 }
371
376 begin() const noexcept
377 {
378 return const_iterator(m_head.m_next);
379 }
380
385 cbegin() const noexcept
386 {
387 return const_iterator(m_head.m_next);
388 }
389
394 end() noexcept
395 {
396 return iterator(&m_tail);
397 }
398
403 end() const noexcept
404 {
405 return const_iterator(&m_tail);
406 }
407
412 cend() const noexcept
413 {
414 return const_iterator(&m_tail);
415 }
416
420 void
421 clear() noexcept
422 {
423 m_head.m_next = &m_tail;
424 m_tail.m_prev = &m_head;
425 m_size = 0;
426 }
427
435 insert(iterator pos, T& element) noexcept
436 {
437 Node* node = static_cast<Node*>(&element);
438 node->m_next = &*pos;
439 node->m_prev = node->m_next->m_prev;
440 node->m_next->m_prev = node;
441 node->m_prev->m_next = node;
442 ++m_size;
443 return iterator(node);
444 }
445
451 void
452 insert(iterator pos, List& other) noexcept
453 {
454 if (!other.empty())
455 {
456 Node* before = &*pos;
457 other.m_head.m_next->m_prev = before->m_prev;
458 before->m_prev->m_next = other.m_head.m_next;
459 other.m_tail.m_prev->m_next = before;
460 before->m_prev = other.m_tail.m_prev;
461 m_size += other.m_size;
462 other.clear();
463 }
464 }
465
472 erase(iterator pos) noexcept
473 {
474 Node* node = &*pos;
475 ++pos;
476 node->m_next->m_prev = node->m_prev;
477 node->m_prev->m_next = node->m_next;
478 --m_size;
479 return pos;
480 }
481
487 push_front(T& element) noexcept
488 {
489 return insert(begin(), element);
490 }
491
496 T&
497 pop_front() noexcept
498 {
499 T& element(front());
500 erase(begin());
501 return element;
502 }
503
509 push_back(T& element) noexcept
510 {
511 return insert(end(), element);
512 }
513
518 T&
519 pop_back() noexcept
520 {
521 T& element(back());
522 erase(--end());
523 return element;
524 }
525
527 void
528 swap(List& other) noexcept
529 {
530 List temp;
531 temp.append(other);
532 other.append(*this);
533 append(temp);
534 }
535
541 prepend(List& list) noexcept
542 {
543 return insert(begin(), list);
544 }
545
551 append(List& list) noexcept
552 {
553 return insert(end(), list);
554 }
555
562 iterator_to(T& element) const noexcept
563 {
564 return iterator(static_cast<Node*>(&element));
565 }
566
573 const_iterator_to(T const& element) const noexcept
574 {
575 return const_iterator(static_cast<Node const*>(&element));
576 }
577
578private:
580 element_from(Node* node) noexcept
581 {
582 return *(static_cast<pointer>(node));
583 }
584
586 element_from(Node const* node) const noexcept
587 {
588 return *(static_cast<const_pointer>(node));
589 }
590
591private:
595};
596
597} // namespace beast
598
599#endif
Intrusive doubly linked list.
Definition: List.h:280
value_type const * const_pointer
Definition: List.h:287
Node m_head
Definition: List.h:593
iterator iterator_to(T &element) const noexcept
Obtain an iterator from an element.
Definition: List.h:562
detail::ListIterator< Node const > const_iterator
Definition: List.h:293
Node m_tail
Definition: List.h:594
std::size_t size_type
Definition: List.h:289
iterator push_back(T &element) noexcept
Append an element at the end of the list.
Definition: List.h:509
const_iterator begin() const noexcept
Obtain a const iterator to the beginning of the list.
Definition: List.h:376
List & operator=(List const &)=delete
const_iterator cend() const noexcept
Obtain a const iterator to the end of the list.
Definition: List.h:412
reference front() noexcept
Obtain a reference to the first element.
Definition: List.h:328
void clear() noexcept
Clear the list.
Definition: List.h:421
void insert(iterator pos, List &other) noexcept
Insert another list into this one.
Definition: List.h:452
iterator begin() noexcept
Obtain an iterator to the beginning of the list.
Definition: List.h:367
const_reference back() const noexcept
Obtain a const reference to the last element.
Definition: List.h:358
detail::ListIterator< Node > iterator
Definition: List.h:292
iterator insert(iterator pos, T &element) noexcept
Insert an element.
Definition: List.h:435
iterator append(List &list) noexcept
Append another list at the end of this list.
Definition: List.h:551
T value_type
Definition: List.h:284
iterator end() noexcept
Obtain a iterator to the end of the list.
Definition: List.h:394
const_reference element_from(Node const *node) const noexcept
Definition: List.h:586
value_type * pointer
Definition: List.h:285
const_reference front() const noexcept
Obtain a const reference to the first element.
Definition: List.h:338
reference back() noexcept
Obtain a reference to the last element.
Definition: List.h:348
const_iterator end() const noexcept
Obtain a const iterator to the end of the list.
Definition: List.h:403
T & pop_back() noexcept
Remove the element at the end of the list.
Definition: List.h:519
typename detail::ListNode< T, Tag > Node
Definition: List.h:282
bool empty() const noexcept
Determine if the list is empty.
Definition: List.h:311
void swap(List &other) noexcept
Swap contents with another list.
Definition: List.h:528
value_type & reference
Definition: List.h:286
const_iterator const_iterator_to(T const &element) const noexcept
Obtain a const iterator from an element.
Definition: List.h:573
List(List const &)=delete
T & pop_front() noexcept
Remove the element at the beginning of the list.
Definition: List.h:497
iterator push_front(T &element) noexcept
Insert an element at the beginning of the list.
Definition: List.h:487
value_type const & const_reference
Definition: List.h:288
size_type size() const noexcept
Returns the number of elements in the list.
Definition: List.h:318
const_iterator cbegin() const noexcept
Obtain a const iterator to the beginning of the list.
Definition: List.h:385
List()
Create an empty list.
Definition: List.h:296
reference element_from(Node *node) noexcept
Definition: List.h:580
iterator erase(iterator pos) noexcept
Remove an element.
Definition: List.h:472
iterator prepend(List &list) noexcept
Insert another list at the beginning of this list.
Definition: List.h:541
size_type m_size
Definition: List.h:592
ListIterator & operator++() noexcept
Definition: List.h:121
ListIterator & operator--() noexcept
Definition: List.h:136
value_type * pointer
Definition: List.h:81
reference operator*() const noexcept
Definition: List.h:109
ListIterator operator++(int) noexcept
Definition: List.h:128
typename beast::detail::CopyConst< N, typename N::value_type >::type value_type
Definition: List.h:79
void decrement() noexcept
Definition: List.h:164
reference dereference() const noexcept
Definition: List.h:152
ListIterator operator--(int) noexcept
Definition: List.h:143
bool operator!=(ListIterator< M > const &other) const noexcept
Definition: List.h:103
value_type & reference
Definition: List.h:82
pointer operator->() const noexcept
Definition: List.h:115
bool operator==(ListIterator< M > const &other) const noexcept
Definition: List.h:96
void increment() noexcept
Definition: List.h:158
ListIterator(ListIterator< M > const &other) noexcept
Definition: List.h:90
ListIterator(N *node=nullptr) noexcept
Definition: List.h:85
ListNode * m_next
Definition: List.h:67
ListNode * m_prev
Definition: List.h:68
typename std::remove_const< U >::type const type
Definition: List.h:48
Copy const attribute from T to U if present.
Definition: List.h:37
typename std::remove_const< U >::type type
Definition: List.h:40