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
25namespace boost {
26namespace intrusive {
27namespace 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
39template <typename T>
40struct 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
47template <typename R>
48struct is_unary_or_binary_function_impl<R (*)()>
49{ static const bool value = true; };
50
51template <typename R>
52struct is_unary_or_binary_function_impl<R (*)(...)>
53{ static const bool value = true; };
54
55#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS
56
57template <typename R>
58struct is_unary_or_binary_function_impl<R (__stdcall*)()>
59{ static const bool value = true; };
60
61#ifndef _MANAGED
62
63template <typename R>
64struct is_unary_or_binary_function_impl<R (__fastcall*)()>
65{ static const bool value = true; };
66
67#endif
68
69template <typename R>
70struct is_unary_or_binary_function_impl<R (__cdecl*)()>
71{ static const bool value = true; };
72
73template <typename R>
74struct 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
83template <typename R, class T0>
84struct is_unary_or_binary_function_impl<R (*)(T0)>
85{ static const bool value = true; };
86
87template <typename R, class T0>
88struct 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
93template <typename R, class T0>
94struct is_unary_or_binary_function_impl<R (__stdcall*)(T0)>
95{ static const bool value = true; };
96
97#ifndef _MANAGED
98
99template <typename R, class T0>
100struct is_unary_or_binary_function_impl<R (__fastcall*)(T0)>
101{ static const bool value = true; };
102
103#endif
104
105template <typename R, class T0>
106struct is_unary_or_binary_function_impl<R (__cdecl*)(T0)>
107{ static const bool value = true; };
108
109template <typename R, class T0>
110struct 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
119template <typename R, class T0, class T1>
120struct is_unary_or_binary_function_impl<R (*)(T0, T1)>
121{ static const bool value = true; };
122
123template <typename R, class T0, class T1>
124struct 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
129template <typename R, class T0, class T1>
130struct is_unary_or_binary_function_impl<R (__stdcall*)(T0, T1)>
131{ static const bool value = true; };
132
133#ifndef _MANAGED
134
135template <typename R, class T0, class T1>
136struct is_unary_or_binary_function_impl<R (__fastcall*)(T0, T1)>
137{ static const bool value = true; };
138
139#endif
140
141template <typename R, class T0, class T1>
142struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1)>
143{ static const bool value = true; };
144
145template <typename R, class T0, class T1>
146struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1...)>
147{ static const bool value = true; };
148#endif
149
150template <typename T>
151struct is_unary_or_binary_function_impl<T&>
152{ static const bool value = false; };
153
154template<typename T>
155struct is_unary_or_binary_function : is_unary_or_binary_function_impl<T>
156{};
157
158template<typename T, bool IsEmpty = true>
159class ebo_functor_holder_impl
160{
161 public:
162 ebo_functor_holder_impl()
163 {}
164 ebo_functor_holder_impl(const T& t)
165 : t_(t)
166 {}
167 template<class Arg1, class Arg2>
168 ebo_functor_holder_impl(const Arg1& arg1, const Arg2& arg2)
169 : t_(arg1, arg2)
170 {}
171
172 T& get(){return t_;}
173 const T& get()const{return t_;}
174
175 private:
176 T t_;
177};
178
179template<typename T>
180class ebo_functor_holder_impl<T, false>
181 : public T
182{
183 public:
184 ebo_functor_holder_impl()
185 {}
186 explicit ebo_functor_holder_impl(const T& t)
187 : T(t)
188 {}
189 template<class Arg1, class Arg2>
190 ebo_functor_holder_impl(const Arg1& arg1, const Arg2& arg2)
191 : T(arg1, arg2)
192 {}
193
194 T& get(){return *this;}
195 const T& get()const{return *this;}
196};
197
198template<typename T>
199class 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 ebo_functor_holder(){}
207 explicit ebo_functor_holder(const T& t)
208 : super(t)
209 {}
210
211 template<class Arg1, class Arg2>
212 ebo_functor_holder(const Arg1& arg1, const Arg2& arg2)
213 : super(arg1, arg2)
214 {}
215
216 ebo_functor_holder& operator=(const ebo_functor_holder& x)
217 {
218 this->get()=x.get();
219 return *this;
220 }
221};
222
223
224} //namespace detail {
225} //namespace intrusive {
226} //namespace boost {
227
228#endif //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP
229