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