#pragma once #include #include #include #include #include namespace AMDiS { /** * \defgroup Concepts Concepts * \brief Concept definitions * @{ **/ namespace Traits { template struct IsSimilar : std::is_same, std::decay_t> {}; template struct IsSimilar, Types> : IsSimilar {}; template <> struct IsSimilar, Types<>> : std::true_type {}; template struct IsSimilar, Types> : and_t::value, IsSimilar, Types>::value> {}; template struct IsReferenceWrapper : std::false_type {}; template struct IsReferenceWrapper> : std::true_type {}; } // end namespace Traits namespace Concepts { #ifndef DOXYGEN namespace Definition { // f(args...) struct Callable { template auto requires_(F&& f, Args&&... args) -> decltype( f(FWD(args)...)); }; // idx[0] struct MultiIndex { template auto requires_(MI&& idx) -> decltype( Concepts::valid_expr( idx[0], idx.size(), idx.max_size() /* ,idx.resize() */ )); }; } // end namespace Definition #endif // DOXYGEN /// Types are the same, up to decay of qualifiers template constexpr bool Similar = Traits::IsSimilar::value; /// \brief A Collable is a function `F` that can be called with arguments of type `Args...`. /** * To be used as follows: `Concepts::Collable`. Returns true, if * an instance of `F` can be called by `operator()` with arguments of type * `Args...`. **/ template constexpr bool Callable = models; /// \brief A Functor is a function `F` with signature `Signature`. /** * To be used as follows: `Concepts::Functor`. Returns true, if * an instance of `F` can be called by `operator()` with arguments of type * `Args...` and returns a value of type `R`, i.e. `Signature := R(Args...)`. **/ template // F, Signature=Return(Arg) constexpr bool Functor = Dune::Functions::Concept::isFunction(); /// A predicate is a function that returns a boolean. template constexpr bool Predicate = Functor; template constexpr bool MultiIndex = models; /** @} **/ } // end namespace Concepts } // end namespace AMDiS