tlx
has_method.hpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * tlx/meta/has_method.hpp
3  *
4  * Part of tlx - http://panthema.net/tlx
5  *
6  * Copyright (C) 2016-2017 Timo Bingmann <tb@panthema.net>
7  *
8  * All rights reserved. Published under the Boost Software License, Version 1.0
9  ******************************************************************************/
10 
11 #ifndef TLX_META_HAS_METHOD_HEADER
12 #define TLX_META_HAS_METHOD_HEADER
13 
14 namespace tlx {
15 
16 //! \addtogroup tlx_meta
17 //! \{
18 
19 /******************************************************************************/
20 // SFINAE check whether a class method is callable with given parameter types.
21 
22 /*!
23  * Macro template for callable class method SFINAE test.
24 
25  Usage:
26  \code
27  TLX_MAKE_HAS_METHOD(myfunc);
28 
29  static_assert(has_method_myfunc<MyClass, int(std::string)>::value,
30  "check MyClass for existence of myfunc "
31  "with signature int(std::string)");
32  \endcode
33 */
34 #define TLX_MAKE_HAS_METHOD(Method) \
35  template <typename Class, typename Signature> \
36  class has_method_ ## Method; \
37  \
38  template <typename Class, typename Return, typename... Args> \
39  class has_method_ ## Method<Class, Return(Args...)> \
40  { \
41  template <typename C> \
42  static char test( \
43  decltype(static_cast<Return (C::*)(Args...)>(&C::Method))); \
44  template <typename C> \
45  static int test(...); \
46  public: \
47  static const bool value = (sizeof(test<Class>(0)) == sizeof(char)); \
48  }
49 
50 /*!
51  * Macro template for callable class method SFINAE test.
52 
53  Usage:
54  \code
55  TLX_MAKE_HAS_STATIC_METHOD(myfunc);
56 
57  static_assert(has_method_myfunc<MyClass, int(std::string)>::value,
58  "check MyClass for existence of static myfunc "
59  "with signature int(std::string)");
60  \endcode
61 */
62 #define TLX_MAKE_HAS_STATIC_METHOD(Method) \
63  template <typename Class, typename Signature> \
64  class has_method_ ## Method; \
65  \
66  template <typename Class, typename Return, typename... Args> \
67  class has_method_ ## Method<Class, Return(Args...)> \
68  { \
69  template <typename C> \
70  static char test( \
71  decltype(static_cast<Return (*)(Args...)>(&C::Method))); \
72  template <typename C> \
73  static int test(...); \
74  public: \
75  static const bool value = (sizeof(test<Class>(0)) == sizeof(char)); \
76  }
77 
78 /*!
79  * Macro template for callable class method SFINAE test.
80 
81  Usage:
82  \code
83  TLX_MAKE_HAS_TEMPLATE_METHOD(myfunc);
84 
85  static_assert(has_method_myfunc<MyClass, int(std::string), float, int>::value,
86  "check MyClass for existence of template myfunc "
87  "with signature int(std::string) "
88  "if the template method is instantiated with <float, int>");
89  \endcode
90 */
91 #define TLX_MAKE_HAS_TEMPLATE_METHOD(Method) \
92  template <typename Class, typename Signature, typename... Cons> \
93  class has_method_ ## Method; \
94  \
95  template <typename Class, \
96  typename Return, typename... Args, typename... Cons> \
97  class has_method_ ## Method<Class, Return(Args...), Cons...> \
98  { \
99  template <typename C> \
100  static char test( \
101  decltype(static_cast<Return (C::*)(Args...)>( \
102  &C::template Method<Cons...>))); \
103  template <typename C> \
104  static int test(...); \
105  public: \
106  static const bool value = (sizeof(test<Class>(0)) == sizeof(char)); \
107  }
108 
109 //! \}
110 
111 } // namespace tlx
112 
113 #endif // !TLX_META_HAS_METHOD_HEADER
114 
115 /******************************************************************************/