SST/macro
preprocessor.h
Go to the documentation of this file.
1 
2 #ifndef SPROCKIT_SPROCKIT_PREPROCESSOR_H_
3 #define SPROCKIT_SPROCKIT_PREPROCESSOR_H_
4 
5 #include <sprockit/spkt_config.h>
6 
7 #if SPKT_HAVE_CPP11
8 # define spkt_static_assert(...) static_assert(__VA_ARGS__)
9 #endif
10 
11 //================================================================================//
12 //================================================================================//
13 //================================================================================//
14 
15 #if SPKT_HAVE_CPP11
16 // Note: these validation metafunctions will not work if the class in question is final
17 #include <type_traits> // for std::integral_constant
18 /**
19  * A macro to generate a metafunction that checks if a class has a member type with a name
20  * given by the macro parameter.
21  * Adapted from http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector
22  *
23  * Example usage: (adapted from the same page as above)
24  *
25  * GENERATE_HAS_MEMBER_TYPE(Foo) // Creates 'has_member_type_Foo'.
26  *
27  * struct A
28  * {
29  * struct Foo;
30  * };
31  *
32  * struct B
33  * {
34  * using Foo = int;
35  * };
36  *
37  * struct D
38  * {
39  * typedef char* Foo;
40  * };
41  *
42  * struct C : A, B { }; // Will also work on incomplete or ambiguous types.
43  *
44  *
45  * int main ( )
46  * {
47  * std::cout << std::boolalpha
48  * << "'Foo' in 'C' : "
49  * << sprockit::validation::has_member_type_Foo<C>::value
50  * << "\n";
51  * << "'Foo' in 'D' : "
52  * << sprockit::validation::has_member_type_Foo<D>::value
53  * << "\n";
54  * }
55  */
56 #define SPKT_GENERATE_HAS_MEMBER_TYPE(Type) \
57  \
58 namespace sprockit { namespace validation { \
59 template < class T > \
60 class HasMemberType_##Type \
61 { \
62 private: \
63  using Yes = char[2]; \
64  using No = char[1]; \
65  \
66  struct Fallback { struct Type { }; }; \
67  struct Derived : T, Fallback { }; \
68  \
69  template < class U > \
70  static No& test ( typename U::Type* ); \
71  template < typename U > \
72  static Yes& test ( U* ); \
73  \
74 public: \
75  static constexpr bool RESULT = sizeof(test<Derived>(nullptr)) == sizeof(Yes); \
76 }; \
77  \
78 template < class T > \
79 struct has_member_type_##Type \
80 : public std::integral_constant<bool, HasMemberType_##Type<T>::RESULT> \
81 { }; \
82 } } /* end of namespaces */
83 
84 // And a flag to let the compiler know this feature is available
85 # define SPKT_HAS_MEMBER_TYPE_VALIDATION 1
86 
87 ////////////////////////////////////////////////////////////////////////////////
88 
89 /**
90  * A macro to generate a metafunction that checks if a class has a member with a name
91  * given by the macro parameter.
92  * Adapted from http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Member_Detector
93  *
94  * Example usage: (adapted from the same page as above)
95  *
96  * GENERATE_HAS_MEMBER(att) // Creates 'has_member_att'.
97  * GENERATE_HAS_MEMBER(func) // Creates 'has_member_func'.
98  *
99  *
100  * struct A
101  * {
102  * int att;
103  * void func ( double );
104  * };
105  *
106  * struct B
107  * {
108  * char att[3];
109  * double func ( const char* );
110  * };
111  *
112  * struct C : A, B { }; // It will also work with ambiguous members.
113  *
114  *
115  * int main ( )
116  * {
117  * std::cout << std::boolalpha
118  * << "\n" "'att' in 'C' : "
119  * << has_member_att<C>::value // <type_traits>-like interface.
120  * << "\n" "'func' in 'C' : "
121  * << has_member_func<C>() // Implicitly convertible to 'bool'.
122  * << "\n";
123  * }
124  */
125 #define SPKT_GENERATE_HAS_MEMBER(member) \
126  \
127 namespace sprockit { namespace validation { \
128 template < class T > \
129 class HasMember_##member \
130 { \
131 private: \
132  using Yes = char[2]; \
133  using No = char[1]; \
134  \
135  struct Fallback { int member; }; \
136  struct Derived : T, Fallback { }; \
137  \
138  template < class U > \
139  static No& test ( decltype(U::member)* ); \
140  template < typename U > \
141  static Yes& test ( U* ); \
142  \
143 public: \
144  static constexpr bool RESULT = sizeof(test<Derived>(nullptr)) == sizeof(Yes); \
145 }; \
146  \
147 template < class T > \
148 struct has_member_##member \
149 : public std::integral_constant<bool, HasMember_##member<T>::RESULT> \
150 { }; \
151 } } /* end namespaces */
152 // And a flag to let the compiler know this feature is available
153 # define SPKT_HAS_MEMBER_VALIDATION 1
154 
155 ////////////////////////////////////////////////////////////////////////////////
156 
157 // TODO overloaded member function detection macro
158 
159 ////////////////////////////////////////////////////////////////////////////////
160 
161 #else // No validation when CPP11 is not available
162 
163 // TODO non-c++11 versions of these macros
164 
165 #endif // SPKT_HAVE_CPP11
166 
167 //================================================================================//
168 //================================================================================//
169 //================================================================================//
170 
171 
172 
173 #endif /* SPROCKIT_SPROCKIT_PREPROCESSOR_H_ */