1 ////////////////////////////////////////////////////////////////////////////// 2 // 3 // (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost 4 // Software License, Version 1.0. (See accompanying file 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 // 7 // See http://www.boost.org/libs/container for documentation. 8 // 9 ////////////////////////////////////////////////////////////////////////////// 10 11 #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP 12 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP 13 14 #ifndef BOOST_CONFIG_HPP 15 # include <boost/config.hpp> 16 #endif 17 18 //In case no decltype and no variadics, mark that we don't support 0 arg calls due to 19 //compiler ICE in GCC 3.4/4.0/4.1 and, wrong SFINAE for GCC 4.2/4.3/MSVC10/MSVC11 20 #if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 21 # if defined(BOOST_GCC) && (BOOST_GCC < 40400) 22 # define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED 23 # elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200) 24 # define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED 25 # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800) 26 # define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED 27 # endif 28 #endif //#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 29 30 #include <cstddef> 31 #include <boost/move/utility_core.hpp> 32 #include <boost/move/detail/fwd_macros.hpp> 33 34 namespace boost_intrusive_hmfcw { 35 36 typedef char yes_type; 37 struct no_type{ char dummy[2]; }; 38 39 struct dont_care 40 { 41 dont_care(...); 42 }; 43 44 #if defined(BOOST_NO_CXX11_DECLTYPE) 45 46 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 47 48 template<class T> 49 struct make_dontcare 50 { 51 typedef dont_care type; 52 }; 53 54 #endif 55 56 struct private_type 57 { 58 static private_type p; 59 private_type const &operator,(int) const; 60 }; 61 62 template<typename T> 63 no_type is_private_type(T const &); 64 yes_type is_private_type(private_type const &); 65 66 #endif //#if defined(BOOST_NO_CXX11_DECLTYPE) 67 68 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) 69 70 template<typename T> struct remove_cv { typedef T type; }; 71 template<typename T> struct remove_cv<const T> { typedef T type; }; 72 template<typename T> struct remove_cv<const volatile T> { typedef T type; }; 73 template<typename T> struct remove_cv<volatile T> { typedef T type; }; 74 75 #endif 76 77 } //namespace boost_intrusive_hmfcw { 78 79 #endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP 80 81 #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME 82 #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME before including this header!" 83 #endif 84 85 #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 86 #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN before including this header!" 87 #endif 88 89 #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 90 #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX before including this header!" 91 #endif 92 93 #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX < BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 94 #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX value MUST be greater or equal than BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN!" 95 #endif 96 97 #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX == 0 98 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF 99 #else 100 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF , 101 #endif 102 103 #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG 104 #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG not defined!" 105 #endif 106 107 #ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END 108 #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!" 109 #endif 110 111 BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG 112 113 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) 114 //With decltype and variadic templaes, things are pretty easy 115 template<typename Fun, class ...Args> BOOST_MOVE_CAT(has_member_function_callable_with_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)116 struct BOOST_MOVE_CAT(has_member_function_callable_with_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) 117 { 118 template<class U> 119 static decltype(boost::move_detail::declval<U>(). 120 BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval<Args>()...) 121 , boost_intrusive_hmfcw::yes_type()) Test(U* f); 122 template<class U> 123 static boost_intrusive_hmfcw::no_type Test(...); 124 static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type); 125 }; 126 127 #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) 128 129 ///////////////////////////////////////////////////////// 130 ///////////////////////////////////////////////////////// 131 // 132 // has_member_function_callable_with_impl_XXX 133 // declaration, special case and 0 arg specializaton 134 // 135 ///////////////////////////////////////////////////////// 136 137 template <typename Type> 138 class BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) 139 { 140 struct BaseMixin 141 { 142 void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() 143 {} //Some compilers require the definition or linker errors happen 144 }; 145 146 struct Base 147 : public boost_intrusive_hmfcw::remove_cv<Type>::type, public BaseMixin 148 { //Declare the unneeded default constructor as some old compilers wrongly require it with is_convertible 149 Base(){} 150 }; 151 template <typename T, T t> class Helper{}; 152 153 template <typename U> 154 static boost_intrusive_hmfcw::no_type deduce 155 (U*, Helper<void (BaseMixin::*)(), &U::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME>* = 0); 156 static boost_intrusive_hmfcw::yes_type deduce(...); 157 158 public: 159 static const bool value = sizeof(boost_intrusive_hmfcw::yes_type) == sizeof(deduce((Base*)0)); 160 }; 161 162 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 163 ///////////////////////////////////////////////////////// 164 ///////////////////////////////////////////////////////// 165 // 166 // has_member_function_callable_with_impl_XXX for 1 to N arguments 167 // 168 ///////////////////////////////////////////////////////// 169 ///////////////////////////////////////////////////////// 170 171 //defined(BOOST_NO_CXX11_DECLTYPE) must be true 172 template<class Fun> 173 struct FunWrapTmpl : Fun 174 { 175 using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME; 176 FunWrapTmpl(); 177 template<class ...DontCares> 178 boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(DontCares...) const; 179 }; 180 181 template<typename Fun, bool HasFunc, class ...Args> 182 struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME); 183 184 //No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization 185 template<typename Fun, class ...Args> 186 struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) 187 <Fun, false, Args...> 188 { 189 static const bool value = false; 190 }; 191 192 template<typename Fun, class ...Args> 193 struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true, Args...> 194 { 195 static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type 196 ( (::boost::move_detail::declval 197 < FunWrapTmpl<Fun> >(). 198 BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval<Args>()...), 0) ) 199 ) 200 ); 201 }; 202 203 template<typename Fun, class ...Args> 204 struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) 205 : public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) 206 <Fun 207 , BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun>::value 208 , Args...> 209 {}; 210 #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 211 212 ///////////////////////////////////////////////////////// 213 ///////////////////////////////////////////////////////// 214 // 215 // has_member_function_callable_with_impl_XXX specializations 216 // 217 ///////////////////////////////////////////////////////// 218 219 template<typename Fun, bool HasFunc BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASSDFLT,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> 220 struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME); 221 222 //No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization 223 template<typename Fun BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASS,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> 224 struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) 225 <Fun, false BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_TARG,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> 226 { 227 static const bool value = false; 228 }; 229 230 #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 231 //0 arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present 232 #if !defined(BOOST_NO_CXX11_DECLTYPE) 233 234 template<typename Fun> 235 struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true> 236 { 237 template<class U> 238 static decltype(boost::move_detail::declval<U>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() 239 , boost_intrusive_hmfcw::yes_type()) Test(U* f); 240 241 template<class U> 242 static boost_intrusive_hmfcw::no_type Test(...); 243 static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type); 244 }; 245 246 #else //defined(BOOST_NO_CXX11_DECLTYPE) 247 248 #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) 249 250 template<class F, std::size_t N = sizeof(boost::move_detail::declval<F>().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(), 0)> 251 struct BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) 252 { boost_intrusive_hmfcw::yes_type dummy[N ? 1 : 2]; }; 253 254 template<typename Fun> 255 struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true> 256 { 257 template<class U> static BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U> 258 Test(BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<U>*); 259 template<class U> static boost_intrusive_hmfcw::no_type Test(...); 260 static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_hmfcw::yes_type); 261 }; 262 263 #else //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) 264 265 template<typename Fun> 266 struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true> 267 { //Some compilers gives ICE when instantiating the 0 arg version so it is not supported. 268 static const bool value = true; 269 }; 270 271 #endif//!defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) 272 #endif //!defined(BOOST_NO_CXX11_DECLTYPE) 273 #endif //#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 274 275 #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0 276 //1 to N arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present 277 //Declare some unneeded default constructor as some old compilers wrongly require it with is_convertible 278 #if defined(BOOST_NO_CXX11_DECLTYPE) 279 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\ 280 \ 281 template<class Fun>\ 282 struct BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ 283 : Fun\ 284 {\ 285 using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;\ 286 BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)();\ 287 boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME\ 288 (BOOST_MOVE_REPEAT##N(boost_intrusive_hmfcw::dont_care)) const;\ 289 };\ 290 \ 291 template<typename Fun, BOOST_MOVE_CLASS##N>\ 292 struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun, true, BOOST_MOVE_TARG##N>\ 293 {\ 294 static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type\ 295 ( (::boost::move_detail::declval\ 296 < BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun> >().\ 297 BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N), 0) )\ 298 )\ 299 );\ 300 };\ 301 // 302 #else 303 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\ 304 template<typename Fun, BOOST_MOVE_CLASS##N>\ 305 struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ 306 <Fun, true, BOOST_MOVE_TARG##N>\ 307 {\ 308 template<class U>\ 309 static decltype(boost::move_detail::declval<U>().\ 310 BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N)\ 311 , boost_intrusive_hmfcw::yes_type()) Test(U* f);\ 312 template<class U>\ 313 static boost_intrusive_hmfcw::no_type Test(...);\ 314 static const bool value = sizeof(Test<Fun>((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type);\ 315 };\ 316 // 317 #endif 318 //////////////////////////////////// 319 // Build and invoke BOOST_MOVE_ITERATE_NTOM macrofunction, note that N has to be at least 1 320 //////////////////////////////////// 321 #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 322 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN 1 323 #else 324 #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 325 #endif 326 BOOST_MOVE_CAT 327 (BOOST_MOVE_CAT(BOOST_MOVE_CAT(BOOST_MOVE_ITERATE_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN), TO) 328 ,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX) 329 (BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION) 330 #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION 331 #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN 332 //////////////////////////////////// 333 // End of BOOST_MOVE_ITERATE_NTOM 334 //////////////////////////////////// 335 #endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0 336 337 ///////////////////////////////////////////////////////// 338 ///////////////////////////////////////////////////////// 339 // 340 // has_member_function_callable_with_FUNC 341 // 342 ///////////////////////////////////////////////////////// 343 ///////////////////////////////////////////////////////// 344 345 //Otherwise use the preprocessor 346 template<typename Fun BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_CLASSDFLT,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> 347 struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) 348 : public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) 349 <Fun 350 , BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)<Fun>::value 351 BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_TARG,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> 352 {}; 353 #endif //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) 354 #endif 355 356 BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END 357 358 //Undef local macros 359 #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF 360 361 //Undef user defined macros 362 #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME 363 #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 364 #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 365 #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG 366 #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END 367