/****************************************************************************** The MIT License(MIT) Embedded Template Library. https://github.com/ETLCPP/etl https://www.etlcpp.com Copyright(c) 2016 jwellbelove Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ #include "unit_test_framework.h" #include "data.h" #include "etl/intrusive_links.h" namespace { //******************************************************* // Forward //******************************************************* typedef etl::forward_link<0> FLink0; typedef etl::forward_link<1> FLink1; struct FData : public FLink0, public FLink1 { FData(int value_) : value(value_) { } int value; }; //******************************************************* // Bidirectional //******************************************************* typedef etl::bidirectional_link<0> BLink0; typedef etl::bidirectional_link<1> BLink1; struct BData : public BLink0, public BLink1 { BData(int value_) : value(value_) { } int value; }; //******************************************************* // Tree //******************************************************* typedef etl::tree_link<0> TLink0; typedef etl::tree_link<1> TLink1; typedef etl::tree_link<2> TLink2; struct TData : public TLink0, public TLink1 { TData(int value_) : value(value_) { } int value; }; //******************************************************* // Mixed //******************************************************* struct MData : public FLink0, public BLink1, public TLink2 { MData(int value_) : value(value_) { } int value; }; SUITE(test_forward_list) { //************************************************************************* TEST(test_link_forward_link) { FData data0(0); FData data1(1); FData data2(2); FData data3(3); data0.FLink0::clear(); etl::link(data0, data1); CHECK(data0.FLink0::etl_next == &data1); data0.FLink0::clear(); etl::link(&data0, data1); CHECK(data0.FLink0::etl_next == &data1); data0.FLink0::clear(); etl::link(data0, &data1); CHECK(data0.FLink0::etl_next == &data1); data0.FLink0::clear(); etl::link(&data0, &data1); CHECK(data0.FLink0::etl_next == &data1); etl::link(data1, data2); etl::link(data2, data3); etl::link(data3, nullptr); etl::link(data3, data2); etl::link(data2, data1); etl::link(data1, data0); etl::link(data0, nullptr); CHECK(data1.FLink0::etl_next == &data2); CHECK(data2.FLink0::etl_next == &data3); CHECK(data3.FLink0::etl_next == nullptr); CHECK(data3.FLink1::etl_next == &data2); CHECK(data2.FLink1::etl_next == &data1); CHECK(data1.FLink1::etl_next == &data0); CHECK(data0.FLink1::etl_next == nullptr); FData* pdata; pdata = static_cast(data0.FLink0::etl_next); CHECK_EQUAL(1, pdata->value); pdata = static_cast(pdata->FLink0::etl_next); CHECK_EQUAL(2, pdata->value); pdata = static_cast(pdata->FLink0::etl_next); CHECK_EQUAL(3, pdata->value); pdata = static_cast(data3.FLink1::etl_next); CHECK_EQUAL(2, pdata->value); pdata = static_cast(pdata->FLink1::etl_next); CHECK_EQUAL(1, pdata->value); pdata = static_cast(pdata->FLink1::etl_next); CHECK_EQUAL(0, pdata->value); } //************************************************************************* TEST(test_link_splice_forward_link) { FData data0(0); FData data1(1); FData data2(2); FData data3(3); data0.FLink0::clear(); etl::link_splice(data0, data1); CHECK(data0.FLink0::etl_next == &data1); CHECK(data1.FLink0::etl_next == nullptr); data0.FLink0::clear(); etl::link_splice(data0, &data1); CHECK(data0.FLink0::etl_next == &data1); CHECK(data1.FLink0::etl_next == nullptr); data0.FLink0::clear(); etl::link_splice(&data0, data1); CHECK(data0.FLink0::etl_next == &data1); CHECK(data1.FLink0::etl_next == nullptr); data0.FLink0::clear(); etl::link_splice(&data0, &data1); CHECK(data0.FLink0::etl_next == &data1); CHECK(data1.FLink0::etl_next == nullptr); data0.FLink0::clear(); etl::link_splice(data0, data3); etl::link_splice(data0, data1); etl::link_splice(data1, data2); CHECK(data0.FLink0::etl_next == &data1); CHECK(data1.FLink0::etl_next == &data2); CHECK(data2.FLink0::etl_next == &data3); CHECK(data3.FLink0::etl_next == nullptr); } //************************************************************************* TEST(test_link_splice_forward_link_range) { FData data0(0); FData data1(1); FData data2(2); FData data3(3); FData data4(4); FData data5(5); FData data6(6); FData data7(7); // First range. data0.FLink0::clear(); etl::link_splice(data0, data1); etl::link_splice(data1, data6); etl::link_splice(data6, data7); // Second range. data2.FLink0::clear(); etl::link_splice(data2, data3); etl::link_splice(data3, data4); etl::link_splice(data4, data5); etl::link_splice(data1, data2, data5); CHECK(data0.FLink0::etl_next == &data1); CHECK(data1.FLink0::etl_next == &data2); CHECK(data2.FLink0::etl_next == &data3); CHECK(data3.FLink0::etl_next == &data4); CHECK(data4.FLink0::etl_next == &data5); CHECK(data5.FLink0::etl_next == &data6); CHECK(data6.FLink0::etl_next == &data7); CHECK(data7.FLink0::etl_next == nullptr); // Do it again with a pointer. // First range. data0.FLink0::clear(); etl::link_splice(data0, data1); etl::link_splice(data1, data6); etl::link_splice(data6, data7); // Second range. data2.FLink0::clear(); etl::link_splice(data2, data3); etl::link_splice(data3, data4); etl::link_splice(data4, data5); etl::link_splice(&data1, data2, data5); CHECK(data0.FLink0::etl_next == &data1); CHECK(data1.FLink0::etl_next == &data2); CHECK(data2.FLink0::etl_next == &data3); CHECK(data3.FLink0::etl_next == &data4); CHECK(data4.FLink0::etl_next == &data5); CHECK(data5.FLink0::etl_next == &data6); CHECK(data6.FLink0::etl_next == &data7); CHECK(data7.FLink0::etl_next == nullptr); // Do it again with a nullptr pointer. // Second range. data2.FLink0::clear(); etl::link_splice(data2, data3); etl::link_splice(data3, data4); etl::link_splice(data4, data5); etl::link_splice(nullptr, data2, data5); CHECK(data2.FLink0::etl_next == &data3); CHECK(data3.FLink0::etl_next == &data4); CHECK(data4.FLink0::etl_next == &data5); CHECK(data5.FLink0::etl_next == nullptr); } //************************************************************************* TEST(test_unlink_after_forward_link) { FData data0(0); FData data1(1); FData data2(2); FData data3(3); etl::link(data0, data1); etl::link(data1, data2); etl::link(data2, data3); etl::link(data3, nullptr); etl::link(data3, data2); etl::link(data2, data1); etl::link(data1, data0); etl::link(data0, nullptr); etl::unlink_after(data1); data2.FLink0::clear(); CHECK(data0.FLink0::etl_next == &data1); CHECK(data1.FLink0::etl_next == &data3); CHECK(data2.FLink0::etl_next == nullptr); CHECK(data3.FLink0::etl_next == nullptr); CHECK(data3.FLink1::etl_next == &data2); CHECK(data2.FLink1::etl_next == &data1); CHECK(data1.FLink1::etl_next == &data0); CHECK(data0.FLink1::etl_next == nullptr); etl::unlink_after(data2); data1.FLink1::clear(); CHECK(data0.FLink0::etl_next == &data1); CHECK(data1.FLink0::etl_next == &data3); CHECK(data3.FLink0::etl_next == nullptr); CHECK(data3.FLink1::etl_next == &data2); CHECK(data2.FLink1::etl_next == &data0); CHECK(data1.FLink1::etl_next == nullptr); CHECK(data0.FLink1::etl_next == nullptr); etl::unlink_after(data3); etl::unlink_after(data0); CHECK(data0.FLink0::etl_next == &data1); CHECK(data1.FLink0::etl_next == &data3); CHECK(data3.FLink0::etl_next == nullptr); CHECK(data3.FLink1::etl_next == &data2); CHECK(data2.FLink1::etl_next == &data0); CHECK(data0.FLink1::etl_next == nullptr); } //************************************************************************* TEST(test_unlink_after_range_forward_link) { FData data0(0); FData data1(1); FData data2(2); FData data3(3); etl::link(data0, data1); etl::link(data1, data2); etl::link(data2, data3); etl::link(data3, nullptr); etl::link(data3, data2); etl::link(data2, data1); etl::link(data1, data0); etl::link(data0, nullptr); etl::unlink_after(data0, data2); data1.FLink0::clear(); data2.FLink0::clear(); CHECK(data0.FLink0::etl_next == &data3); CHECK(data1.FLink0::etl_next == nullptr); CHECK(data2.FLink0::etl_next == nullptr); CHECK(data3.FLink0::etl_next == nullptr); CHECK(data3.FLink1::etl_next == &data2); CHECK(data2.FLink1::etl_next == &data1); CHECK(data1.FLink1::etl_next == &data0); CHECK(data0.FLink1::etl_next == nullptr); } //************************************************************************* TEST(test_self_link_forward_link) { FData data0(0); etl::link(data0, data0); CHECK(data0.FLink0::etl_next == &data0); etl::unlink_after(data0); CHECK(data0.FLink0::etl_next == &data0); } //************************************************************************* TEST(test_link_bidirectional_link) { BData data0(0); BData data1(1); BData data2(2); BData data3(3); etl::link(nullptr, data0); data1.BLink0::clear(); etl::link(data0, data1); CHECK(data0.BLink0::etl_next == &data1); CHECK(data1.BLink0::etl_previous == &data0); data1.BLink0::clear(); etl::link(data0, data1); CHECK(data0.BLink0::etl_next == &data1); CHECK(data1.BLink0::etl_previous == &data0); data1.BLink0::clear(); etl::link(data0, data1); CHECK(data0.BLink0::etl_next == &data1); CHECK(data1.BLink0::etl_previous == &data0); data1.BLink0::clear(); etl::link(data0, data1); CHECK(data0.BLink0::etl_next == &data1); CHECK(data1.BLink0::etl_previous == &data0); etl::link(data1, data2); etl::link(data2, data3); etl::link(data3, nullptr); CHECK(data0.BLink0::etl_previous == nullptr); CHECK(data1.BLink0::etl_previous == &data0); CHECK(data1.BLink0::etl_next == &data2); CHECK(data2.BLink0::etl_previous == &data1); CHECK(data2.BLink0::etl_next == &data3); CHECK(data3.BLink0::etl_previous == &data2); CHECK(data3.BLink0::etl_next == nullptr); etl::link(nullptr, data3); etl::link(data3, data2); etl::link(data2, data1); etl::link(data1, data0); etl::link(data0, nullptr); CHECK(data3.BLink1::etl_previous == nullptr); CHECK(data3.BLink1::etl_next == &data2); CHECK(data2.BLink1::etl_previous == &data3); CHECK(data2.BLink1::etl_next == &data1); CHECK(data1.BLink1::etl_previous == &data2); CHECK(data1.BLink1::etl_next == &data0); CHECK(data0.BLink1::etl_previous == &data1); CHECK(data0.BLink1::etl_next == nullptr); BData* pdata; pdata = static_cast(data0.BLink0::etl_next); CHECK_EQUAL(1, pdata->value); pdata = static_cast(pdata->BLink0::etl_next); CHECK_EQUAL(2, pdata->value); pdata = static_cast(pdata->BLink0::etl_next); CHECK_EQUAL(3, pdata->value); pdata = static_cast(data3.BLink0::etl_previous); CHECK_EQUAL(2, pdata->value); pdata = static_cast(pdata->BLink0::etl_previous); CHECK_EQUAL(1, pdata->value); pdata = static_cast(pdata->BLink0::etl_previous); CHECK_EQUAL(0, pdata->value); pdata = static_cast(data3.BLink1::etl_next); CHECK_EQUAL(2, pdata->value); pdata = static_cast(pdata->BLink1::etl_next); CHECK_EQUAL(1, pdata->value); pdata = static_cast(pdata->BLink1::etl_next); CHECK_EQUAL(0, pdata->value); pdata = static_cast(data0.BLink1::etl_previous); CHECK_EQUAL(1, pdata->value); pdata = static_cast(pdata->BLink1::etl_previous); CHECK_EQUAL(2, pdata->value); pdata = static_cast(pdata->BLink1::etl_previous); CHECK_EQUAL(3, pdata->value); data1.BLink0::unlink(); CHECK(data0.BLink0::etl_next == &data2); CHECK(data2.BLink0::etl_previous == &data0); CHECK(data3.BLink1::etl_previous == nullptr); CHECK(data3.BLink1::etl_next == &data2); CHECK(data2.BLink1::etl_previous == &data3); CHECK(data2.BLink1::etl_next != nullptr); CHECK(data0.BLink1::etl_previous != nullptr); CHECK(data0.BLink1::etl_next == nullptr); data0.BLink0::unlink(); CHECK(data2.BLink0::etl_next == &data3); CHECK(data2.BLink0::etl_previous == nullptr); CHECK(data3.BLink0::etl_previous == &data2); CHECK(data3.BLink1::etl_previous == nullptr); CHECK(data3.BLink1::etl_next == &data2); CHECK(data2.BLink1::etl_previous == &data3); CHECK(data2.BLink1::etl_next != nullptr); data3.BLink0::unlink(); CHECK(data2.BLink0::etl_next == nullptr); CHECK(data2.BLink0::etl_previous == nullptr); CHECK(data2.BLink1::etl_next != nullptr); CHECK(data2.BLink1::etl_previous != nullptr); data2.BLink0::unlink(); } //************************************************************************* TEST(test_link_splice_bidirectional_link) { BData data0(0); BData data1(1); BData data2(2); BData data3(3); data0.BLink0::clear(); etl::link_splice(nullptr, data0); etl::link_splice(data0, data1); CHECK(data0.BLink0::etl_next == &data1); CHECK(data1.BLink0::etl_previous == &data0); CHECK(data1.BLink0::etl_next == nullptr); data0.BLink0::clear(); etl::link_splice(nullptr, data0); etl::link_splice(data0, &data1); CHECK(data0.BLink0::etl_next == &data1); CHECK(data1.BLink0::etl_previous == &data0); CHECK(data1.BLink0::etl_next == nullptr); data0.BLink0::clear(); etl::link_splice(nullptr, data0); etl::link_splice(&data0, data1); CHECK(data0.BLink0::etl_next == &data1); CHECK(data1.BLink0::etl_previous == &data0); CHECK(data1.BLink0::etl_next == nullptr); data0.BLink0::clear(); etl::link_splice(nullptr, data0); etl::link_splice(&data0, &data1); CHECK(data0.BLink0::etl_next == &data1); CHECK(data1.BLink0::etl_previous == &data0); CHECK(data1.BLink0::etl_next == nullptr); data0.BLink0::clear(); etl::link_splice(nullptr, data0); etl::link_splice(data0, data3); etl::link_splice(data0, data1); etl::link_splice(data1, data2); CHECK(data0.BLink0::etl_previous == nullptr); CHECK(data0.BLink0::etl_next == &data1); CHECK(data1.BLink0::etl_previous == &data0); CHECK(data1.BLink0::etl_next == &data2); CHECK(data2.BLink0::etl_previous == &data1); CHECK(data2.BLink0::etl_next == &data3); CHECK(data3.BLink0::etl_previous == &data2); CHECK(data3.BLink0::etl_next == nullptr); } //************************************************************************* TEST(test_link_splice_range_bidirectional_link) { BData data0(0); BData data1(1); BData data2(2); BData data3(3); BData data4(4); BData data5(5); BData data6(6); BData data7(7); // Build the first range. data0.BLink0::clear(); etl::link_splice(nullptr, data0); etl::link_splice(data0, data1); etl::link_splice(data1, data6); etl::link_splice(data6, data7); // Build the second range. data2.BLink0::clear(); etl::link_splice(nullptr, data2); etl::link_splice(data2, data3); etl::link_splice(data3, data4); etl::link_splice(data4, data5); etl::link_splice(data1, data2, data5); CHECK(data0.BLink0::etl_previous == nullptr); CHECK(data0.BLink0::etl_next == &data1); CHECK(data1.BLink0::etl_previous == &data0); CHECK(data1.BLink0::etl_next == &data2); CHECK(data2.BLink0::etl_previous == &data1); CHECK(data2.BLink0::etl_next == &data3); CHECK(data3.BLink0::etl_previous == &data2); CHECK(data3.BLink0::etl_next == &data4); CHECK(data4.BLink0::etl_previous == &data3); CHECK(data4.BLink0::etl_next == &data5); CHECK(data5.BLink0::etl_previous == &data4); CHECK(data5.BLink0::etl_next == &data6); CHECK(data6.BLink0::etl_previous == &data5); CHECK(data6.BLink0::etl_next == &data7); CHECK(data7.BLink0::etl_previous == &data6); CHECK(data7.BLink0::etl_next == nullptr); // Do it again with a pointer parameter. // Build the first range. data0.BLink0::clear(); etl::link_splice(nullptr, data0); etl::link_splice(data0, data1); etl::link_splice(data1, data6); etl::link_splice(data6, data7); // Build the second range. data2.BLink0::clear(); etl::link_splice(nullptr, data2); etl::link_splice(data2, data3); etl::link_splice(data3, data4); etl::link_splice(data4, data5); etl::link_splice(&data1, data2, data5); CHECK(data0.BLink0::etl_previous == nullptr); CHECK(data0.BLink0::etl_next == &data1); CHECK(data1.BLink0::etl_previous == &data0); CHECK(data1.BLink0::etl_next == &data2); CHECK(data2.BLink0::etl_previous == &data1); CHECK(data2.BLink0::etl_next == &data3); CHECK(data3.BLink0::etl_previous == &data2); CHECK(data3.BLink0::etl_next == &data4); CHECK(data4.BLink0::etl_previous == &data3); CHECK(data4.BLink0::etl_next == &data5); CHECK(data5.BLink0::etl_previous == &data4); CHECK(data5.BLink0::etl_next == &data6); CHECK(data6.BLink0::etl_previous == &data5); CHECK(data6.BLink0::etl_next == &data7); CHECK(data7.BLink0::etl_previous == &data6); CHECK(data7.BLink0::etl_next == nullptr); // Do it again with a nullptr parameter. // Build the range. data2.BLink0::clear(); etl::link_splice(nullptr, data2); etl::link_splice(data2, data3); etl::link_splice(data3, data4); etl::link_splice(data4, data5); etl::link_splice(nullptr, data2, data5); CHECK(data2.BLink0::etl_previous == nullptr); CHECK(data2.BLink0::etl_next == &data3); CHECK(data3.BLink0::etl_previous == &data2); CHECK(data3.BLink0::etl_next == &data4); CHECK(data4.BLink0::etl_previous == &data3); CHECK(data4.BLink0::etl_next == &data5); CHECK(data5.BLink0::etl_previous == &data4); CHECK(data5.BLink0::etl_next == nullptr); } //************************************************************************* TEST(test_unlink_bidirectional_link) { BData data0(0); BData data1(1); BData data2(2); BData data3(3); etl::link(nullptr, data0); etl::link(data0, data1); etl::link(data1, data2); etl::link(data2, data3); etl::link(data3, nullptr); etl::link(nullptr, data3); etl::link(data3, data2); etl::link(data2, data1); etl::link(data1, data0); etl::link(data0, nullptr); etl::unlink(data1); data1.BLink0::clear(); CHECK(data0.BLink0::etl_previous == nullptr); CHECK(data0.BLink0::etl_next == &data2); CHECK(data1.BLink0::etl_previous == nullptr); CHECK(data1.BLink0::etl_next == nullptr); CHECK(data2.BLink0::etl_previous == &data0); CHECK(data2.BLink0::etl_next == &data3); CHECK(data3.BLink0::etl_previous == &data2); CHECK(data3.BLink0::etl_next == nullptr); CHECK(data3.BLink1::etl_previous == nullptr); CHECK(data3.BLink1::etl_next == &data2); CHECK(data2.BLink1::etl_previous == &data3); CHECK(data2.BLink1::etl_next == &data1); CHECK(data1.BLink1::etl_previous == &data2); CHECK(data1.BLink1::etl_next == &data0); CHECK(data0.BLink1::etl_previous == &data1); CHECK(data0.BLink1::etl_next == nullptr); etl::unlink(data2); data2.BLink1::clear(); CHECK(data0.BLink0::etl_previous == nullptr); CHECK(data0.BLink0::etl_next == &data2); CHECK(data1.BLink0::etl_previous == nullptr); CHECK(data1.BLink0::etl_next == nullptr); CHECK(data2.BLink0::etl_previous == &data0); CHECK(data2.BLink0::etl_next == &data3); CHECK(data3.BLink0::etl_previous == &data2); CHECK(data3.BLink0::etl_next == nullptr); CHECK(data3.BLink1::etl_previous == nullptr); CHECK(data3.BLink1::etl_next == &data1); CHECK(data2.BLink1::etl_previous == nullptr); CHECK(data2.BLink1::etl_next == nullptr); CHECK(data1.BLink1::etl_previous == &data3); CHECK(data1.BLink1::etl_next == &data0); CHECK(data0.BLink1::etl_previous == &data1); CHECK(data0.BLink1::etl_next == nullptr); etl::unlink(data0); data0.BLink0::clear(); CHECK(data0.BLink0::etl_previous == nullptr); CHECK(data0.BLink0::etl_next == nullptr); CHECK(data1.BLink0::etl_previous == nullptr); CHECK(data1.BLink0::etl_next == nullptr); CHECK(data2.BLink0::etl_previous == nullptr); CHECK(data2.BLink0::etl_next == &data3); CHECK(data3.BLink0::etl_previous == &data2); CHECK(data3.BLink0::etl_next == nullptr); CHECK(data3.BLink1::etl_previous == nullptr); CHECK(data3.BLink1::etl_next == &data1); CHECK(data2.BLink1::etl_previous == nullptr); CHECK(data2.BLink1::etl_next == nullptr); CHECK(data1.BLink1::etl_previous == &data3); CHECK(data1.BLink1::etl_next == &data0); CHECK(data0.BLink1::etl_previous == &data1); CHECK(data0.BLink1::etl_next == nullptr); etl::unlink(data3); data3.BLink1::clear(); CHECK(data0.BLink0::etl_previous == nullptr); CHECK(data0.BLink0::etl_next == nullptr); CHECK(data1.BLink0::etl_previous == nullptr); CHECK(data1.BLink0::etl_next == nullptr); CHECK(data2.BLink0::etl_previous == nullptr); CHECK(data2.BLink0::etl_next == &data3); CHECK(data3.BLink0::etl_previous == &data2); CHECK(data3.BLink0::etl_next == nullptr); CHECK(data3.BLink1::etl_previous == nullptr); CHECK(data3.BLink1::etl_next == nullptr); CHECK(data2.BLink1::etl_previous == nullptr); CHECK(data2.BLink1::etl_next == nullptr); CHECK(data1.BLink1::etl_previous == nullptr); CHECK(data1.BLink1::etl_next == &data0); CHECK(data0.BLink1::etl_previous == &data1); CHECK(data0.BLink1::etl_next == nullptr); } //************************************************************************* TEST(test_unlink_range_bidirectional_link) { BData data0(0); BData data1(1); BData data2(2); BData data3(3); etl::link(nullptr, data0); etl::link(data0, data1); etl::link(data1, data2); etl::link(data2, data3); etl::link(data3, nullptr); etl::link(nullptr, data3); etl::link(data3, data2); etl::link(data2, data1); etl::link(data1, data0); etl::link(data0, nullptr); etl::unlink(data1, data2); data1.BLink0::clear(); data2.BLink0::clear(); CHECK(data0.BLink0::etl_previous == nullptr); CHECK(data0.BLink0::etl_next == &data3); CHECK(data1.BLink0::etl_previous == nullptr); CHECK(data1.BLink0::etl_next == nullptr); CHECK(data2.BLink0::etl_previous == nullptr); CHECK(data2.BLink0::etl_next == nullptr); CHECK(data3.BLink0::etl_previous == &data0); CHECK(data3.BLink0::etl_next == nullptr); CHECK(data3.BLink1::etl_previous == nullptr); CHECK(data3.BLink1::etl_next == &data2); CHECK(data2.BLink1::etl_previous == &data3); CHECK(data2.BLink1::etl_next == &data1); CHECK(data1.BLink1::etl_previous == &data2); CHECK(data1.BLink1::etl_next == &data0); CHECK(data0.BLink1::etl_previous == &data1); CHECK(data0.BLink1::etl_next == nullptr); } //************************************************************************* TEST(test_self_link_bidirectional_link) { BData data0(0); etl::link(data0, data0); CHECK(data0.BLink0::etl_previous == &data0); CHECK(data0.BLink0::etl_next == &data0); etl::unlink(data0); CHECK(data0.BLink0::etl_previous == &data0); CHECK(data0.BLink0::etl_next == &data0); } //************************************************************************* TEST(test_tree_link) { TData data0(0); TData data1(1); TData data2(2); TData data3(3); TData data4(4); TData data5(5); TData data6(6); // First link data0.TLink0::clear(); etl::link_left(data0, data1); etl::link_right(data0, data2); CHECK(data0.TLink0::etl_left == &data1); CHECK(data0.TLink0::etl_right == &data2); CHECK(data1.TLink0::etl_parent == &data0); CHECK(data2.TLink0::etl_parent == &data0); data0.TLink0::clear(); etl::link_left(&data0, data1); etl::link_right(&data0, data2); CHECK(data0.TLink0::etl_left == &data1); CHECK(data0.TLink0::etl_right == &data2); CHECK(data1.TLink0::etl_parent == &data0); CHECK(data2.TLink0::etl_parent == &data0); data0.TLink0::clear(); etl::link_left(data0, &data1); etl::link_right(data0, &data2); CHECK(data0.TLink0::etl_left == &data1); CHECK(data0.TLink0::etl_right == &data2); CHECK(data1.TLink0::etl_parent == &data0); CHECK(data2.TLink0::etl_parent == &data0); data0.TLink0::clear(); etl::link_left(&data0, &data1); etl::link_right(&data0, &data2); etl::link_left(data1, data3); etl::link_right(data1, data4); etl::link_left(data3, nullptr); etl::link_right(data3, nullptr); etl::link_left(data4, nullptr); etl::link_right(data4, nullptr); etl::link_left(data2, data5); etl::link_right(data2, data6); etl::link_left(data5, nullptr); etl::link_right(data5, nullptr); etl::link_left(data6, nullptr); etl::link_right(data6, nullptr); // Second link data0.TLink1::clear(); etl::link_left(&data6, &data4); etl::link_right(&data6, &data5); etl::link_left(data4, data0); etl::link_right(data4, data1); etl::link_left(data0, nullptr); etl::link_right(data0, nullptr); etl::link_left(data1, nullptr); etl::link_right(data1, nullptr); etl::link_left(data5, data2); etl::link_right(data5, data3); etl::link_left(data2, nullptr); etl::link_right(data2, nullptr); etl::link_left(data3, nullptr); etl::link_right(data3, nullptr); // Check first CHECK(data0.TLink0::etl_left == &data1); CHECK(data0.TLink0::etl_right == &data2); CHECK(data1.TLink0::etl_parent == &data0); CHECK(data2.TLink0::etl_parent == &data0); CHECK(data1.TLink0::etl_left == &data3); CHECK(data1.TLink0::etl_right == &data4); CHECK(data3.TLink0::etl_parent == &data1); CHECK(data3.TLink0::etl_left == nullptr); CHECK(data3.TLink0::etl_right == nullptr); CHECK(data4.TLink0::etl_parent == &data1); CHECK(data4.TLink0::etl_left == nullptr); CHECK(data4.TLink0::etl_right == nullptr); CHECK(data2.TLink0::etl_left == &data5); CHECK(data2.TLink0::etl_right == &data6); CHECK(data5.TLink0::etl_parent == &data2); CHECK(data5.TLink0::etl_left == nullptr); CHECK(data5.TLink0::etl_right == nullptr); CHECK(data6.TLink0::etl_parent == &data2); CHECK(data6.TLink0::etl_left == nullptr); CHECK(data6.TLink0::etl_right == nullptr); // Check second CHECK(data6.TLink1::etl_left == &data4); CHECK(data6.TLink1::etl_right == &data5); CHECK(data4.TLink1::etl_parent == &data6); CHECK(data5.TLink1::etl_parent == &data6); CHECK(data4.TLink1::etl_left == &data0); CHECK(data4.TLink1::etl_right == &data1); CHECK(data0.TLink1::etl_parent == &data4); CHECK(data0.TLink1::etl_left == nullptr); CHECK(data0.TLink1::etl_right == nullptr); CHECK(data1.TLink1::etl_parent == &data4); CHECK(data1.TLink1::etl_left == nullptr); CHECK(data1.TLink1::etl_right == nullptr); CHECK(data5.TLink1::etl_left == &data2); CHECK(data5.TLink1::etl_right == &data3); CHECK(data2.TLink1::etl_parent == &data5); CHECK(data2.TLink1::etl_left == nullptr); CHECK(data2.TLink1::etl_right == nullptr); CHECK(data3.TLink1::etl_parent == &data5); CHECK(data3.TLink1::etl_left == nullptr); CHECK(data3.TLink1::etl_right == nullptr); } //************************************************************************* TEST(test_is_linked) { // Forward link FData fdata(0); fdata.FLink0::clear(); fdata.FLink1::clear(); CHECK(!fdata.FLink0::is_linked()); CHECK(!fdata.FLink1::is_linked()); etl::link(fdata, fdata); CHECK(fdata.FLink0::is_linked()); CHECK(!fdata.FLink1::is_linked()); etl::link(fdata, fdata); CHECK(fdata.FLink0::is_linked()); CHECK(fdata.FLink1::is_linked()); // Bidirectional link BData bdata(0); bdata.BLink0::clear(); bdata.BLink1::clear(); CHECK(!bdata.BLink0::is_linked()); CHECK(!bdata.BLink1::is_linked()); etl::link(bdata, bdata); CHECK(bdata.BLink0::is_linked()); CHECK(!bdata.BLink1::is_linked()); etl::link(bdata, bdata); CHECK(bdata.BLink0::is_linked()); CHECK(bdata.BLink1::is_linked()); // Tree link TData tdata(0); tdata.TLink0::clear(); tdata.TLink1::clear(); CHECK(!tdata.TLink0::is_linked()); CHECK(!tdata.TLink1::is_linked()); etl::link_left(tdata, tdata); CHECK(tdata.TLink0::is_linked()); CHECK(!tdata.TLink1::is_linked()); etl::link_right(tdata, tdata); CHECK(tdata.TLink0::is_linked()); CHECK(tdata.TLink1::is_linked()); } //************************************************************************* TEST(test_link_mixed_links) { MData data0(0); MData data1(1); MData data2(2); MData data3(3); MData data4(4); MData data5(5); MData data6(6); // Forward data0.FLink0::clear(); etl::link(data0, data1); etl::link(data1, data2); etl::link(data2, data3); etl::link(data3, nullptr); // Bidirectional etl::link(nullptr, data3); etl::link(data3, data2); etl::link(data2, data1); etl::link(data1, data0); etl::link(data0, nullptr); // Tree data0.TLink2::clear(); etl::link_left(data0, data1); etl::link_right(data0, data2); etl::link_left(data1, data3); etl::link_right(data1, data4); etl::link_left(data3, nullptr); etl::link_right(data3, nullptr); etl::link_left(data4, nullptr); etl::link_right(data4, nullptr); etl::link_left(data2, data5); etl::link_right(data2, data6); etl::link_left(data5, nullptr); etl::link_right(data5, nullptr); etl::link_left(data6, nullptr); etl::link_right(data6, nullptr); CHECK(data0.FLink0::etl_next == &data1); CHECK(data1.FLink0::etl_next == &data2); CHECK(data2.FLink0::etl_next == &data3); CHECK(data3.FLink0::etl_next == nullptr); CHECK(data3.BLink1::etl_previous == nullptr); CHECK(data3.BLink1::etl_next == &data2); CHECK(data2.BLink1::etl_previous == &data3); CHECK(data2.BLink1::etl_next == &data1); CHECK(data1.BLink1::etl_previous == &data2); CHECK(data1.BLink1::etl_next == &data0); CHECK(data0.BLink1::etl_previous == &data1); CHECK(data0.BLink1::etl_next == nullptr); CHECK(data0.TLink2::etl_left == &data1); CHECK(data0.TLink2::etl_right == &data2); CHECK(data1.TLink2::etl_parent == &data0); CHECK(data2.TLink2::etl_parent == &data0); CHECK(data1.TLink2::etl_left == &data3); CHECK(data1.TLink2::etl_right == &data4); CHECK(data3.TLink2::etl_parent == &data1); CHECK(data3.TLink2::etl_left == nullptr); CHECK(data3.TLink2::etl_right == nullptr); CHECK(data4.TLink2::etl_parent == &data1); CHECK(data4.TLink2::etl_left == nullptr); CHECK(data4.TLink2::etl_right == nullptr); CHECK(data2.TLink2::etl_left == &data5); CHECK(data2.TLink2::etl_right == &data6); CHECK(data5.TLink2::etl_parent == &data2); CHECK(data5.TLink2::etl_left == nullptr); CHECK(data5.TLink2::etl_right == nullptr); CHECK(data6.TLink2::etl_parent == &data2); CHECK(data6.TLink2::etl_left == nullptr); CHECK(data6.TLink2::etl_right == nullptr); } //************************************************************************* TEST(test_tree_link_rotate_left) { TLink0 r; TLink0 a; TLink0 b; TLink0 c; TLink0 d; TLink0 e; r.clear(); c.clear(); d.clear(); e.clear(); etl::link_left(r, b); etl::link_right(b, a); etl::link_left(b, d); etl::link_right(a, c); etl::link_left(a, e); etl::link_rotate_left(b, a); CHECK(a.etl_parent == &r); CHECK(b.etl_parent == &a); CHECK(e.etl_parent == &b); CHECK(d.etl_parent == &b); CHECK(c.etl_parent == &a); CHECK(a.etl_left == &b); CHECK(a.etl_right == &c); CHECK(b.etl_left == &d); CHECK(b.etl_right == &e); } //************************************************************************* TEST(test_tree_link_rotate_left_nullptr) { TLink0 r; TLink0 a; TLink0 b; TLink0 c; TLink0 d; r.clear(); a.clear(); c.clear(); d.clear(); etl::link_left(r, b); etl::link_right(b, a); etl::link_left(b, d); etl::link_right(a, c); etl::link_rotate_left(b, a); CHECK(a.etl_parent == &r); CHECK(b.etl_parent == &a); CHECK(d.etl_parent == &b); CHECK(c.etl_parent == &a); CHECK(a.etl_left == &b); CHECK(a.etl_right == &c); CHECK(b.etl_left == &d); CHECK(b.etl_right == nullptr); } //************************************************************************* TEST(test_tree_link_rotate_right) { TLink0 r; TLink0 a; TLink0 b; TLink0 c; TLink0 d; TLink0 e; r.clear(); c.clear(); d.clear(); e.clear(); etl::link_left(r, a); etl::link_left(a, b); etl::link_left(b, d); etl::link_right(a, c); etl::link_right(b, e); etl::link_rotate_right(a, b); CHECK(b.etl_parent == &r); CHECK(d.etl_parent == &b); CHECK(a.etl_parent == &b); CHECK(e.etl_parent == &a); CHECK(c.etl_parent == &a); CHECK(b.etl_left == &d); CHECK(b.etl_right == &a); CHECK(a.etl_left == &e); CHECK(a.etl_right == &c); } //************************************************************************* TEST(test_tree_link_rotate_right_nullptr) { TLink0 r; TLink0 a; TLink0 b; TLink0 c; TLink0 d; r.clear(); b.clear(); c.clear(); d.clear(); etl::link_left(r, a); etl::link_left(a, b); etl::link_left(b, d); etl::link_right(a, c); etl::link_rotate_right(a, b); CHECK(b.etl_parent == &r); CHECK(d.etl_parent == &b); CHECK(a.etl_parent == &b); CHECK(c.etl_parent == &a); CHECK(b.etl_left == &d); CHECK(b.etl_right == &a); CHECK(a.etl_left == nullptr); CHECK(a.etl_right == &c); } }; }