1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-GPL-2.0-only-with-PDELab-exception
#include "config.h"
#include "typetreetestutility.hh"
#include <dune/typetree/traversal.hh>
#include <dune/typetree/treecontainer.hh>
#include <dune/common/test/testsuite.hh>
struct NameVisitor
: public Dune::TypeTree::TreeVisitor
, public Dune::TypeTree::DynamicTraversal
{
std::string s;
template<typename T, typename TreePath>
void pre(const T& node, TreePath) { s += node.name(); s += "<"; }
template<typename T, typename TreePath>
void leaf(const T& node, TreePath) { s += node.name(); s += ","; }
template<typename T, typename TreePath>
void post(const T& node, TreePath) { s += ">"; }
};
template<class Tree>
std::string treeName(const Tree& tree)
{
NameVisitor nameVisitor;
Dune::TypeTree::applyToTree(tree, nameVisitor);
return nameVisitor.s;
}
template<class F>
bool notThrown(F&& f)
{
try {
f();
return true;
}
catch(...) {}
return false;
}
template <class Value, class Tree>
using UniformTreeMatrix
= Dune::TypeTree::UniformTreeContainer<
Dune::TypeTree::UniformTreeContainer<Value,Tree>,Tree>;
template<class Tree, class Value>
Dune::TestSuite checkTreeContainer(const Tree& tree, const Value& value)
{
Dune::TestSuite test(treeName(tree));
// construct a container using a factory function
auto container = Dune::TypeTree::makeTreeContainer<Value>(tree);
// copy construct the container
auto container2{container};
auto container3{container};
// copy-assign the container
container2 = container;
// move-construct the container
auto container4{std::move(container2)};
// move-assign the container
container4 = std::move(container3);
Dune::TypeTree::forEachLeafNode(tree, [&] (auto&& node, auto treePath) {
test.check(notThrown([&]() {
container[treePath] = value;
})) << "Assigning desired value to tree container entry failed";
});
Dune::TypeTree::forEachLeafNode(tree, [&] (auto&& node, auto treePath) {
test.check(container[treePath] == value)
<< "Value in tree container does not match assigned value";
});
// default construct a container
decltype(container) container5{};
container5.resize(tree);
Dune::TypeTree::forEachLeafNode(tree, [&] (auto&& node, auto treePath) {
test.check(notThrown([&]() {
container5[treePath] = value;
})) << "Assigning desired value to tree container entry failed";
});
Dune::TypeTree::forEachLeafNode(tree, [&] (auto&& node, auto treePath) {
test.check(container5[treePath] == value)
<< "Value in tree container does not match assigned value";
});
// default construct a container with size information from tree
decltype(container) container6{tree};
Dune::TypeTree::forEachLeafNode(tree, [&] (auto&& node, auto treePath) {
test.check(notThrown([&]() {
container6[treePath] = value;
})) << "Assigning desired value to tree container entry failed";
});
Dune::TypeTree::forEachLeafNode(tree, [&] (auto&& node, auto treePath) {
test.check(container6[treePath] == value)
<< "Value in tree container does not match assigned value";
});
// construct a matrix-like container
auto matrix = Dune::TypeTree::makeTreeContainer(tree,
[&](auto const&) { return Dune::TypeTree::makeTreeContainer<Value>(tree); });
Dune::TypeTree::forEachLeafNode(tree, [&] (auto&& rowNode, auto rowTreePath) {
Dune::TypeTree::forEachLeafNode(tree, [&] (auto&& colNode, auto colTreePath) {
test.check(notThrown([&]() {
matrix[rowTreePath][colTreePath] = value;
})) << "Assigning desired value to tree matrix-container entry failed";
});
});
Dune::TypeTree::forEachLeafNode(tree, [&] (auto&& rowNode, auto rowTreePath) {
Dune::TypeTree::forEachLeafNode(tree, [&] (auto&& colNode, auto colTreePath) {
test.check(matrix[rowTreePath][colTreePath] == value)
<< "Value in tree matrix-container does not match assigned value";
});
});
return test;
}
int main(int argc, char** argv)
{
Dune::TestSuite test;
int v1 = 42;
std::vector<double> v2{1,2,3,4};
using SL1 = SimpleLeaf;
SL1 sl1;
test.subTest(checkTreeContainer(sl1, v1));
test.subTest(checkTreeContainer(sl1, v2));
using SP1 = SimplePower<SimpleLeaf,3>;
SP1 sp1(sl1, sl1, sl1);
test.subTest(checkTreeContainer(sp1, v1));
test.subTest(checkTreeContainer(sp1, v2));
using SDP1 = SimpleDynamicPower<SimpleLeaf>;
SDP1 sdp1(sl1, sl1, sl1);
test.subTest(checkTreeContainer(sdp1, v1));
test.subTest(checkTreeContainer(sdp1, v2));
using SL2 = SimpleLeaf;
using SP2 = SimplePower<SimpleLeaf,2>;
using SC1 = SimpleComposite<SL1,SP1,SP2>;
SL2 sl2;
SP2 sp2(sl2,sl2);
SC1 sc1_1(sl1,sp1,sp2);
test.subTest(checkTreeContainer(sc1_1, v1));
test.subTest(checkTreeContainer(sc1_1, v2));
test.report();
return test.exit();
}
|