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
14namespace 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/******************************************************************************/