CreateHasTypeAlias.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <type_traits>
7 
8 #include "Utilities/NoSuchType.hpp"
9 
10 // @{
11 /*!
12  * \ingroup TypeTraitsGroup
13  * \brief Generate a type trait to check if a class has a type alias with a
14  * particular name, optionally also checking its type.
15  *
16  * To generate the corresponding `_v` metafunction, call
17  * `CREATE_HAS_TYPE_ALIAS` first and then `CREATE_HAS_TYPE_ALIAS_V`.
18  *
19  * \example
20  * \snippet Test_CreateHasTypeAlias.cpp CREATE_HAS_TYPE_ALIAS
21  *
22  * \see `CREATE_IS_CALLABLE`
23  */
24 // Use `NoSuchType*****` to represent any `AliasType`, i.e. not checking the
25 // alias type at all. If someone has that many pointers to a thing that isn't
26 // useful, it's their fault...
27 #define CREATE_HAS_TYPE_ALIAS(ALIAS_NAME) \
28  template <typename CheckingType, typename AliasType = NoSuchType*****, \
29  typename = std::void_t<>> \
30  struct has_##ALIAS_NAME : std::false_type {}; \
31  \
32  template <typename CheckingType, typename AliasType> \
33  struct has_##ALIAS_NAME<CheckingType, AliasType, \
34  std::void_t<typename CheckingType::ALIAS_NAME>> \
35  : std::bool_constant< \
36  std::is_same_v<AliasType, NoSuchType*****> or \
37  std::is_same_v<typename CheckingType::ALIAS_NAME, AliasType>> {};
38 // Separate macros to avoid compiler warnings about unused variables
39 #define CREATE_HAS_TYPE_ALIAS_V(ALIAS_NAME) \
40  template <typename CheckingType, typename AliasType = NoSuchType*****> \
41  static constexpr const bool has_##ALIAS_NAME##_v = \
42  has_##ALIAS_NAME<CheckingType, AliasType>::value;
43 // @}
type_traits