diff --git a/include/stdx/detail/list_common.hpp b/include/stdx/detail/list_common.hpp index 2b4f3a7..9cbe5dd 100644 --- a/include/stdx/detail/list_common.hpp +++ b/include/stdx/detail/list_common.hpp @@ -23,13 +23,13 @@ concept base_double_linkable = base_single_linkable and requires(T node) { } // namespace detail template -concept single_linkable = not complete or requires(T *node) { +concept single_linkable = requires(T *node) { requires detail::base_single_linkable< std::remove_cvref_tnext)>>; }; template -concept double_linkable = not complete or requires(T *node) { +concept double_linkable = requires(T *node) { requires detail::base_double_linkable< std::remove_cvref_tnext)>>; requires detail::base_double_linkable< @@ -46,6 +46,7 @@ constexpr auto namespace node_policy { template class checked { constexpr static auto valid_for_push(Node *node) -> bool { + static_assert(single_linkable); if constexpr (detail::detect::has_prev_pointer) { return node->prev == nullptr and node->next == nullptr; } else { @@ -79,6 +80,7 @@ template class checked { } constexpr static auto on_pop(Node *node) { + static_assert(single_linkable); if constexpr (detail::detect::has_prev_pointer) { node->prev = nullptr; } @@ -86,6 +88,7 @@ template class checked { } constexpr static auto on_clear(Node *head) { + static_assert(single_linkable); while (head != nullptr) { if constexpr (detail::detect::has_prev_pointer) { head->prev = nullptr; diff --git a/include/stdx/intrusive_forward_list.hpp b/include/stdx/intrusive_forward_list.hpp index ee32364..3819ee6 100644 --- a/include/stdx/intrusive_forward_list.hpp +++ b/include/stdx/intrusive_forward_list.hpp @@ -6,7 +6,7 @@ namespace stdx { inline namespace v1 { -template typename P = node_policy::checked> class intrusive_forward_list { friend P; @@ -58,6 +58,7 @@ class intrusive_forward_list { pointer tail{}; constexpr auto unchecked_push_front(pointer n) -> void { + static_assert(single_linkable); n->next = head; head = n; if (tail == nullptr) { @@ -66,6 +67,7 @@ class intrusive_forward_list { } constexpr auto unchecked_push_back(pointer n) -> void { + static_assert(single_linkable); if (tail != nullptr) { tail->next = n; } @@ -99,6 +101,7 @@ class intrusive_forward_list { } constexpr auto pop_front() -> pointer { + static_assert(single_linkable); pointer poppedNode = head; head = head->next; diff --git a/include/stdx/intrusive_list.hpp b/include/stdx/intrusive_list.hpp index 1a42bae..2f8ccd4 100644 --- a/include/stdx/intrusive_list.hpp +++ b/include/stdx/intrusive_list.hpp @@ -6,7 +6,7 @@ namespace stdx { inline namespace v1 { -template typename P = node_policy::checked> class intrusive_list { friend P; @@ -58,6 +58,7 @@ class intrusive_list { pointer tail{}; constexpr auto unchecked_push_front(pointer n) -> void { + static_assert(double_linkable); if (head != nullptr) { head->prev = n; } @@ -70,6 +71,7 @@ class intrusive_list { } constexpr auto unchecked_push_back(pointer n) -> void { + static_assert(double_linkable); if (tail != nullptr) { tail->next = n; } @@ -82,6 +84,7 @@ class intrusive_list { } constexpr auto unchecked_insert(iterator it, pointer n) -> void { + static_assert(double_linkable); if (it != end()) { auto p = it.operator->(); n->next = p; @@ -128,6 +131,7 @@ class intrusive_list { } constexpr auto pop_front() -> pointer { + static_assert(double_linkable); pointer poppedNode = head; head = head->next; @@ -142,6 +146,7 @@ class intrusive_list { } constexpr auto pop_back() -> pointer { + static_assert(double_linkable); pointer poppedNode = tail; tail = tail->prev; @@ -166,6 +171,7 @@ class intrusive_list { } constexpr auto remove(pointer n) -> void { + static_assert(double_linkable); pointer nextNode = n->next; pointer prevNode = n->prev;