| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- // Copyright (c) 2018-2025 Jean-Louis Leroy
- // Distributed under the Boost Software License, Version 1.0.
- // See accompanying file LICENSE_1_0.txt
- // or copy at http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_OPENMETHOD_DETAIL_STATIC_LIST_HPP
- #define BOOST_OPENMETHOD_DETAIL_STATIC_LIST_HPP
- #include <algorithm>
- #include <boost/assert.hpp>
- namespace boost::openmethod {
- namespace detail {
- template<typename T>
- class static_list {
- public:
- static_list(static_list&) = delete;
- static_list() = default;
- class static_link {
- public:
- static_link(const static_link&) = delete;
- static_link() = default;
- auto next() -> T* {
- return next_ptr;
- }
- protected:
- friend class static_list;
- T* prev_ptr;
- T* next_ptr;
- };
- void push_back(T& node) {
- BOOST_ASSERT(node.prev_ptr == nullptr);
- BOOST_ASSERT(node.next_ptr == nullptr);
- if (!first) {
- first = &node;
- node.prev_ptr = &node;
- return;
- }
- auto last = first->prev_ptr;
- last->next_ptr = &node;
- node.prev_ptr = last;
- first->prev_ptr = &node;
- }
- void remove(T& node) {
- BOOST_ASSERT(first != nullptr);
- auto prev = node.prev_ptr;
- auto next = node.next_ptr;
- auto last = first->prev_ptr;
- node.prev_ptr = nullptr;
- node.next_ptr = nullptr;
- if (&node == last) {
- if (&node == first) {
- first = nullptr;
- return;
- }
- first->prev_ptr = prev;
- prev->next_ptr = nullptr;
- return;
- }
- if (&node == first) {
- first = next;
- first->prev_ptr = last;
- return;
- }
- prev->next_ptr = next;
- next->prev_ptr = prev;
- }
- void clear() {
- auto next = first;
- first = nullptr;
- while (next) {
- auto cur = next;
- next = cur->next_ptr;
- cur->prev_ptr = nullptr;
- cur->next_ptr = nullptr;
- }
- }
- class iterator {
- public:
- using iterator_category = std::forward_iterator_tag;
- using difference_type = std::ptrdiff_t;
- using value_type = T;
- using pointer = value_type*;
- using reference = value_type&;
- iterator() : ptr(nullptr) {
- }
- explicit iterator(T* p) : ptr(p) {
- }
- auto operator*() -> reference {
- return *ptr;
- }
- auto operator->() -> pointer {
- return ptr;
- }
- auto operator++() -> iterator& {
- BOOST_ASSERT(ptr);
- ptr = ptr->next_ptr;
- return *this;
- }
- auto operator++(int) -> iterator {
- auto tmp = *this;
- ++(*this);
- return tmp;
- }
- friend auto operator==(const iterator& a, const iterator& b) -> bool {
- return a.ptr == b.ptr;
- };
- friend auto operator!=(const iterator& a, const iterator& b) -> bool {
- return a.ptr != b.ptr;
- };
- private:
- T* ptr;
- };
- auto begin() -> iterator {
- return iterator(first);
- }
- auto end() -> iterator {
- return iterator(nullptr);
- }
- class const_iterator {
- public:
- using iterator_category = std::forward_iterator_tag;
- using difference_type = std::ptrdiff_t;
- using value_type = const T;
- using pointer = value_type*;
- using reference = value_type&;
- const_iterator() : ptr(nullptr) {
- }
- explicit const_iterator(T* p) : ptr(p) {
- }
- auto operator*() -> reference {
- return *ptr;
- }
- auto operator->() -> pointer {
- return ptr;
- }
- auto operator++() -> const_iterator& {
- BOOST_ASSERT(ptr);
- ptr = ptr->next_ptr;
- return *this;
- }
- auto operator++(int) -> const_iterator {
- auto tmp = *this;
- ++(*this);
- return tmp;
- }
- friend auto
- operator==(const const_iterator& a, const const_iterator& b) -> bool {
- return a.ptr == b.ptr;
- };
- friend auto
- operator!=(const const_iterator& a, const const_iterator& b) -> bool {
- return a.ptr != b.ptr;
- };
- private:
- T* ptr;
- };
- auto begin() const -> const_iterator {
- return const_iterator(first);
- }
- auto end() const -> const_iterator {
- return const_iterator(nullptr);
- }
- auto size() const -> std::size_t {
- return std::distance(begin(), end());
- }
- auto empty() const -> bool {
- return !first;
- }
- protected:
- T* first;
- };
- } // namespace detail
- } // namespace boost::openmethod
- #endif
|