From c3c12da8616c6bbbe67583c2bf06cee7f2d54f95 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 11 Jun 2023 19:01:43 +0100 Subject: [PATCH] Initial updates and fixes --- include/etl/intrusive_links.h | 153 ++++++++++++++++++++++++++++++++++ include/etl/intrusive_queue.h | 7 +- include/etl/intrusive_stack.h | 5 ++ test/test_intrusive_queue.cpp | 148 +++++++++++++++++++++++++++----- 4 files changed, 290 insertions(+), 23 deletions(-) diff --git a/include/etl/intrusive_links.h b/include/etl/intrusive_links.h index 39504c14..32551aec 100644 --- a/include/etl/intrusive_links.h +++ b/include/etl/intrusive_links.h @@ -91,6 +91,22 @@ namespace etl ID = ID_, }; + forward_link() + : etl_next(ETL_NULLPTR) + { + } + + forward_link(const forward_link& other) + : etl_next(other.etl_next) + { + } + + forward_link& operator =(const forward_link& rhs) + { + etl_next = rhs.etl_next; + return *this; + } + void clear() { etl_next = ETL_NULLPTR; @@ -132,6 +148,38 @@ namespace etl } } + // Reference + template + typename etl::enable_if >::value, void>::type + link_clear(TLink& node) + { + node.clear(); + } + + // Pointer + template + typename etl::enable_if >::value, void>::type + link_clear(TLink* node) + { + node->clear(); + } + + // Reference + template + typename etl::enable_if >::value, bool>::type + link_is_linked(TLink& node) + { + return node.is_linked(); + } + + // Pointer + template + typename etl::enable_if >::value, bool>::type + link_is_linked(TLink* node) + { + return node.is_linked(); + } + // Pointer, Pointer template typename etl::enable_if >::value, void>::type @@ -248,6 +296,25 @@ namespace etl ID = ID_, }; + bidirectional_link() + : etl_previous(ETL_NULLPTR) + , etl_next(ETL_NULLPTR) + { + } + + bidirectional_link(const bidirectional_link& other) + : etl_previous(other.etl_previous) + , etl_next(other.etl_next) + { + } + + bidirectional_link& operator =(const bidirectional_link& rhs) + { + etl_previous = rhs.etl_previous; + etl_next = rhs.etl_next; + return *this; + } + void clear() { etl_previous = ETL_NULLPTR; @@ -465,6 +532,38 @@ namespace etl } } + // Reference + template + typename etl::enable_if >::value, void>::type + link_clear(TLink& node) + { + node.clear(); + } + + // Pointer + template + typename etl::enable_if >::value, void>::type + link_clear(TLink* node) + { + node->clear(); + } + + // Reference + template + typename etl::enable_if >::value, bool>::type + link_is_linked(TLink& node) + { + return node.is_linked(); + } + + // Pointer + template + typename etl::enable_if >::value, bool>::type + link_is_linked(TLink* node) + { + return node.is_linked(); + } + // Reference template typename etl::enable_if >::value, void>::type @@ -507,6 +606,28 @@ namespace etl ID = ID_, }; + tree_link() + : etl_parent(ETL_NULLPTR) + , etl_left(ETL_NULLPTR) + , etl_right(ETL_NULLPTR) + { + } + + tree_link(const tree_link& other) + : etl_parent(other.etl_parent) + , etl_left(other.etl_left) + , etl_right(other.etl_right) + { + } + + tree_link& operator =(const tree_link& rhs) + { + etl_parent = other.etl_parent; + etl_left = other.etl_left; + etl_right = other.etl_right; + return *this; + } + void clear() { etl_parent = ETL_NULLPTR; @@ -790,6 +911,38 @@ namespace etl } } } + + // Reference + template + typename etl::enable_if >::value, void>::type + link_clear(TLink& node) + { + node.clear(); + } + + // Pointer + template + typename etl::enable_if >::value, void>::type + link_clear(TLink* node) + { + node->clear(); + } + + // Reference + template + typename etl::enable_if >::value, bool>::type + link_is_linked(TLink& node) + { + return node.is_linked(); + } + + // Pointer + template + typename etl::enable_if >::value, bool>::type + link_is_linked(TLink* node) + { + return node.is_linked(); + } } #endif diff --git a/include/etl/intrusive_queue.h b/include/etl/intrusive_queue.h index 7268d326..eb12b5fe 100644 --- a/include/etl/intrusive_queue.h +++ b/include/etl/intrusive_queue.h @@ -87,7 +87,10 @@ namespace etl //************************************************************************* void push(link_type& value) { - value.clear(); + //if (value.is_linked()) + //{ + // return; + //} if (p_back != ETL_NULLPTR) { @@ -113,7 +116,7 @@ namespace etl ETL_ASSERT(!empty(), ETL_ERROR(intrusive_queue_empty)); #endif link_type* p_next = p_front->etl_next; - + p_front->clear(); p_front = p_next; // Now empty? diff --git a/include/etl/intrusive_stack.h b/include/etl/intrusive_stack.h index 694a7ed1..267458d9 100644 --- a/include/etl/intrusive_stack.h +++ b/include/etl/intrusive_stack.h @@ -87,6 +87,11 @@ namespace etl //************************************************************************* void push(link_type& value) { + //if (value.is_linked()) + //{ + // return; + //} + value.clear(); if (p_top != ETL_NULLPTR) diff --git a/test/test_intrusive_queue.cpp b/test/test_intrusive_queue.cpp index f48275af..f8ee1ba3 100644 --- a/test/test_intrusive_queue.cpp +++ b/test/test_intrusive_queue.cpp @@ -35,10 +35,10 @@ SOFTWARE. namespace { - typedef etl::forward_link<0> link0; - typedef etl::bidirectional_link<1> link1; + typedef etl::forward_link<0> link_fwd; + typedef etl::bidirectional_link<1> link_bdir; - struct Data : public link0, public link1 + struct Data : public link_fwd, public link_bdir { Data(int i_) : i(i_) @@ -70,8 +70,8 @@ namespace //************************************************************************* TEST(test_constructor) { - etl::intrusive_queue queueD; - etl::intrusive_queue queueC; + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; CHECK(queueD.empty()); CHECK(queueC.empty()); @@ -83,8 +83,8 @@ namespace //************************************************************************* TEST(test_empty) { - etl::intrusive_queue queueD; - etl::intrusive_queue queueC; + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; Data data1(1); Data data2(2); @@ -106,8 +106,8 @@ namespace Data data2(2); Data data3(3); - etl::intrusive_queue queueD; - etl::intrusive_queue queueC; + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; queueD.push(data1); queueD.push(data2); @@ -127,8 +127,8 @@ namespace Data data2(2); Data data3(3); - etl::intrusive_queue queueD; - etl::intrusive_queue queueC; + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; queueD.push(data1); queueD.push(data2); @@ -151,8 +151,8 @@ namespace Data data2(2); Data data3(3); - etl::intrusive_queue queueD; - etl::intrusive_queue queueC; + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; queueD.push(data1); CHECK_EQUAL(queueD.front(), data1); @@ -175,6 +175,48 @@ namespace CHECK_EQUAL(queueC.back(), data2); } + //************************************************************************* + TEST(test_double_push) + { + Data data1(1); + Data data2(2); + Data data3(3); + Data data4(4); + + etl::intrusive_queue queue; + + queue.push(data1); + CHECK(data1.link_fwd::etl_next == ETL_NULLPTR); + CHECK(data2.link_fwd::etl_next == ETL_NULLPTR); + CHECK(data3.link_fwd::etl_next == ETL_NULLPTR); + CHECK(data4.link_fwd::etl_next == ETL_NULLPTR); + + queue.push(data2); + CHECK(data1.link_fwd::etl_next == &data2); + CHECK(data2.link_fwd::etl_next == ETL_NULLPTR); + CHECK(data3.link_fwd::etl_next == ETL_NULLPTR); + CHECK(data4.link_fwd::etl_next == ETL_NULLPTR); + + queue.push(data3); + CHECK(data1.link_fwd::etl_next == &data2); + CHECK(data2.link_fwd::etl_next == &data3); + CHECK(data3.link_fwd::etl_next == ETL_NULLPTR); + CHECK(data4.link_fwd::etl_next == ETL_NULLPTR); + + queue.push(data2); + CHECK(data1.link_fwd::etl_next == &data2); + CHECK(data2.link_fwd::etl_next == &data3); + CHECK(data3.link_fwd::etl_next == ETL_NULLPTR); + CHECK(data4.link_fwd::etl_next == ETL_NULLPTR); + + queue.push(data4); + CHECK(data1.link_fwd::etl_next == &data2); + CHECK(data2.link_fwd::etl_next == &data3); + CHECK(data3.link_fwd::etl_next == &data4); + CHECK(data4.link_fwd::etl_next == ETL_NULLPTR); + + CHECK_EQUAL(4, queue.size()); + } //************************************************************************* TEST(test_pop) @@ -183,8 +225,8 @@ namespace Data data2(2); Data data3(3); - etl::intrusive_queue queueD; - etl::intrusive_queue queueC; + etl::intrusive_queue queueD; + etl::intrusive_queue queueC; queueD.push(data1); queueD.push(data2); @@ -220,8 +262,8 @@ namespace Data data2(2); Data data3(3); - etl::intrusive_queue queue1; - etl::intrusive_queue queue2; + etl::intrusive_queue queue1; + etl::intrusive_queue queue2; queue1.push(data1); queue1.push(data2); @@ -251,6 +293,70 @@ namespace CHECK_EQUAL(data3, queue2.back()); } + //************************************************************************* + TEST(test_pop_forward_link_clear) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_queue queue; + + queue.push(data1); + queue.push(data2); + queue.push(data3); + CHECK_TRUE(data1.link_fwd::etl_next != ETL_NULLPTR); + CHECK_TRUE(data2.link_fwd::etl_next != ETL_NULLPTR); + CHECK_TRUE(data3.link_fwd::etl_next == ETL_NULLPTR); + + queue.pop(); + CHECK_TRUE(data1.link_fwd::etl_next == ETL_NULLPTR); + CHECK_TRUE(data2.link_fwd::etl_next != ETL_NULLPTR); + CHECK_TRUE(data3.link_fwd::etl_next == ETL_NULLPTR); + + queue.pop(); + CHECK_TRUE(data1.link_fwd::etl_next == ETL_NULLPTR); + CHECK_TRUE(data2.link_fwd::etl_next == ETL_NULLPTR); + CHECK_TRUE(data3.link_fwd::etl_next == ETL_NULLPTR); + + queue.pop(); + CHECK_TRUE(data1.link_fwd::etl_next == ETL_NULLPTR); + CHECK_TRUE(data2.link_fwd::etl_next == ETL_NULLPTR); + CHECK_TRUE(data3.link_fwd::etl_next == ETL_NULLPTR); + } + + //************************************************************************* + TEST(test_pop_bidirectional_link_clear) + { + Data data1(1); + Data data2(2); + Data data3(3); + + etl::intrusive_queue queue; + + queue.push(data1); + queue.push(data2); + queue.push(data3); + CHECK_TRUE(data1.link_bdir::etl_next != ETL_NULLPTR); + CHECK_TRUE(data2.link_bdir::etl_next != ETL_NULLPTR); + CHECK_TRUE(data3.link_bdir::etl_next == ETL_NULLPTR); + + queue.pop(); + CHECK_TRUE(data1.link_bdir::etl_next == ETL_NULLPTR); + CHECK_TRUE(data2.link_bdir::etl_next != ETL_NULLPTR); + CHECK_TRUE(data3.link_bdir::etl_next == ETL_NULLPTR); + + queue.pop(); + CHECK_TRUE(data1.link_bdir::etl_next == ETL_NULLPTR); + CHECK_TRUE(data2.link_bdir::etl_next == ETL_NULLPTR); + CHECK_TRUE(data3.link_bdir::etl_next == ETL_NULLPTR); + + queue.pop(); + CHECK_TRUE(data1.link_bdir::etl_next == ETL_NULLPTR); + CHECK_TRUE(data2.link_bdir::etl_next == ETL_NULLPTR); + CHECK_TRUE(data3.link_bdir::etl_next == ETL_NULLPTR); + } + //************************************************************************* TEST(test_front_const) { @@ -258,8 +364,8 @@ namespace Data data2(2); Data data3(3); - etl::intrusive_queue queueD; - const etl::intrusive_queue& queueDR = queueD; + etl::intrusive_queue queueD; + const etl::intrusive_queue& queueDR = queueD; queueD.push(data1); queueD.push(data2); @@ -280,8 +386,8 @@ namespace Data data2(2); Data data3(3); - etl::intrusive_queue queueD; - const etl::intrusive_queue& queueDR = queueD; + etl::intrusive_queue queueD; + const etl::intrusive_queue& queueDR = queueD; queueD.push(data1); queueD.push(data2);