// // immer: immutable data structures for C++ // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente // // This software is distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt // #include #include #include #include #include #include #include using namespace immer; TEST_CASE("instantiation") { auto v = dvektor{}; CHECK(v.size() == 0u); } TEST_CASE("push back one element") { SUBCASE("one element") { const auto v1 = dvektor{}; auto v2 = v1.push_back(42); CHECK(v1.size() == 0u); CHECK(v2.size() == 1u); CHECK(v2[0] == 42); } SUBCASE("many elements") { const auto n = 666u; auto v = dvektor{}; for (auto i = 0u; i < n; ++i) { v = v.push_back(i * 10); CHECK(v.size() == i + 1); for (auto j = 0u; j < v.size(); ++j) CHECK(i + v[j] == i + j * 10); } } } TEST_CASE("update") { const auto n = 42u; auto v = dvektor{}; for (auto i = 0u; i < n; ++i) v = v.push_back(i); SUBCASE("assoc") { const auto u = v.assoc(3u, 13u); CHECK(u.size() == v.size()); CHECK(u[2u] == 2u); CHECK(u[3u] == 13u); CHECK(u[4u] == 4u); CHECK(u[40u] == 40u); CHECK(v[3u] == 3u); } SUBCASE("assoc further") { for (auto i = n; i < 666; ++i) v = v.push_back(i); auto u = v.assoc(3u, 13u); u = u.assoc(200u, 7u); CHECK(u.size() == v.size()); CHECK(u[2u] == 2u); CHECK(u[4u] == 4u); CHECK(u[40u] == 40u); CHECK(u[600u] == 600u); CHECK(u[3u] == 13u); CHECK(u[200u] == 7u); CHECK(v[3u] == 3u); CHECK(v[200u] == 200u); } SUBCASE("assoc further more") { auto v = immer::dvektor{}; for (auto i = n; i < 1000u; ++i) v = v.push_back(i); for (auto i = 0u; i < v.size(); ++i) { v = v.assoc(i, i + 1); CHECK(v[i] == i + 1); } } SUBCASE("update") { const auto u = v.update(10u, [](auto x) { return x + 10; }); CHECK(u.size() == v.size()); CHECK(u[10u] == 20u); CHECK(v[40u] == 40u); const auto w = v.update(40u, [](auto x) { return x - 10; }); CHECK(w.size() == v.size()); CHECK(w[40u] == 30u); CHECK(v[40u] == 40u); } } #if IMMER_SLOW_TESTS TEST_CASE("big") { const auto n = 1000000; auto v = dvektor{}; for (auto i = 0u; i < n; ++i) v = v.push_back(i); SUBCASE("read") { for (auto i = 0u; i < n; ++i) CHECK(v[i] == i); } SUBCASE("assoc") { for (auto i = 0u; i < n; ++i) { v = v.assoc(i, i + 1); CHECK(v[i] == i + 1); } } } #endif // IMMER_SLOW_TESTS TEST_CASE("iterator") { const auto n = 666u; auto v = dvektor{}; for (auto i = 0u; i < n; ++i) v = v.push_back(i); SUBCASE("works with range loop") { auto i = 0u; for (const auto& x : v) CHECK(x == i++); CHECK(i == v.size()); } SUBCASE("works with standard algorithms") { auto s = std::vector(n); std::iota(s.begin(), s.end(), 0u); std::equal(v.begin(), v.end(), s.begin(), s.end()); } SUBCASE("can go back from end") { CHECK(n - 1 == *--v.end()); } SUBCASE("works with reversed range adaptor") { auto r = v | boost::adaptors::reversed; auto i = n; for (const auto& x : r) CHECK(x == --i); } SUBCASE("works with strided range adaptor") { auto r = v | boost::adaptors::strided(5); auto i = 0u; for (const auto& x : r) CHECK(x == 5 * i++); } SUBCASE("works reversed") { auto i = n; for (auto iter = v.rbegin(), last = v.rend(); iter != last; ++iter) CHECK(*iter == --i); } SUBCASE("advance and distance") { auto i1 = v.begin(); auto i2 = i1 + 100; CHECK(*i2 == 100u); CHECK(i2 - i1 == 100); CHECK(*(i2 - 50) == 50u); CHECK((i2 - 30) - i2 == -30); } }