diff options
Diffstat (limited to 'test/box')
-rw-r--r-- | test/box/default.cpp | 12 | ||||
-rw-r--r-- | test/box/gc.cpp | 20 | ||||
-rw-r--r-- | test/box/generic.ipp | 58 | ||||
-rw-r--r-- | test/box/recursive.cpp | 108 | ||||
-rw-r--r-- | test/box/vector-of-boxes-transient.cpp | 36 |
5 files changed, 234 insertions, 0 deletions
diff --git a/test/box/default.cpp b/test/box/default.cpp new file mode 100644 index 000000000000..fbd1b178df08 --- /dev/null +++ b/test/box/default.cpp @@ -0,0 +1,12 @@ +// +// 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 <immer/box.hpp> + +#define BOX_T ::immer::box +#include "generic.ipp" diff --git a/test/box/gc.cpp b/test/box/gc.cpp new file mode 100644 index 000000000000..04e459559abc --- /dev/null +++ b/test/box/gc.cpp @@ -0,0 +1,20 @@ +// +// 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 <immer/box.hpp> +#include <immer/heap/gc_heap.hpp> +#include <immer/refcount/no_refcount_policy.hpp> + +using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, + immer::no_refcount_policy>; + +template <typename T> +using test_box_t = immer::box<T, gc_memory>; + +#define BOX_T test_box_t +#include "generic.ipp" diff --git a/test/box/generic.ipp b/test/box/generic.ipp new file mode 100644 index 000000000000..cfb5f04ea1b9 --- /dev/null +++ b/test/box/generic.ipp @@ -0,0 +1,58 @@ +// +// 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 +// + +#ifndef BOX_T +#error "define the box template to use in BOX_T" +#endif + +#include <catch.hpp> + +TEST_CASE("construction and copy") +{ + auto x = BOX_T<int>{}; + CHECK(x == 0); + + auto y = x; + CHECK(&x.get() == &y.get()); + + auto z = std::move(x); + CHECK(&z.get() == &y.get()); +} + +TEST_CASE("equality") +{ + auto x = BOX_T<int>{}; + auto y = x; + CHECK(x == 0.0f); + CHECK(x == y); + CHECK(x == BOX_T<int>{}); + CHECK(x != BOX_T<int>{42}); +} + +TEST_CASE("update") +{ + auto x = BOX_T<int>{}; + auto y = x.update([](auto v) { return v + 1; }); + CHECK(x == 0); + CHECK(y == 1); +} + +TEST_CASE("update move") +{ + auto x = BOX_T<int>{}; + auto addr = &x.get(); + auto y = std::move(x).update( + [](auto&& v) { return std::forward<decltype(v)>(v) + 1; }); + + CHECK(y == 1); + if (std::is_empty<typename BOX_T<int>::memory_policy::refcount>::value) { + CHECK(&y.get() != addr); + } else { + CHECK(&y.get() == addr); + } +} diff --git a/test/box/recursive.cpp b/test/box/recursive.cpp new file mode 100644 index 000000000000..4c8fce07dea2 --- /dev/null +++ b/test/box/recursive.cpp @@ -0,0 +1,108 @@ +// +// 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 <immer/algorithm.hpp> +#include <immer/box.hpp> +#include <immer/flex_vector.hpp> +#include <immer/map.hpp> +#include <immer/set.hpp> +#include <immer/vector.hpp> + +#include <catch.hpp> + +struct rec_vec +{ + int data; + immer::vector<immer::box<rec_vec>> children; +}; + +TEST_CASE("recursive vector") +{ + auto v1 = rec_vec{42, + {rec_vec{12, {}}, + rec_vec{13, {rec_vec{5, {}}, rec_vec{7, {}}}}, + rec_vec{15, {}}}}; + CHECK(v1.data == 42); + CHECK(v1.children[0]->data == 12); + CHECK(v1.children[1]->children[0]->data == 5); +} + +struct rec_fvec +{ + int data; + immer::flex_vector<immer::box<rec_fvec>> children; +}; + +TEST_CASE("recursive flex_vector") +{ + auto v1 = rec_fvec{42, + {rec_fvec{12, {}}, + rec_fvec{13, {rec_fvec{5, {}}, rec_fvec{7, {}}}}, + rec_fvec{15, {}}}}; + CHECK(v1.data == 42); + CHECK(v1.children[0]->data == 12); + CHECK(v1.children[1]->children[0]->data == 5); +} + +struct rec_map +{ + int data; + immer::map<std::string, immer::box<rec_map>> children; +}; + +TEST_CASE("recursive map") +{ + auto v1 = rec_map{42, {}}; + auto v2 = rec_map{43, v1.children.set("hello", rec_map{12, {}})}; + auto v3 = rec_map{44, v2.children.set("world", rec_map{13, {}})}; + + CHECK(v3.data == 44); + CHECK(v3.children["hello"]->data == 12); + CHECK(v3.children["world"]->data == 13); +} + +struct rec_set +{ + int data; + immer::set<immer::box<rec_set>> children; + + bool operator==(const rec_set& other) const + { + return data == other.data && children == other.children; + } + bool operator!=(const rec_set& other) const { return !(*this == other); } +}; + +namespace std { + +template <> +struct hash<rec_set> +{ + auto operator()(const rec_set& s) + { + return std::hash<decltype(s.data)>{}(s.data) ^ + immer::accumulate( + s.children, std::size_t{}, [](auto ac, auto v) { + return std::hash<decltype(v)>{}(v); + }); + } +}; + +} // namespace std + +TEST_CASE("recursive set") +{ + auto v1 = rec_set{42, {}}; + auto v2 = rec_set{43, v1.children.insert(rec_set{12, {}})}; + auto v3 = rec_set{44, v2.children.insert(rec_set{13, {}})}; + + CHECK(v3.data == 44); + CHECK(v3.children.count(rec_set{12, {}}) == 1); + CHECK(v3.children.count(rec_set{13, {}}) == 1); + CHECK(v3.children.count(rec_set{14, {}}) == 0); +} diff --git a/test/box/vector-of-boxes-transient.cpp b/test/box/vector-of-boxes-transient.cpp new file mode 100644 index 000000000000..623c8ba37d32 --- /dev/null +++ b/test/box/vector-of-boxes-transient.cpp @@ -0,0 +1,36 @@ +// +// 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 <immer/box.hpp> +#include <immer/vector.hpp> +#include <immer/vector_transient.hpp> + +#include <catch.hpp> + +TEST_CASE("issue-33") +{ + using Element = immer::box<std::string>; + auto vect = immer::vector<Element>{}; + + // this one works fine + for (auto i = 0; i < 100; ++i) { + vect = vect.push_back(Element("x")); + } + + // this one doesn't compile + auto t = vect.transient(); + + for (auto i = 0; i < 100; ++i) { + t.push_back(Element("x")); + } + + vect = t.persistent(); + + CHECK(*vect[0] == "x"); + CHECK(*vect[99] == "x"); +} |