1 /////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Joaquin M Lopez Munoz  2006-2013
4 // (C) Copyright Ion Gaztanaga          2014-2014
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 //    (See accompanying file LICENSE_1_0.txt or copy at
8 //          http://www.boost.org/LICENSE_1_0.txt)
9 //
10 // See http://www.boost.org/libs/intrusive for documentation.
11 //
12 /////////////////////////////////////////////////////////////////////////////
13 
14 #ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
15 #define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
16 
17 #ifndef BOOST_CONFIG_HPP
18 #  include <boost/config.hpp>
19 #endif
20 
21 #if defined(BOOST_HAS_PRAGMA_ONCE)
22 #  pragma once
23 #endif
24 
25 namespace boost {
26 namespace intrusive {
27 namespace detail {
28 
29 #if defined(BOOST_MSVC) || defined(__BORLANDC_)
30 #define BOOST_INTRUSIVE_TT_DECL __cdecl
31 #else
32 #define BOOST_INTRUSIVE_TT_DECL
33 #endif
34 
35 #if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(UNDER_CE)
36 #define BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
37 #endif
38 
39 template <typename T>
40 struct is_unary_or_binary_function_impl
41 {  static const bool value = false; };
42 
43 // see boost ticket #4094
44 // avoid duplicate definitions of is_unary_or_binary_function_impl
45 #ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
46 
47 template <typename R>
48 struct is_unary_or_binary_function_impl<R (*)()>
49 {  static const bool value = true;  };
50 
51 template <typename R>
52 struct is_unary_or_binary_function_impl<R (*)(...)>
53 {  static const bool value = true;  };
54 
55 #else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
56 
57 template <typename R>
58 struct is_unary_or_binary_function_impl<R (__stdcall*)()>
59 {  static const bool value = true;  };
60 
61 #ifndef _MANAGED
62 
63 template <typename R>
64 struct is_unary_or_binary_function_impl<R (__fastcall*)()>
65 {  static const bool value = true;  };
66 
67 #endif
68 
69 template <typename R>
70 struct is_unary_or_binary_function_impl<R (__cdecl*)()>
71 {  static const bool value = true;  };
72 
73 template <typename R>
74 struct is_unary_or_binary_function_impl<R (__cdecl*)(...)>
75 {  static const bool value = true;  };
76 
77 #endif
78 
79 // see boost ticket #4094
80 // avoid duplicate definitions of is_unary_or_binary_function_impl
81 #ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
82 
83 template <typename R, class T0>
84 struct is_unary_or_binary_function_impl<R (*)(T0)>
85 {  static const bool value = true;  };
86 
87 template <typename R, class T0>
88 struct is_unary_or_binary_function_impl<R (*)(T0...)>
89 {  static const bool value = true;  };
90 
91 #else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
92 
93 template <typename R, class T0>
94 struct is_unary_or_binary_function_impl<R (__stdcall*)(T0)>
95 {  static const bool value = true;  };
96 
97 #ifndef _MANAGED
98 
99 template <typename R, class T0>
100 struct is_unary_or_binary_function_impl<R (__fastcall*)(T0)>
101 {  static const bool value = true;  };
102 
103 #endif
104 
105 template <typename R, class T0>
106 struct is_unary_or_binary_function_impl<R (__cdecl*)(T0)>
107 {  static const bool value = true;  };
108 
109 template <typename R, class T0>
110 struct is_unary_or_binary_function_impl<R (__cdecl*)(T0...)>
111 {  static const bool value = true;  };
112 
113 #endif
114 
115 // see boost ticket #4094
116 // avoid duplicate definitions of is_unary_or_binary_function_impl
117 #ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
118 
119 template <typename R, class T0, class T1>
120 struct is_unary_or_binary_function_impl<R (*)(T0, T1)>
121 {  static const bool value = true;  };
122 
123 template <typename R, class T0, class T1>
124 struct is_unary_or_binary_function_impl<R (*)(T0, T1...)>
125 {  static const bool value = true;  };
126 
127 #else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
128 
129 template <typename R, class T0, class T1>
130 struct is_unary_or_binary_function_impl<R (__stdcall*)(T0, T1)>
131 {  static const bool value = true;  };
132 
133 #ifndef _MANAGED
134 
135 template <typename R, class T0, class T1>
136 struct is_unary_or_binary_function_impl<R (__fastcall*)(T0, T1)>
137 {  static const bool value = true;  };
138 
139 #endif
140 
141 template <typename R, class T0, class T1>
142 struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1)>
143 {  static const bool value = true;  };
144 
145 template <typename R, class T0, class T1>
146 struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1...)>
147 {  static const bool value = true;  };
148 #endif
149 
150 template <typename T>
151 struct is_unary_or_binary_function_impl<T&>
152 {  static const bool value = false; };
153 
154 template<typename T>
155 struct is_unary_or_binary_function : is_unary_or_binary_function_impl<T>
156 {};
157 
158 template<typename T, bool IsEmpty = true>
159 class ebo_functor_holder_impl
160 {
161    public:
ebo_functor_holder_impl()162    ebo_functor_holder_impl()
163    {}
ebo_functor_holder_impl(const T & t)164    ebo_functor_holder_impl(const T& t)
165       :  t_(t)
166    {}
167    template<class Arg1, class Arg2>
ebo_functor_holder_impl(const Arg1 & arg1,const Arg2 & arg2)168    ebo_functor_holder_impl(const Arg1& arg1, const Arg2& arg2)
169       :  t_(arg1, arg2)
170    {}
171 
get()172    T&       get(){return t_;}
get() const173    const T& get()const{return t_;}
174 
175    private:
176    T t_;
177 };
178 
179 template<typename T>
180 class ebo_functor_holder_impl<T, false>
181    :  public T
182 {
183    public:
ebo_functor_holder_impl()184    ebo_functor_holder_impl()
185    {}
ebo_functor_holder_impl(const T & t)186    explicit ebo_functor_holder_impl(const T& t)
187       :  T(t)
188    {}
189    template<class Arg1, class Arg2>
ebo_functor_holder_impl(const Arg1 & arg1,const Arg2 & arg2)190    ebo_functor_holder_impl(const Arg1& arg1, const Arg2& arg2)
191       :  T(arg1, arg2)
192    {}
193 
get()194    T&       get(){return *this;}
get() const195    const T& get()const{return *this;}
196 };
197 
198 template<typename T>
199 class ebo_functor_holder
200    :  public ebo_functor_holder_impl<T, is_unary_or_binary_function<T>::value>
201 {
202    private:
203    typedef ebo_functor_holder_impl<T, is_unary_or_binary_function<T>::value> super;
204 
205    public:
206    typedef T functor_type;
ebo_functor_holder()207    ebo_functor_holder(){}
ebo_functor_holder(const T & t)208    explicit ebo_functor_holder(const T& t)
209       :  super(t)
210    {}
211 
212    template<class Arg1, class Arg2>
ebo_functor_holder(const Arg1 & arg1,const Arg2 & arg2)213    ebo_functor_holder(const Arg1& arg1, const Arg2& arg2)
214       :  super(arg1, arg2)
215    {}
216 
operator =(const ebo_functor_holder & x)217    ebo_functor_holder& operator=(const ebo_functor_holder& x)
218    {
219       this->get()=x.get();
220       return *this;
221    }
222 };
223 
224 
225 }  //namespace detail {
226 }  //namespace intrusive {
227 }  //namespace boost {
228 
229 #endif   //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
230