///****************************************************************************** // The MIT License(MIT) // // Embedded Template Library. // https://github.com/ETLCPP/etl // https://www.etlcpp.com // // Copyright(c) 2021 John Wellbelove // // 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 "etl/multi_vector.h" #include "etl/vector.h" #include #include #include #include #include "etl/integral_limits.h" namespace { static const size_t SIZE1 = 4UL; static const size_t SIZE2 = 3UL; using Data = etl::multi_vector; using Compare_Data = std::vector>; using Array = std::array, SIZE1>; void Copy(const Array& from, Data& to) { to.resize(SIZE1); for (size_t i = 0U; i < SIZE1; ++i) { to[i].resize(SIZE2); for (size_t j = 0U; j < SIZE2; ++j) { to[i][j] = from[i][j]; } } } Compare_Data compare_data = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; SUITE(test_multi_vector_external_buffer) { //************************************************************************* TEST(test_constructor) { Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); CHECK_EQUAL(data.size(), SIZE1); CHECK_EQUAL(data.max_size(), SIZE1); CHECK_EQUAL(data[0].size(), SIZE2); CHECK_EQUAL(data[0].max_size(), SIZE2); } //************************************************************************* TEST(test_assignment) { Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Data other_data; Copy(initial, data); other_data = data; bool isEqual = std::equal(data.begin(), data.end(), other_data.begin()); CHECK(isEqual); } //************************************************************************* TEST(test_at) { Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); for (size_t i = 0UL; i < data.size(); ++i) { for (size_t j = 0UL; j < data[0].size(); ++j) { CHECK_EQUAL(data[i].at(j), compare_data[i].at(j)); } } CHECK_THROW(data.at(data.size()), etl::vector_out_of_bounds); CHECK_THROW(data[0].at(data[0].size()), etl::vector_out_of_bounds); } //************************************************************************* TEST(test_at_const) { const Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); for (size_t i = 0UL; i < data.size(); ++i) { for (size_t j = 0UL; j < data[0].size(); ++j) { CHECK_EQUAL(data[i].at(j), compare_data[i].at(j)); } CHECK_THROW(data.at(data.size()), etl::vector_out_of_bounds); } } //************************************************************************* TEST(test_index_operator) { Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); for (size_t i = 0UL; i < data.size(); ++i) { for (size_t j = 0UL; j < data[0].size(); ++j) { CHECK_EQUAL(data[i][j], compare_data[i][j]); } } } //************************************************************************* TEST(test_index_operator_const) { const Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); for (size_t i = 0UL; i < data.size(); ++i) { for (size_t j = 0UL; j < data[0].size(); ++j) { CHECK_EQUAL(data[i][j], compare_data[i][j]); } } } //************************************************************************* TEST(test_front) { Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); int& ref = data.front().front(); CHECK(ref == compare_data.front().front()); } //************************************************************************* TEST(test_front_const) { const Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); const int& ref = data.front().front(); CHECK(ref == compare_data.front().front()); } //************************************************************************* TEST(test_back) { Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); int& ref = data.back().back(); CHECK(ref == compare_data.back().back()); } //************************************************************************* TEST(test_back_const) { const Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); const int& ref = data.back().back(); CHECK(ref == compare_data.back().back()); } //************************************************************************* TEST(test_data) { Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); bool isEqual = std::equal(data.begin(), data.end(), data.data()); CHECK(isEqual); } //************************************************************************* TEST(test_data_const) { const Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); bool isEqual = std::equal(data.begin(), data.end(), data.data()); CHECK(isEqual); } //************************************************************************* TEST(test_begin) { Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); CHECK(data.begin() == &data[0]); CHECK(data[0].begin() == &data[0][0]); CHECK(data[1].begin() == &data[1][0]); CHECK(data[2].begin() == &data[2][0]); CHECK(data[3].begin() == &data[3][0]); } //************************************************************************* TEST(test_end) { Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); CHECK(data.end() == &data[0] + SIZE1); CHECK(data[0].end() == &data[0][0] + SIZE2); CHECK(data[1].end() == &data[1][0] + SIZE2); CHECK(data[2].end() == &data[2][0] + SIZE2); CHECK(data[3].end() == &data[3][0] + SIZE2); } //************************************************************************* TEST(test_cbegin) { const Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); CHECK(data.cbegin() == &data[0]); CHECK(data[0].cbegin() == &data[0][0]); CHECK(data[1].cbegin() == &data[1][0]); CHECK(data[2].cbegin() == &data[2][0]); CHECK(data[3].cbegin() == &data[3][0]); } //************************************************************************* TEST(test_cend) { const Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); CHECK(data.cend() == &data[0] + SIZE1); CHECK(data[0].cend() == &data[0][0] + SIZE2); CHECK(data[1].cend() == &data[1][0] + SIZE2); CHECK(data[2].cend() == &data[2][0] + SIZE2); CHECK(data[3].cend() == &data[3][0] + SIZE2); } //************************************************************************* TEST(test_rbegin) { Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); typedef etl::multi_vector Inner; CHECK(data.rbegin() == Data::reverse_iterator(&data[0] + SIZE1)); CHECK(data[0].rbegin() == Inner::reverse_iterator(&data[0][0] + SIZE2)); CHECK(data[1].rbegin() == Inner::reverse_iterator(&data[1][0] + SIZE2)); CHECK(data[2].rbegin() == Inner::reverse_iterator(&data[2][0] + SIZE2)); CHECK(data[3].rbegin() == Inner::reverse_iterator(&data[3][0] + SIZE2)); } //************************************************************************* TEST(test_rend) { Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); typedef etl::multi_vector Inner; CHECK(data.rend() == Data::reverse_iterator(&data[0])); CHECK(data[0].rend() == Inner::reverse_iterator(&data[0][0])); CHECK(data[1].rend() == Inner::reverse_iterator(&data[1][0])); CHECK(data[2].rend() == Inner::reverse_iterator(&data[2][0])); CHECK(data[3].rend() == Inner::reverse_iterator(&data[3][0])); } //************************************************************************* TEST(test_crbegin) { const Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); typedef etl::multi_vector Inner; CHECK(data.rbegin() == Data::const_reverse_iterator(&data[0] + SIZE1)); CHECK(data[0].rbegin() == Inner::const_reverse_iterator(&data[0][0] + SIZE2)); CHECK(data[1].rbegin() == Inner::const_reverse_iterator(&data[1][0] + SIZE2)); CHECK(data[2].rbegin() == Inner::const_reverse_iterator(&data[2][0] + SIZE2)); CHECK(data[3].rbegin() == Inner::const_reverse_iterator(&data[3][0] + SIZE2)); } //************************************************************************* TEST(test_crend) { const Array initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data data; Copy(initial, data); typedef etl::multi_vector Inner; CHECK(data.rend() == Data::const_reverse_iterator(&data[0])); CHECK(data[0].rend() == Inner::const_reverse_iterator(&data[0][0])); CHECK(data[1].rend() == Inner::const_reverse_iterator(&data[1][0])); CHECK(data[2].rend() == Inner::const_reverse_iterator(&data[2][0])); CHECK(data[3].rend() == Inner::const_reverse_iterator(&data[3][0])); } //************************************************************************* TEST(test_empty) { Data data; CHECK(data.empty()); data.resize(1); CHECK(data[0].empty()); } //************************************************************************* TEST(test_size) { Data data; CHECK_EQUAL(0, data.size()); data.resize(1); CHECK_EQUAL(1, data.size()); CHECK_EQUAL(0, data[0].size()); } //************************************************************************* TEST(test_max_size) { Data data; data.resize(1); CHECK_EQUAL(SIZE1, data.max_size()); CHECK_EQUAL(SIZE2, data[0].max_size()); } #if ETL_HAS_INITIALIZER_LIST //************************************************************************* TEST(test_swap) { Data initial1 = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data initial2 = {{{12, 13, 14}, {15, 16, 17}, {18, 19, 20}, {21, 22, 23}}}; Data data1 = initial1; Data data2 = initial2; using ETL_OR_STD::swap; swap(data1, data2); CHECK(std::equal(initial2.begin(), initial2.end(), data1.begin())); CHECK(std::equal(initial1.begin(), initial1.end(), data2.begin())); } #endif #if ETL_HAS_INITIALIZER_LIST //************************************************************************* TEST(test_assign) { Data initial = {{{-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}, {-1, -1, -1}}}; Data initial_source = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data initial_check1 = {{{0, 1, 2}, {3, 4, 5}, {-1, -1, -1}, {-1, -1, -1}}}; Data initial_check2 = {{{0, 1, 2}, {3, 4, 5}, {99, 99, 99}, {99, 99, 99}}}; Data source = initial_source; Data check1 = initial_check1; Data check2 = initial_check2; Data data; // Initial data. data.assign(std::begin(initial), std::end(initial)); bool isEqual = std::equal(data.begin(), data.end(), std::begin(initial)); CHECK(isEqual); // Assign smaller. data.assign(std::begin(initial), std::end(initial)); data.assign(&source[0], &source[2]); isEqual = std::equal(data.begin(), data.end(), std::begin(check1)); CHECK(isEqual); } #endif #if ETL_HAS_INITIALIZER_LIST //************************************************************************* TEST(test_insert_value) { Data initial = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}}}; Data initial_check1 = {{{9, 10, 11}, {0, 1, 2}, {3, 4, 5}, {6, 7, 8}}}; Data initial_check2 = {{{0, 1, 2}, {9, 10, 11}, {3, 4, 5}, {6, 7, 8}}}; Data initial_check3 = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data check1 = initial_check1; Data check2 = initial_check2; Data check3 = initial_check3; typedef etl::multi_vector Inner; const Inner inserted = {{9, 10, 11}}; Data data; Data::iterator result; // Insert beginning. data.assign(std::begin(initial), std::end(initial)); result = data.insert(data.begin(), inserted); CHECK(data[0] == *result); bool isEqual = std::equal(data.begin(), data.end(), check1.begin()); CHECK(isEqual); // Insert middle. data.assign(std::begin(initial), std::end(initial)); result = data.insert(data.begin() + 1U, inserted); CHECK(data[1] == *result); isEqual = std::equal(data.begin(), data.end(), check2.begin()); CHECK(isEqual); // Insert end. data.assign(std::begin(initial), std::end(initial)); result = data.insert(data.begin() + 3U, inserted); CHECK(data[3] == *result); isEqual = std::equal(data.begin(), data.end(), check3.begin()); CHECK(isEqual); } #endif //************************************************************************* #if ETL_HAS_INITIALIZER_LIST TEST(test_equal) { Data initial1 = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Data initial2 = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; CHECK(initial1 == initial2); } #endif //************************************************************************* #if ETL_HAS_INITIALIZER_LIST TEST(test_not_equal) { Array initial1 = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Array initial2 = {{{0, 1, 2}, {3, 4, 6}, {6, 7, 8}, {9, 10, 11}}}; CHECK(initial1 != initial2); } #endif //************************************************************************* TEST(test_less_than) { Array initial_data = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Array initial_lesser = {{{0, 1, 2}, {3, 4, 4}, {6, 7, 8}, {9, 10, 11}}}; Array initial_greater = {{{0, 1, 2}, {3, 4, 6}, {6, 7, 8}, {9, 10, 11}}}; Data data; Data lesser; Data greater; Copy(initial_data, data); Copy(initial_lesser, lesser); Copy(initial_greater, greater); CHECK(lesser < data); CHECK(!(data < data)); CHECK(!(greater < data)); } //************************************************************************* TEST(test_less_than_equal) { Array initial_data = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Array initial_lesser = {{{0, 1, 2}, {3, 4, 4}, {6, 7, 8}, {9, 10, 11}}}; Array initial_greater = {{{0, 1, 2}, {3, 4, 6}, {6, 7, 8}, {9, 10, 11}}}; Data data; Data lesser; Data greater; Copy(initial_data, data); Copy(initial_lesser, lesser); Copy(initial_greater, greater); CHECK(lesser <= data); CHECK(data <= data); CHECK(!(greater <= data)); } //************************************************************************* TEST(test_greater_than) { Array initial_data = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Array initial_lesser = {{{0, 1, 2}, {3, 4, 4}, {6, 7, 8}, {9, 10, 11}}}; Array initial_greater = {{{0, 1, 2}, {3, 4, 6}, {6, 7, 8}, {9, 10, 11}}}; Data data; Data lesser; Data greater; Copy(initial_data, data); Copy(initial_lesser, lesser); Copy(initial_greater, greater); CHECK(greater > data); CHECK(!(data > data)); CHECK(!(lesser > data)); } //************************************************************************* TEST(test_greater_than_equal) { Array initial_data = {{{0, 1, 2}, {3, 4, 5}, {6, 7, 8}, {9, 10, 11}}}; Array initial_lesser = {{{0, 1, 2}, {3, 4, 4}, {6, 7, 8}, {9, 10, 11}}}; Array initial_greater = {{{0, 1, 2}, {3, 4, 6}, {6, 7, 8}, {9, 10, 11}}}; Data data; Data lesser; Data greater; Copy(initial_data, data); Copy(initial_lesser, lesser); Copy(initial_greater, greater); CHECK(greater >= data); CHECK(data >= data); CHECK(!(lesser >= data)); } } } // namespace