tlx
has_member.hpp
Go to the documentation of this file.
1/*******************************************************************************
2 * tlx/meta/has_member.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_MEMBER_HEADER
12#define TLX_META_HAS_MEMBER_HEADER
13
14namespace tlx {
15
16//! \addtogroup tlx_meta
17//! \{
18
19/******************************************************************************/
20// SFINAE check whether a class member exists.
21
22// based on http://stackoverflow.com/questions/257288/is-it-possible
23// -to-write-a-c-template-to-check-for-a-functions-existence
24
25/*!
26 * Macro template for class member / attribute SFINAE test
27
28 Usage:
29 \code
30 TLX_MAKE_HAS_METHOD(myfunc);
31
32 static_assert(has_method_myfunc<MyClass>::value,
33 "check MyClass for existence of attribute/method myfunc");
34 \endcode
35*/
36#define TLX_MAKE_HAS_MEMBER(Member) \
37 template <typename Type> \
38 class has_member_ ## Member \
39 { \
40 template <typename C> \
41 static char test(decltype(&C::Member)); \
42 template <typename C> \
43 static int test(...); \
44 public: \
45 static const bool value = ( /* NOLINT */ \
46 sizeof(test<Type>(0)) == sizeof(char)); \
47 }
48
49/*!
50 * Macro template for class template member SFINAE test
51
52 Usage:
53 \code
54 TLX_MAKE_HAS_TEMPLATE_METHOD(myfunc);
55
56 static_assert(has_method_myfunc<MyClass, float, int>::value,
57 "check MyClass for existence of attribute/method myfunc "
58 "if instantiated with <float, int>");
59 \endcode
60*/
61#define TLX_MAKE_HAS_TEMPLATE_MEMBER(Member) \
62 template <typename Type, typename... Args> \
63 class has_member_ ## Member \
64 { \
65 template <typename C> \
66 static char test(decltype(&C::template Member<Args...>)); \
67 template <typename C> \
68 static int test(...); \
69 public: \
70 static const bool value = ( /* NOLINT */ \
71 sizeof(test<Type>(0)) == sizeof(char)); \
72 }
73
74//! \}
75
76} // namespace tlx
77
78#endif // !TLX_META_HAS_MEMBER_HEADER
79
80/******************************************************************************/