From fa1284d7ed3bb32bc1ab26145f0472897904d4b7 Mon Sep 17 00:00:00 2001 From: jwellbelove Date: Mon, 25 Jan 2016 12:37:41 +0000 Subject: [PATCH] Partial update. Added link_after to forward_link. Added SAFE option to bidirectional_link --- intrusive_links.h | 111 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 4 deletions(-) diff --git a/intrusive_links.h b/intrusive_links.h index 6c373eae..e2f380dd 100644 --- a/intrusive_links.h +++ b/intrusive_links.h @@ -33,6 +33,11 @@ SOFTWARE. #include "nullptr.h" #include "type_traits.h" +#include "exception.h" +#include "error_handler.h" + +#undef ETL_FILE +#define ETL_FILE "23" namespace etl { @@ -40,11 +45,26 @@ namespace etl { enum { - NO_AUTO_UNLINK = false, - AUTO_UNLINK = true + DEFAULT = 0, + AUTO = 1, + SAFE = 2 }; }; + //*************************************************************************** + /// Deque full exception. + ///\ingroup deque + //*************************************************************************** + class link_exception : public etl::exception + { + public: + + link_exception(string_type file_name, numeric_type line_number) + : exception(ETL_ERROR_TEXT("link:still linked", ETL_FILE"A"), file_name, line_number) + { + } + }; + //*************************************************************************** /// A forward link. //*************************************************************************** @@ -72,6 +92,15 @@ namespace etl lhs.etl_next = &rhs; } + // Reference, Reference + template + typename etl::enable_if >::value, void>::type + link_insert(TLink& lhs, TLink& rhs) + { + rhs.etl_next = lhs.etl_next; + lhs.etl_next = &rhs; + } + // Pointer, Pointer template typename etl::enable_if >::value, void>::type @@ -83,6 +112,22 @@ namespace etl } } + // Pointer, Pointer + template + typename etl::enable_if >::value, void>::type + link_insert(TLink* lhs, TLink* rhs) + { + if (lhs != nullptr) + { + if (rhs != nullptr) + { + rhs->etl_next = lhs->etl_next; + } + + lhs->etl_next = rhs; + } + } + // Reference, Pointer template typename etl::enable_if >::value, void>::type @@ -91,6 +136,19 @@ namespace etl lhs.etl_next = rhs; } + // Reference, Pointer + template + typename etl::enable_if >::value, void>::type + link_insert(TLink& lhs, TLink* rhs) + { + if (rhs != nullptr) + { + rhs->etl_next = lhs.etl_next; + } + + lhs.etl_next = rhs; + } + // Pointer, Reference template typename etl::enable_if >::value, void>::type @@ -102,6 +160,18 @@ namespace etl } } + // Pointer, Reference + template + typename etl::enable_if >::value, void>::type + link_insert(TLink* lhs, TLink& rhs) + { + if (lhs != nullptr) + { + rhs.etl_next = lhs->etl_next; + lhs->etl_next = &rhs; + } + } + // Reference template typename etl::enable_if >::value, void>::type @@ -130,7 +200,7 @@ namespace etl //*************************************************************************** /// A bidirectional link. //*************************************************************************** - template + template struct bidirectional_link { enum @@ -149,10 +219,12 @@ namespace etl bidirectional_link* etl_next; }; + //****************************************************************** // Specialisation for auto unlinked option. // When this link is destroyed it will automatically unlink itself. + //****************************************************************** template - struct bidirectional_link + struct bidirectional_link { enum { @@ -185,6 +257,36 @@ namespace etl bidirectional_link* etl_next; }; + //****************************************************************** + // Specialisation for safe unlinked option. + // An error will be generated if the links are valid when the object + // is destroyed. + //****************************************************************** + template + struct bidirectional_link + { + enum + { + ID = ID_, + OPTION = etl::link_option::AUTO_UNLINK + }; + + ~bidirectional_link() + { + ETL_ASSERT(etl_previous == nullptr, ETL_ERROR(link_exception)); + ETL_ASSERT(etl_next == nullptr, ETL_ERROR(link_exception)); + } + + void clear() + { + etl_previous = nullptr; + etl_next = nullptr; + } + + bidirectional_link* etl_previous; + bidirectional_link* etl_next; + }; + // Reference, Reference template typename etl::enable_if >::value, void>::type @@ -393,4 +495,5 @@ namespace etl } } +#undef ETL_FILE #endif