diff --git a/include/etl/intrusive_forward_list.h b/include/etl/intrusive_forward_list.h index 84d0aa94e..a466337f1 100644 --- a/include/etl/intrusive_forward_list.h +++ b/include/etl/intrusive_forward_list.h @@ -629,6 +629,20 @@ namespace etl this->assign(first, last); } +#if ETL_USING_CPP11 + //************************************************************************* + /// Constructor from variadic list of nodes. + //************************************************************************* + template + intrusive_forward_list(link_type& first, TLinks&... links) + { + current_size = 0; + this->start.etl_next = &first; + link_type* last = make_linked_list(current_size, first, static_cast(links)...); + last->etl_next = &this->terminator; + } +#endif + //************************************************************************* /// Gets the beginning of the intrusive_forward_list. //************************************************************************* @@ -1169,6 +1183,41 @@ namespace etl private: +#if ETL_USING_CPP17 + //*************************************************************************** + /// Create a linked list from a number of forward_link nodes. + //*************************************************************************** + template + TLink* make_linked_list(size_t& count, TLink& first, TLinks&... links) + { + TLink* current = &first; + ++count; + ((current->etl_next = &links, current = &links, ++count), ...); + + return current; + } +#elif ETL_USING_CPP11 + //*************************************************************************** + /// Create a counted linked list from a number of forward_link nodes. + //*************************************************************************** + link_type* make_linked_list(size_t& count, link_type& first) + { + ++count; + return &first; + } + + //*************************************************************************** + /// Create a counted linked list from a number of forward_link nodes. + //*************************************************************************** + template + link_type* make_linked_list(size_t& count, link_type& first, link_type& next, TLinks&... links) + { + ++count; + first.etl_next = &next; + return make_linked_list(count, next, static_cast(links)...); + } +#endif + //************************************************************************* /// Get the next value. //************************************************************************* diff --git a/include/etl/intrusive_list.h b/include/etl/intrusive_list.h index 6bbd906f5..a8da751ee 100644 --- a/include/etl/intrusive_list.h +++ b/include/etl/intrusive_list.h @@ -685,6 +685,22 @@ namespace etl this->assign(first, last); } +#if ETL_USING_CPP11 + //************************************************************************* + /// Constructor from variadic list of nodes. + //************************************************************************* + template + intrusive_list(link_type& first, TLinks&... links) + { + current_size = 0; + this->terminal_link.etl_next = &first; + link_type* last = make_linked_list(current_size, first, static_cast(links)...); + first.etl_previous = &this->terminal_link; + last->etl_next = &this->terminal_link; + this->terminal_link.etl_previous = last; + } +#endif + //************************************************************************* /// Gets the beginning of the intrusive_list. //************************************************************************* @@ -1194,6 +1210,44 @@ namespace etl private: +#if ETL_USING_CPP17 + //*************************************************************************** + /// Create a linked list from a number of bidirectional_link nodes. + //*************************************************************************** + template + link_type* make_linked_list(size_t& count, link_type& first, TLinks&... links) + { + TLink* current = &first; + ++count; + ((current->etl_next = &links, static_cast(links).etl_previous = current, current = &links, ++count), ...); + + return current; + } +#elif ETL_USING_CPP11 + //*************************************************************************** + /// Create a linked list from a number of bidirectional_link nodes. + //*************************************************************************** + link_type* make_linked_list(size_t& count, link_type& first) + { + ++count; + + return &first; + } + + //*************************************************************************** + /// Create a linked list from a number of bidirectional_link nodes. + //*************************************************************************** + template + link_type* make_linked_list(size_t& count, link_type& first, link_type& next, TLinks&... links) + { + ++count; + first.etl_next = &next; + next.etl_previous = &first; + + return make_linked_list(count, next, static_cast(links)...); + } +#endif + // Disabled. intrusive_list(const intrusive_list& other); intrusive_list& operator = (const intrusive_list& rhs); diff --git a/test/test_intrusive_forward_list.cpp b/test/test_intrusive_forward_list.cpp index 20c8d830c..50ac48836 100644 --- a/test/test_intrusive_forward_list.cpp +++ b/test/test_intrusive_forward_list.cpp @@ -183,6 +183,29 @@ namespace CHECK_EQUAL(sorted_data.size(), data0.size()); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_variadic_list_single) + { + DataNDC0 data0(sorted_data[0]); + + CHECK(!data0.empty()); + CHECK_EQUAL(1, data0.size()); + CHECK_EQUAL(sorted_data[0], data0.front()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_variadic_list_multiple) + { + DataNDC0 data0(sorted_data[0], sorted_data[1], sorted_data[2], sorted_data[3], sorted_data[4], + sorted_data[5], sorted_data[6], sorted_data[7], sorted_data[8], sorted_data[9]); + + CHECK(!data0.empty()); + CHECK_EQUAL(10, data0.size()); + + bool are_equal = std::equal(data0.begin(), data0.end(), sorted_data.begin()); + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_empty_begin_end) { diff --git a/test/test_intrusive_list.cpp b/test/test_intrusive_list.cpp index 33aa44679..48081e355 100644 --- a/test/test_intrusive_list.cpp +++ b/test/test_intrusive_list.cpp @@ -196,6 +196,29 @@ namespace CHECK_EQUAL(sorted_data.size(), data0.size()); } + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_variadic_list_single) + { + DataNDC0 data0(sorted_data[0]); + + CHECK(!data0.empty()); + CHECK_EQUAL(1, data0.size()); + CHECK_EQUAL(sorted_data[0], data0.front()); + } + + //************************************************************************* + TEST_FIXTURE(SetupFixture, test_constructor_variadic_list_multiple) + { + DataNDC0 data0(sorted_data[0], sorted_data[1], sorted_data[2], sorted_data[3], sorted_data[4], + sorted_data[5], sorted_data[6], sorted_data[7], sorted_data[8], sorted_data[9]); + + CHECK(!data0.empty()); + CHECK_EQUAL(10, data0.size()); + + bool are_equal = std::equal(data0.begin(), data0.end(), sorted_data.begin()); + CHECK(are_equal); + } + //************************************************************************* TEST_FIXTURE(SetupFixture, test_empty_begin_end) {