moved requires into asserts, cleanup and implemented operator= in const_list.h

This commit is contained in:
Patrick 2024-01-27 19:35:50 +01:00
parent 2115cc39be
commit ad406e9647
1 changed files with 52 additions and 22 deletions

View File

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