diff --git a/include/const_list.h b/include/const_list.h index 4e560fa..55f45f9 100644 --- a/include/const_list.h +++ b/include/const_list.h @@ -8,8 +8,6 @@ #include #include #include -#include "allocator.h" -#include "CompileOptional.h" namespace cc { @@ -17,13 +15,12 @@ namespace cc { class const_list_node; template - requires std::derived_from> class _const_list_iterator_base { protected: - N *_curr; + N *_curr = nullptr; public: - constexpr _const_list_iterator_base() noexcept : _curr() {} + constexpr _const_list_iterator_base() noexcept = default; constexpr explicit _const_list_iterator_base(N *curr) noexcept : _curr(curr) {} constexpr _const_list_iterator_base(const _const_list_iterator_base& other) noexcept : _curr(other._curr) {} @@ -32,8 +29,8 @@ namespace cc { constexpr virtual _const_list_iterator_base &operator++() noexcept = 0; constexpr virtual _const_list_iterator_base &operator--() noexcept = 0; - constexpr virtual _const_list_iterator_base operator++(int) & noexcept = 0; - constexpr virtual _const_list_iterator_base operator--(int) & noexcept = 0; + constexpr virtual _const_list_iterator_base &operator++(int) & noexcept = 0; + constexpr virtual _const_list_iterator_base &operator--(int) & noexcept = 0; constexpr bool operator==(const _const_list_iterator_base &other) { return _curr == other._curr; } }; @@ -70,8 +67,11 @@ namespace cc { }; template - requires std::derived_from> class const_list { + private: + static consteval void asserts() { + static_assert(std::is_base_of_v, Node>, "Can only create const_list with elements derived from const_list_node"); + } public: @@ -94,16 +94,16 @@ namespace cc { public: - constexpr const_list() noexcept = default; + constexpr const_list() noexcept { asserts(); }; constexpr const_list(const const_list&) = delete; constexpr const_list(const_list&& other) noexcept; constexpr const_list(std::initializer_list> init) noexcept; constexpr ~const_list(); - constexpr const_list& operator=(const const_list& other); - constexpr const_list& operator=(const_list&& other); - constexpr const_list& operator=(std::initializer_list init); + constexpr const_list& operator=(const const_list&) = delete; + constexpr const_list& operator=(const_list&& other) noexcept; + constexpr const_list& operator=(std::initializer_list> init) noexcept; constexpr void assign(size_type count, const value_type& value) noexcept; template @@ -203,16 +203,22 @@ namespace cc { template class const_list_node { - static_assert(std::is_base_of_v, D>); + private: + static consteval void asserts() { + static_assert(std::is_base_of_v, D>, "Template parameter has to be a subclass of const_list_node<*self*>"); + } + private: const_list_node *_prev = nullptr; const_list_node *_next = nullptr; const_list *_owner = nullptr; + public: + constexpr const_list_node() noexcept { asserts(); } virtual constexpr ~const_list_node(); - friend class const_list; - friend class _const_list_iterator_base; + friend class const_list; + friend class _const_list_iterator_base; }; template @@ -249,28 +255,32 @@ namespace cc { } template - requires std::derived_from> constexpr const_list::const_list(const_list &&other) noexcept : _start(other._start), _end(other._end), _size(other._size) { + asserts(); + for (auto node : other) { node._owner = this; } + other._size = 0; other._start = nullptr; other._end = nullptr; } template - requires std::derived_from> constexpr const_list::const_list(std::initializer_list> init) noexcept - : _start(std::addressof(*init.begin())), - _end(std::addressof(*(--init.begin()))), + : _start(std::addressof(init.begin()->get())), + _end(std::addressof(std::prev(init.end())->get())), _size(init.size()) { + asserts(); + auto prev = init.begin(); prev->get()._owner = this; - for (auto it = ++init.begin(); it != init.end(); ++it) { + + for (auto it = std::next(init.begin()); it != init.end(); ++it) { prev->get()._next = std::addressof(it->get()); it->get()._prev = std::addressof(prev->get()); it->get()._owner = this; @@ -280,14 +290,34 @@ namespace cc { } template - requires std::derived_from> constexpr const_list::~const_list() { clear(); } + template + constexpr const_list &const_list::operator=(const_list &&other) noexcept + { + for (auto node : other) { + node._owner = this; + } - template + other._size = 0; + other._start = nullptr; + other._end = nullptr; + + return *this; + } + + template + constexpr const_list &const_list::operator=(std::initializer_list> init) noexcept + { + *this = const_list(init); + return *this; + } + + + template constexpr const_list_node::~const_list_node() { _owner->remove(*this);