1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga  2009-2013.
4 //
5 // Distributed under the Boost Software License, Version 1.0.
6 //    (See accompanying file LICENSE_1_0.txt or copy at
7 //          http://www.boost.org/LICENSE_1_0.txt)
8 //
9 // See http://www.boost.org/libs/intrusive for documentation.
10 //
11 /////////////////////////////////////////////////////////////////////////////
12 //  This code was modified from the code posted by Alexandre Courpron in his
13 //  article "Interface Detection" in The Code Project:
14 //  http://www.codeproject.com/KB/architecture/Detector.aspx
15 ///////////////////////////////////////////////////////////////////////////////
16 // Copyright 2007 Alexandre Courpron
17 //
18 // Permission to use, copy, modify, redistribute and sell this software,
19 // provided that this copyright notice appears on all copies of the software.
20 ///////////////////////////////////////////////////////////////////////////////
21 
22 #ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
23 #define BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
24 
25 #ifndef BOOST_CONFIG_HPP
26 #  include <boost/config.hpp>
27 #endif
28 
29 #if defined(BOOST_HAS_PRAGMA_ONCE)
30 #  pragma once
31 #endif
32 
33 namespace boost {
34 namespace intrusive {
35 namespace function_detector {
36 
37     typedef char NotFoundType;
38     struct StaticFunctionType { NotFoundType x [2]; };
39     struct NonStaticFunctionType { NotFoundType x [3]; };
40 
41     enum
42          { NotFound          = 0,
43            StaticFunction    = sizeof( StaticFunctionType )    - sizeof( NotFoundType ),
44            NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType )
45          };
46 
47 }  //namespace boost {
48 }  //namespace intrusive {
49 }  //namespace function_detector {
50 
51 #define BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \
52    namespace boost { \
53    namespace intrusive { \
54    namespace function_detector { \
55    template < class T, \
56             class NonStaticType, \
57             class NonStaticConstType, \
58             class StaticType > \
59    class DetectMember_##InstantiationKey_##Identifier { \
60       template < NonStaticType > \
61       struct TestNonStaticNonConst ; \
62       \
63       template < NonStaticConstType > \
64       struct TestNonStaticConst ; \
65       \
66       template < StaticType > \
67       struct TestStatic ; \
68       \
69       template <class U > \
70       static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \
71       \
72       template <class U > \
73       static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \
74       \
75       template <class U> \
76       static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \
77       \
78       template <class U> \
79       static NotFoundType Test( ... ); \
80    public : \
81       static const int check = NotFound + (sizeof(Test<T>(0, 0)) - sizeof(NotFoundType));\
82    };\
83 }}} //namespace boost::intrusive::function_detector {
84 
85 #define BOOST_INTRUSIVE_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \
86     ::boost::intrusive::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\
87                                          ReturnType (Class::*)Params,\
88                                          ReturnType (Class::*)Params const,\
89                                          ReturnType (*)Params \
90                                        >::check
91 
92 #endif   //@ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
93