Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <type_traits> 7 : 8 : namespace tt { 9 : namespace detail { 10 : template <template <typename...> class U, typename T> 11 : struct is_a : std::false_type {}; 12 : 13 : template <template <typename...> class U, typename... Args> 14 : struct is_a<U, U<Args...>> : std::true_type {}; 15 : 16 : template <template <typename...> class U> 17 : struct is_a_wrapper; 18 : 19 : template <typename U, typename T> 20 : struct wrapped_is_a; 21 : 22 : template <template <typename...> class U, typename T> 23 : struct wrapped_is_a<is_a_wrapper<U>, T> : detail::is_a<U, T> {}; 24 : } // namespace detail 25 : 26 : /// @{ 27 : /// \ingroup TypeTraitsGroup 28 : /// \brief Check if type `T` is a template specialization of `U` 29 : /// 30 : /// \requires `U` is a class template 31 : /// \effects If `T` is a template specialization of `U`, then inherits from 32 : /// std::true_type, otherwise inherits from std::false_type 33 : /// 34 : /// \usage 35 : /// For any type `T` and class template `U` 36 : /// \code 37 : /// using result = tt::is_a<U, T>; 38 : /// \endcode 39 : /// \metareturns 40 : /// std::bool_constant 41 : /// 42 : /// \semantics 43 : /// If the type `T` is a template specialization of the type `U`, then 44 : /// \code 45 : /// typename result::type = std::true_type; 46 : /// \endcode 47 : /// otherwise 48 : /// \code 49 : /// typename result::type = std::false_type; 50 : /// \endcode 51 : /// 52 : /// \example 53 : /// \snippet Test_IsA.cpp is_a_example 54 : /// \see is_std_array 55 : /// \tparam T type to check 56 : /// \tparam U the type that T might be a template specialization of 57 : template <template <typename...> class U, typename T> 58 1 : using is_a = detail::wrapped_is_a<detail::is_a_wrapper<U>, T>; 59 : 60 : /// \see is_a 61 : template <template <typename...> class U, typename T> 62 1 : constexpr bool is_a_v = is_a<U, T>::value; 63 : 64 : /// \see is_a 65 : template <template <typename...> class U, typename T> 66 1 : using is_a_t = typename is_a<U, T>::type; 67 : /// @} 68 : } // namespace tt