/* Copyright (C) 2022 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * 0 A.D. is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with 0 A.D. If not, see . */ #include "lib/self_test.h" #include "ps/containers/StaticVector.h" #include #include #include #include class TestStaticVector : public CxxTest::TestSuite { public: class ConstructionCounter { public: ConstructionCounter(size_t& count) : m_Count{count} { ++m_Count; } ConstructionCounter(const ConstructionCounter& other) : m_Count{other.m_Count} { ++m_Count; } ConstructionCounter& operator=(const ConstructionCounter&) { return *this; } ConstructionCounter(ConstructionCounter&& other) : m_Count{other.m_Count} { ++m_Count; } ConstructionCounter& operator=(ConstructionCounter&&) { return *this; } ~ConstructionCounter() { --m_Count; } friend bool operator==(const ConstructionCounter&, const ConstructionCounter&) { return true; } private: size_t& m_Count; }; void test_construction() { size_t count{0}; { PS::StaticVector vec{ConstructionCounter{count}}; TS_ASSERT_EQUALS(count, 1); TS_ASSERT_EQUALS(vec.size(), 1); vec.pop_back(); TS_ASSERT_EQUALS(count, 0); TS_ASSERT_EQUALS(vec.size(), 0); vec.push_back(count); TS_ASSERT_EQUALS(count, 1); { ConstructionCounter lval{count}; vec.push_back(lval); vec.push_back(lval); } TS_ASSERT_EQUALS(count, 3); TS_ASSERT_EQUALS(vec.end() - vec.begin(), 3); vec.pop_back(); TS_ASSERT_EQUALS(count, 2); vec.clear(); TS_ASSERT_EQUALS(count, 0); TS_ASSERT(vec.empty()); vec.emplace_back(count); vec.insert(vec.begin(), ConstructionCounter{count}); TS_ASSERT_EQUALS(count, 2); } TS_ASSERT_EQUALS(count, 0); PS::StaticVector vec0(6, count); TS_ASSERT_EQUALS(count, 6); PS::StaticVector vec1(vec0); TS_ASSERT_EQUALS(count, 12); PS::StaticVector vec2(vec1); TS_ASSERT_EQUALS(count, 18); vec2.clear(); PS::StaticVector vec3(vec2); TS_ASSERT_EQUALS(count, 12); } void test_assigne() { size_t count{0}; PS::StaticVector vec0(3, count); TS_ASSERT_EQUALS(count, 3); PS::StaticVector vec1(vec0); TS_ASSERT_EQUALS(count, 6); vec0 = vec1; TS_ASSERT_EQUALS(count, 6); vec0.emplace_back(count); vec1 = vec0; TS_ASSERT_EQUALS(vec0, vec1); TS_ASSERT_EQUALS(count, 8); vec1.pop_back(); vec1.pop_back(); vec0 = vec1; TS_ASSERT_EQUALS(count, 4); } void test_exception() { TS_ASSERT_THROWS((PS::StaticVector(4)), PS::CapacityExceededException&); PS::StaticVector vec0(3); TS_ASSERT_THROWS(vec0.emplace_back(), PS::CapacityExceededException&); PS::StaticVector vec1; TS_ASSERT_THROWS(vec1.at(0), std::out_of_range&); } void test_ordering() { PS::StaticVector vec(36); std::iota(vec.begin(), vec.end(), 0); TS_ASSERT_EQUALS(vec[2], 2); TS_ASSERT_EQUALS(vec[24], 24); std::rotate(vec.begin(), vec.begin() + 12, vec.end()); TS_ASSERT_EQUALS(vec.front(), 12); TS_ASSERT_EQUALS(vec[23], 35); TS_ASSERT_EQUALS(vec[24], 0); const auto pred { [](const int elem) { return elem < 10; } }; std::partition(vec.begin(), vec.end(), pred); TS_ASSERT_LESS_THAN(vec[2], vec[10]); TS_ASSERT_LESS_THAN(vec[5], vec[20]); TS_ASSERT_EQUALS(std::partition_point(vec.begin(), vec.end(), pred), vec.begin() + 10); std::sort(vec.begin(), vec.end()); TS_ASSERT(std::is_sorted(vec.begin(), vec.end())); } void test_compare() { TS_ASSERT((PS::StaticVector{0, 1, 2, 3} == PS::StaticVector{0, 1, 2, 3})); TS_ASSERT((PS::StaticVector{0, 1, 2, 3} == PS::StaticVector{0, 1, 2, 3})); TS_ASSERT((PS::StaticVector{0, 1, 2, 3} != PS::StaticVector{0, 1, 2, 4})); TS_ASSERT((PS::StaticVector{0, 1, 2, 3} != PS::StaticVector{0, 1, 2, 4})); TS_ASSERT((PS::StaticVector{0, 1, 2, 3} != PS::StaticVector{0, 1, 2})); TS_ASSERT((PS::StaticVector{0, 1, 2, 3} != PS::StaticVector{0})); TS_ASSERT((PS::StaticVector{0, 1, 2, 3} != PS::StaticVector{3, 2, 1, 0})); } // Types static_assert(std::is_same_v>().begin()), int*>); static_assert(std::is_same_v>().begin()), const int*>); static_assert(std::is_same_v>().end()), int*>); static_assert(std::is_same_v>().end()), const int*>); static_assert(std::is_same_v>().data()), int*>); static_assert(std::is_same_v>().data()), const int*>); static_assert(std::is_same_v>().front()), int&>); static_assert(std::is_same_v>().front()), const int&>); // Size-types static_assert(std::is_same_v::size_type, uint_fast8_t>); static_assert(std::numeric_limits::size_type>::max() > 255); static_assert(std::numeric_limits::difference_type>::min() < -128); static_assert(std::is_same_v::size_type, uint_fast8_t>); static_assert(std::is_same_v::difference_type, int_fast16_t>); };