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
|