Traits.hpp 1.92 KB
Newer Older
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
#pragma once

#include <type_traits>

#include <dune/typetree/treepath.hh>
#include <amdis/typetree/TreePath.hpp>

namespace AMDiS
{
  namespace Traits
  {
    template <class Tree, class TreePath, class NodeTag = typename Tree::NodeTag>
    struct IsValidTreePath;

    // empty treepath
    template <class Tree, class NodeTag>
    struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<>, NodeTag>
        : std::true_type {};

    // leaf nodes
    template <class Tree, class I0, class... II>
    struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<I0,II...>, Dune::TypeTree::LeafNodeTag>
        : std::false_type {};

    // power nodes
    template <class Tree, class I0, class... II>
    struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<I0,II...>, Dune::TypeTree::PowerNodeTag>
        : IsValidTreePath<typename Tree::ChildType, Dune::TypeTree::HybridTreePath<II...>> {};

    // composite node with integer index
    template <class Tree, class I0, class... II>
    struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<I0,II...>, Dune::TypeTree::CompositeNodeTag>
        : std::false_type {};

    // composite node with integral-constant index
    template <class Tree, class Int, Int i, class... II>
    struct IsValidTreePath<Tree, Dune::TypeTree::HybridTreePath<std::integral_constant<Int,i>,II...>, Dune::TypeTree::CompositeNodeTag>
        : std::conditional_t<(i >= 0 && i < Tree::degree()),
            IsValidTreePath<typename Tree::template Child<(i >= 0 && i < Tree::degree()) ? i : 0>::Type, Dune::TypeTree::HybridTreePath<II...>>,
            std::false_type> {};

  } // end namespace Traits

  namespace Concepts
  {
    /// \brief Check whether `Path` is a valid index of treepath for the given typetree `Tree`
    template <class Tree, class Path>
    static constexpr bool ValidTreePath = Traits::IsValidTreePath<Tree,TYPEOF(makeTreePath(std::declval<Path>()))>::value;
  }

} // end namespace AMDiS