diff options
Diffstat (limited to 'test/box/recursive.cpp')
-rw-r--r-- | test/box/recursive.cpp | 108 |
1 files changed, 108 insertions, 0 deletions
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); +} |