"Fossies" - the Fresh Open Source Software Archive

Member "dune-typetree-2.8.0/test/testcallbacktraversal.cc" (31 Aug 2021, 5032 Bytes) of package /linux/misc/dune/dune-typetree-2.8.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    2 // vi: set et ts=4 sw=2 sts=2:
    3 #include <config.h>
    4 
    5 #include <dune/common/test/testsuite.hh>
    6 
    7 #include <dune/typetree/leafnode.hh>
    8 #include <dune/typetree/powernode.hh>
    9 #include <dune/typetree/compositenode.hh>
   10 #include <dune/typetree/traversal.hh>
   11 
   12 
   13 
   14 template<class P>
   15 class SimpleLeafNode :
   16     public Dune::TypeTree::LeafNode
   17 {
   18   using Base = Dune::TypeTree::LeafNode;
   19 public:
   20   using Payload = P;
   21 
   22   SimpleLeafNode(const Payload& payload) :
   23     payload_(payload)
   24   {}
   25 
   26   SimpleLeafNode(Payload&& payload) :
   27     payload_(std::move(payload))
   28   {}
   29 
   30   const Payload& value() const
   31   { return payload_;}
   32 
   33   Payload& value()
   34   { return payload_;}
   35 
   36 private:
   37   Payload payload_;
   38 };
   39 
   40 
   41 
   42 template<class P, class C, std::size_t n>
   43 class SimplePowerNode:
   44     public Dune::TypeTree::PowerNode<C,n>
   45 {
   46   using Base = Dune::TypeTree::PowerNode<C,n>;
   47 public:
   48   using Payload = P;
   49 
   50   template<class... CC>
   51   SimplePowerNode(const Payload& payload, CC&&... cc) :
   52     Base(std::forward<CC>(cc)...),
   53     payload_(payload)
   54   {}
   55 
   56   template<class... CC>
   57   SimplePowerNode(Payload&& payload, CC&&... cc) :
   58     Base(std::forward<CC>(cc)...),
   59     payload_(std::move(payload))
   60   {}
   61 
   62   const Payload& value() const
   63   { return payload_;}
   64 
   65   Payload& value()
   66   { return payload_;}
   67 
   68 private:
   69   Payload payload_;
   70 };
   71 
   72 
   73 
   74 template<class P, class... C>
   75 class SimpleCompositeNode:
   76     public Dune::TypeTree::CompositeNode<C...>
   77 {
   78   using Base = Dune::TypeTree::CompositeNode<C...>;
   79 public:
   80   using Payload = P;
   81 
   82   template<class... CC>
   83   SimpleCompositeNode(const Payload& payload, CC&&... cc) :
   84     Base(std::forward<CC>(cc)...),
   85     payload_(payload)
   86   {}
   87 
   88   template<class... CC>
   89   SimpleCompositeNode(Payload&& payload, CC&&... cc) :
   90     Base(std::forward<CC>(cc)...),
   91     payload_(std::move(payload))
   92   {}
   93 
   94   const Payload& value() const
   95   { return payload_;}
   96 
   97   Payload& value()
   98   { return payload_;}
   99 
  100 private:
  101   Payload payload_;
  102 };
  103 
  104 
  105 
  106 template<class P>
  107 auto leafNode(P&& p)
  108 {
  109   return SimpleLeafNode<std::decay_t<P>>(std::forward<P>(p));
  110 }
  111 
  112 
  113 
  114 template<class P, class... C>
  115 auto compositeNode(P&& p, C&&... c)
  116 {
  117   return SimpleCompositeNode<std::decay_t<P>, std::decay_t<C>...>(std::forward<P>(p), std::forward<C>(c)...);
  118 }
  119 
  120 
  121 
  122 template<class P, class C0, class... C>
  123 auto powerNode(P&& p, C0&& c0, C&&... c)
  124 {
  125   return SimplePowerNode<std::decay_t<P>, std::decay_t<C0>, sizeof...(C)+1>(std::forward<P>(p), std::forward<C0>(c0), std::forward<C>(c)...);
  126 }
  127 
  128 
  129 template<class PreOp = Dune::TypeTree::NoOp, class PostOp = Dune::TypeTree::NoOp, class LeafOp = Dune::TypeTree::NoOp>
  130 struct GenericVisitor
  131     : Dune::TypeTree::TreeVisitor
  132     , Dune::TypeTree::DynamicTraversal
  133 {
  134   GenericVisitor(PreOp const& preOp = {}, LeafOp const& leafOp = {}, PostOp const& postOp = {})
  135     : preOp_(preOp)
  136     , leafOp_(leafOp)
  137     , postOp_(postOp)
  138   {}
  139 
  140   template<class Node, class TreePath>
  141   void pre(Node&& node, TreePath tp) const { preOp_(node, tp); }
  142 
  143   template<class Node, class TreePath>
  144   void leaf(Node&& node, TreePath tp) const { leafOp_(node, tp); }
  145 
  146   template<class Node, class TreePath>
  147   void post(Node&& node, TreePath tp) const { postOp_(node, tp); }
  148 
  149 private:
  150   PreOp preOp_;
  151   LeafOp leafOp_;
  152   PostOp postOp_;
  153 };
  154 
  155 
  156 int main()
  157 {
  158   Dune::TestSuite test("tree traversal check");
  159 
  160   using Payload = std::size_t;
  161 
  162   auto tree = compositeNode(
  163                 Payload(0),
  164                 powerNode(
  165                   Payload(0),
  166                   leafNode(Payload(0)),
  167                   leafNode(Payload(0)),
  168                   leafNode(Payload(0))
  169                 ),
  170                 leafNode(Payload(0)));
  171 
  172   {
  173     std::size_t all = 0;
  174     forEachNode(tree, [&](auto&& node, auto&& path) {
  175       ++all;
  176     });
  177     test.check(all==6)
  178       << "Counting all nodes with forEachNode failed. Result is " << all << " but should be " << 6;
  179   }
  180 
  181   {
  182     std::size_t inner = 0;
  183     std::size_t leaf = 0;
  184     applyToTree(tree, GenericVisitor{
  185        [&](auto&& node, auto&& path) {
  186       ++inner;
  187     }, [&](auto&& node, auto&& path) {
  188       ++leaf;
  189     }});
  190     test.check(inner==2)
  191       << "Counting inner nodes with forEachNode failed. Result is " << inner << " but should be " << 2;
  192     test.check(leaf==4)
  193       << "Counting leaf nodes with forEachNode failed. Result is " << leaf << " but should be " << 4;
  194   }
  195 
  196   {
  197     std::size_t leaf = 0;
  198     forEachLeafNode(tree, [&](auto&& node, auto&& path) {
  199       ++leaf;
  200     });
  201     test.check(leaf==4)
  202       << "Counting leaf nodes with forEachLeafNode failed. Result is " << leaf << " but should be " << 4;
  203   }
  204 
  205   {
  206     auto countVisit = [] (auto&& node, auto&& path) {
  207       ++(node.value());
  208     };
  209     applyToTree(tree, GenericVisitor{countVisit, countVisit, countVisit});
  210 
  211     std::size_t visits=0;
  212     forEachNode(tree, [&](auto&& node, auto&& path) {
  213       visits += node.value();
  214     });
  215 
  216     test.check(visits==8)
  217       << "Counting all node visitations failed. Result is " << visits << " but should be " << 8;
  218   }
  219 
  220   return test.exit();
  221 }