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
25namespace beast {
26
27template <typename, typename>
28class List;
29
30namespace detail {
31
34template <typename T, typename U>
36{
37 explicit CopyConst() = default;
38
40};
41
42template <typename T, typename U>
43struct CopyConst<T const, U>
44{
45 explicit CopyConst() = default;
46
47 using type = typename std::remove_const<U>::type const;
48};
51// This is the intrusive portion of the doubly linked list.
52// One derivation per list that the object may appear on
53// concurrently is required.
54//
55template <typename T, typename Tag>
57{
58private:
59 using value_type = T;
60
61 friend class List<T, Tag>;
62
63 template <typename>
64 friend class ListIterator;
65
68};
69
70//------------------------------------------------------------------------------
71
72template <typename N>
74{
75public:
77 using value_type =
83
84 ListIterator(N* node = nullptr) noexcept : m_node(node)
85 {
86 }
87
88 template <typename M>
89 ListIterator(ListIterator<M> const& other) noexcept : m_node(other.m_node)
90 {
91 }
92
93 template <typename M>
94 bool
95 operator==(ListIterator<M> const& other) const noexcept
96 {
97 return m_node == other.m_node;
98 }
99
100 template <typename M>
101 bool
102 operator!=(ListIterator<M> const& other) const noexcept
103 {
104 return !((*this) == other);
105 }
106
108 operator*() const noexcept
109 {
110 return dereference();
111 }
112
113 pointer
114 operator->() const noexcept
115 {
116 return &dereference();
117 }
118
120 operator++() noexcept
121 {
122 increment();
123 return *this;
124 }
125
127 operator++(int) noexcept
128 {
129 ListIterator result(*this);
130 increment();
131 return result;
132 }
133
135 operator--() noexcept
136 {
137 decrement();
138 return *this;
139 }
140
142 operator--(int) noexcept
143 {
144 ListIterator result(*this);
145 decrement();
146 return result;
147 }
148
149private:
151 dereference() const noexcept
152 {
153 return static_cast<reference>(*m_node);
154 }
155
156 void
157 increment() noexcept
158 {
159 m_node = m_node->m_next;
160 }
161
162 void
163 decrement() noexcept
164 {
165 m_node = m_node->m_prev;
166 }
167
169};
170
171} // namespace detail
172
277template <typename T, typename Tag = void>
278class List
279{
280public:
282
283 using value_type = T;
286 using const_pointer = value_type const*;
290
293
296 {
297 m_head.m_prev = nullptr; // identifies the head
298 m_tail.m_next = nullptr; // identifies the tail
299 clear();
300 }
301
302 List(List const&) = delete;
303 List&
304 operator=(List const&) = delete;
305
309 bool
310 empty() const noexcept
311 {
312 return size() == 0;
313 }
314
317 size() const noexcept
318 {
319 return m_size;
320 }
321
327 front() noexcept
328 {
329 return element_from(m_head.m_next);
330 }
331
337 front() const noexcept
338 {
339 return element_from(m_head.m_next);
340 }
341
347 back() noexcept
348 {
349 return element_from(m_tail.m_prev);
350 }
351
357 back() const noexcept
358 {
359 return element_from(m_tail.m_prev);
360 }
361
366 begin() noexcept
367 {
368 return iterator(m_head.m_next);
369 }
370
375 begin() const noexcept
376 {
377 return const_iterator(m_head.m_next);
378 }
379
384 cbegin() const noexcept
385 {
386 return const_iterator(m_head.m_next);
387 }
388
393 end() noexcept
394 {
395 return iterator(&m_tail);
396 }
397
402 end() const noexcept
403 {
404 return const_iterator(&m_tail);
405 }
406
411 cend() const noexcept
412 {
413 return const_iterator(&m_tail);
414 }
415
419 void
420 clear() noexcept
421 {
422 m_head.m_next = &m_tail;
423 m_tail.m_prev = &m_head;
424 m_size = 0;
425 }
426
434 insert(iterator pos, T& element) noexcept
435 {
436 Node* node = static_cast<Node*>(&element);
437 node->m_next = &*pos;
438 node->m_prev = node->m_next->m_prev;
439 node->m_next->m_prev = node;
440 node->m_prev->m_next = node;
441 ++m_size;
442 return iterator(node);
443 }
444
450 void
451 insert(iterator pos, List& other) noexcept
452 {
453 if (!other.empty())
454 {
455 Node* before = &*pos;
456 other.m_head.m_next->m_prev = before->m_prev;
457 before->m_prev->m_next = other.m_head.m_next;
458 other.m_tail.m_prev->m_next = before;
459 before->m_prev = other.m_tail.m_prev;
460 m_size += other.m_size;
461 other.clear();
462 }
463 }
464
471 erase(iterator pos) noexcept
472 {
473 Node* node = &*pos;
474 ++pos;
475 node->m_next->m_prev = node->m_prev;
476 node->m_prev->m_next = node->m_next;
477 --m_size;
478 return pos;
479 }
480
486 push_front(T& element) noexcept
487 {
488 return insert(begin(), element);
489 }
490
495 T&
496 pop_front() noexcept
497 {
498 T& element(front());
499 erase(begin());
500 return element;
501 }
502
508 push_back(T& element) noexcept
509 {
510 return insert(end(), element);
511 }
512
517 T&
518 pop_back() noexcept
519 {
520 T& element(back());
521 erase(--end());
522 return element;
523 }
524
526 void
527 swap(List& other) noexcept
528 {
529 List temp;
530 temp.append(other);
531 other.append(*this);
532 append(temp);
533 }
534
540 prepend(List& list) noexcept
541 {
542 return insert(begin(), list);
543 }
544
550 append(List& list) noexcept
551 {
552 return insert(end(), list);
553 }
554
561 iterator_to(T& element) const noexcept
562 {
563 return iterator(static_cast<Node*>(&element));
564 }
565
572 const_iterator_to(T const& element) const noexcept
573 {
574 return const_iterator(static_cast<Node const*>(&element));
575 }
576
577private:
579 element_from(Node* node) noexcept
580 {
581 return *(static_cast<pointer>(node));
582 }
583
585 element_from(Node const* node) const noexcept
586 {
587 return *(static_cast<const_pointer>(node));
588 }
589
590private:
594};
595
596} // namespace beast
597
598#endif
Intrusive doubly linked list.
Definition List.h:279
value_type const * const_pointer
Definition List.h:286
Node m_head
Definition List.h:592
iterator iterator_to(T &element) const noexcept
Obtain an iterator from an element.
Definition List.h:561
detail::ListIterator< Node const > const_iterator
Definition List.h:292
Node m_tail
Definition List.h:593
std::size_t size_type
Definition List.h:288
iterator push_back(T &element) noexcept
Append an element at the end of the list.
Definition List.h:508
const_iterator begin() const noexcept
Obtain a const iterator to the beginning of the list.
Definition List.h:375
List & operator=(List const &)=delete
const_iterator cend() const noexcept
Obtain a const iterator to the end of the list.
Definition List.h:411
reference front() noexcept
Obtain a reference to the first element.
Definition List.h:327
void clear() noexcept
Clear the list.
Definition List.h:420
void insert(iterator pos, List &other) noexcept
Insert another list into this one.
Definition List.h:451
iterator begin() noexcept
Obtain an iterator to the beginning of the list.
Definition List.h:366
const_reference back() const noexcept
Obtain a const reference to the last element.
Definition List.h:357
detail::ListIterator< Node > iterator
Definition List.h:291
iterator insert(iterator pos, T &element) noexcept
Insert an element.
Definition List.h:434
iterator append(List &list) noexcept
Append another list at the end of this list.
Definition List.h:550
T value_type
Definition List.h:283
iterator end() noexcept
Obtain a iterator to the end of the list.
Definition List.h:393
const_reference element_from(Node const *node) const noexcept
Definition List.h:585
value_type * pointer
Definition List.h:284
const_reference front() const noexcept
Obtain a const reference to the first element.
Definition List.h:337
reference back() noexcept
Obtain a reference to the last element.
Definition List.h:347
const_iterator end() const noexcept
Obtain a const iterator to the end of the list.
Definition List.h:402
T & pop_back() noexcept
Remove the element at the end of the list.
Definition List.h:518
typename detail::ListNode< T, Tag > Node
Definition List.h:281
bool empty() const noexcept
Determine if the list is empty.
Definition List.h:310
void swap(List &other) noexcept
Swap contents with another list.
Definition List.h:527
value_type & reference
Definition List.h:285
const_iterator const_iterator_to(T const &element) const noexcept
Obtain a const iterator from an element.
Definition List.h:572
List(List const &)=delete
T & pop_front() noexcept
Remove the element at the beginning of the list.
Definition List.h:496
iterator push_front(T &element) noexcept
Insert an element at the beginning of the list.
Definition List.h:486
value_type const & const_reference
Definition List.h:287
size_type size() const noexcept
Returns the number of elements in the list.
Definition List.h:317
const_iterator cbegin() const noexcept
Obtain a const iterator to the beginning of the list.
Definition List.h:384
List()
Create an empty list.
Definition List.h:295
reference element_from(Node *node) noexcept
Definition List.h:579
iterator erase(iterator pos) noexcept
Remove an element.
Definition List.h:471
iterator prepend(List &list) noexcept
Insert another list at the beginning of this list.
Definition List.h:540
size_type m_size
Definition List.h:591
ListIterator & operator++() noexcept
Definition List.h:120
ListIterator & operator--() noexcept
Definition List.h:135
value_type * pointer
Definition List.h:80
reference operator*() const noexcept
Definition List.h:108
ListIterator operator++(int) noexcept
Definition List.h:127
typename beast::detail::CopyConst< N, typename N::value_type >::type value_type
Definition List.h:78
void decrement() noexcept
Definition List.h:163
reference dereference() const noexcept
Definition List.h:151
ListIterator operator--(int) noexcept
Definition List.h:142
bool operator!=(ListIterator< M > const &other) const noexcept
Definition List.h:102
value_type & reference
Definition List.h:81
pointer operator->() const noexcept
Definition List.h:114
bool operator==(ListIterator< M > const &other) const noexcept
Definition List.h:95
void increment() noexcept
Definition List.h:157
ListIterator(ListIterator< M > const &other) noexcept
Definition List.h:89
ListIterator(N *node=nullptr) noexcept
Definition List.h:84
ListNode * m_next
Definition List.h:66
ListNode * m_prev
Definition List.h:67
typename std::remove_const< U >::type const type
Definition List.h:47
Copy const attribute from T to U if present.
Definition List.h:36
typename std::remove_const< U >::type type
Definition List.h:39