"Fossies" - the Fresh Open Source Software Archive

Member "dune-typetree-2.8.0/dune/typetree/typetraits.hh" (31 Aug 2021, 5570 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. For more information about "typetraits.hh" see the Fossies "Dox" file reference documentation.

    1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
    2 // vi: set et ts=4 sw=2 sts=2:
    3 
    4 #ifndef DUNE_TYPETREE_TYPETRAITS_HH
    5 #define DUNE_TYPETREE_TYPETRAITS_HH
    6 
    7 #include <type_traits>
    8 #include <dune/common/typetraits.hh>
    9 
   10 #include <dune/typetree/treepath.hh>
   11 #include <dune/typetree/nodeinterface.hh>
   12 
   13 namespace Dune {
   14 
   15   // Provide some more C++11 TMP helpers.
   16   // These should be upstreamed to dune-common ASAP.
   17 
   18   template<typename... T>
   19   struct first_type;
   20 
   21   template<typename T0, typename... T>
   22   struct first_type<T0,T...>
   23   {
   24     typedef T0 type;
   25   };
   26 
   27   namespace TypeTree {
   28 
   29     template<typename T>
   30     struct has_node_tag
   31     {
   32       struct yes { char dummy[1]; };
   33       struct no  { char dummy[2]; };
   34 
   35       template<typename X>
   36       static yes test(NodeTag<X> *);
   37       template<typename X>
   38       static no  test(...);
   39 
   40       enum {
   41         /** @brief True if class T defines a NodeTag. */
   42         value = sizeof(test<T>(0)) == sizeof(yes)
   43       };
   44     };
   45 
   46     template<typename T, typename V>
   47     struct has_node_tag_value
   48     {
   49       template<int N>
   50       struct maybe { char dummy[N+1]; };
   51       struct yes { char dummy[2]; };
   52       struct no  { char dummy[1]; };
   53 
   54       template<typename X>
   55       static maybe<std::is_base_of<V, NodeTag<X>>::value>
   56       test(NodeTag<X> * a);
   57       template<typename X>
   58       static no test(...);
   59 
   60       enum {
   61         /** @brief True if class T defines a NodeTag of type V. */
   62         value = sizeof(test<T>(0)) == sizeof(yes)
   63       };
   64     };
   65 
   66     template<typename T>
   67     struct has_implementation_tag
   68     {
   69       struct yes { char dummy[1]; };
   70       struct no  { char dummy[2]; };
   71 
   72       template<typename X>
   73       static yes test(ImplementationTag<X> *);
   74       template<typename X>
   75       static no  test(...);
   76 
   77       enum {
   78         /** @brief True if class T defines an ImplementationTag. */
   79         value = sizeof(test<T>(0)) == sizeof(yes)
   80       };
   81     };
   82 
   83     template<typename T, typename V>
   84     struct has_implementation_tag_value
   85     {
   86       template<int N>
   87       struct maybe { char dummy[N+1]; };
   88       struct yes { char dummy[2]; };
   89       struct no  { char dummy[1]; };
   90 
   91       template<typename X>
   92       static maybe<std::is_base_of<V, ImplementationTag<X>>::value>
   93       test(ImplementationTag<X> * a);
   94       template<typename X>
   95       static no test(...);
   96 
   97       enum {
   98         /** @brief True if class T defines an ImplementationTag of type V. */
   99         value = sizeof(test<T>(0)) == sizeof(yes)
  100       };
  101     };
  102 
  103     template<typename>
  104     struct AlwaysVoid
  105     {
  106       typedef void type;
  107     };
  108 
  109 
  110     //! Helper function for generating a pointer to a value of type T in an unevaluated operand setting.
  111     template<typename T>
  112     T* declptr();
  113 
  114 
  115     // Support for lazy evaluation of meta functions. This is required when doing
  116     // nested tag dispatch without C++11-style typedefs (based on using syntax).
  117     // The standard struct-based meta functions cause premature evaluation in a
  118     // context that is not SFINAE-compatible. We thus have to return the meta function
  119     // without evaluating it, placing that burden on the caller. On the other hand,
  120     // the lookup will often directly be the target type, so here is some helper code
  121     // to automatically do the additional evaluation if necessary.
  122     // Too bad that the new syntax is GCC 4.6+...
  123 
  124 
  125     //! Marker tag declaring a meta function.
  126     /**
  127      * Just inherit from this type to cause lazy evaluation
  128      */
  129     struct meta_function {};
  130 
  131     //! Helper meta function to delay evaluation of F.
  132     template<typename F>
  133     struct lazy_evaluate
  134     {
  135       typedef typename F::type type;
  136     };
  137 
  138     //! Identity function.
  139     template<typename F>
  140     struct lazy_identity
  141     {
  142       typedef F type;
  143     };
  144 
  145     //! Meta function that evaluates its argument iff it inherits from meta_function.
  146     template<typename F>
  147     struct evaluate_if_meta_function
  148     {
  149       typedef typename std::conditional<
  150         std::is_base_of<meta_function,F>::value,
  151         lazy_evaluate<F>,
  152         lazy_identity<F>
  153         >::type::type type;
  154     };
  155 
  156     namespace impl {
  157 
  158       // Check if type is a or is derived from one of the tree path types
  159 
  160       // Default overload for types not representing a tree path
  161       constexpr auto isTreePath(void*)
  162         -> std::false_type
  163       {
  164         return std::false_type();
  165       }
  166 
  167       // Overload for instances of HybridTreePath<...>
  168       template<class... I>
  169       constexpr auto isTreePath(const HybridTreePath<I...>*)
  170         -> std::true_type
  171       {
  172         return std::true_type();
  173       }
  174 
  175     }
  176 
  177     /**
  178      * \brief Check if type represents a tree path
  179      *
  180      * If T is a or derived from one of the tree path types this
  181      * struct derives from std::true_type, otherwise from std::false_type.
  182      * Hence the result of the check is available via ::value, cast to bool,
  183      * or operator().
  184      *
  185      * \tparam T Check if this type represents a tree path
  186      */
  187     template<class T>
  188     struct IsTreePath :
  189       public decltype(impl::isTreePath((typename std::decay<T>::type*)(nullptr)))
  190     {};
  191 
  192     /**
  193      * \brief Check if given object represents a tree path
  194      *
  195      * \tparam T Check if this type represents a tree path
  196      * \returns std::true_type if argument is a tree path and std::false_type if not
  197      */
  198     template<class T>
  199     constexpr auto isTreePath(const T&)
  200       -> IsTreePath<T>
  201     {
  202       return IsTreePath<T>();
  203     }
  204 
  205 
  206   } // end namespace TypeTree
  207 } // end namespace Dune
  208 
  209 #endif // DUNE_TYPETREE_TYPETRAITS_HH