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 #include <boost/intrusive/detail/workaround.hpp> 26 #include <boost/move/utility_core.hpp> 27 28 namespace boost { 29 namespace intrusive { 30 namespace detail { 31 32 #if defined(BOOST_MSVC) || defined(__BORLANDC_) 33 #define BOOST_INTRUSIVE_TT_DECL __cdecl 34 #else 35 #define BOOST_INTRUSIVE_TT_DECL 36 #endif 37 38 #if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(UNDER_CE) 39 #define BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS 40 #endif 41 42 template <typename T> 43 struct is_unary_or_binary_function_impl 44 { static const bool value = false; }; 45 46 // see boost ticket #4094 47 // avoid duplicate definitions of is_unary_or_binary_function_impl 48 #ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS 49 50 template <typename R> 51 struct is_unary_or_binary_function_impl<R (*)()> 52 { static const bool value = true; }; 53 54 template <typename R> 55 struct is_unary_or_binary_function_impl<R (*)(...)> 56 { static const bool value = true; }; 57 58 #else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS 59 60 template <typename R> 61 struct is_unary_or_binary_function_impl<R (__stdcall*)()> 62 { static const bool value = true; }; 63 64 #ifndef _MANAGED 65 66 template <typename R> 67 struct is_unary_or_binary_function_impl<R (__fastcall*)()> 68 { static const bool value = true; }; 69 70 #endif 71 72 template <typename R> 73 struct is_unary_or_binary_function_impl<R (__cdecl*)()> 74 { static const bool value = true; }; 75 76 template <typename R> 77 struct is_unary_or_binary_function_impl<R (__cdecl*)(...)> 78 { static const bool value = true; }; 79 80 #endif 81 82 // see boost ticket #4094 83 // avoid duplicate definitions of is_unary_or_binary_function_impl 84 #ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS 85 86 template <typename R, class T0> 87 struct is_unary_or_binary_function_impl<R (*)(T0)> 88 { static const bool value = true; }; 89 90 template <typename R, class T0> 91 struct is_unary_or_binary_function_impl<R (*)(T0...)> 92 { static const bool value = true; }; 93 94 #else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS 95 96 template <typename R, class T0> 97 struct is_unary_or_binary_function_impl<R (__stdcall*)(T0)> 98 { static const bool value = true; }; 99 100 #ifndef _MANAGED 101 102 template <typename R, class T0> 103 struct is_unary_or_binary_function_impl<R (__fastcall*)(T0)> 104 { static const bool value = true; }; 105 106 #endif 107 108 template <typename R, class T0> 109 struct is_unary_or_binary_function_impl<R (__cdecl*)(T0)> 110 { static const bool value = true; }; 111 112 template <typename R, class T0> 113 struct is_unary_or_binary_function_impl<R (__cdecl*)(T0...)> 114 { static const bool value = true; }; 115 116 #endif 117 118 // see boost ticket #4094 119 // avoid duplicate definitions of is_unary_or_binary_function_impl 120 #ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS 121 122 template <typename R, class T0, class T1> 123 struct is_unary_or_binary_function_impl<R (*)(T0, T1)> 124 { static const bool value = true; }; 125 126 template <typename R, class T0, class T1> 127 struct is_unary_or_binary_function_impl<R (*)(T0, T1...)> 128 { static const bool value = true; }; 129 130 #else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS 131 132 template <typename R, class T0, class T1> 133 struct is_unary_or_binary_function_impl<R (__stdcall*)(T0, T1)> 134 { static const bool value = true; }; 135 136 #ifndef _MANAGED 137 138 template <typename R, class T0, class T1> 139 struct is_unary_or_binary_function_impl<R (__fastcall*)(T0, T1)> 140 { static const bool value = true; }; 141 142 #endif 143 144 template <typename R, class T0, class T1> 145 struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1)> 146 { static const bool value = true; }; 147 148 template <typename R, class T0, class T1> 149 struct is_unary_or_binary_function_impl<R (__cdecl*)(T0, T1...)> 150 { static const bool value = true; }; 151 #endif 152 153 template <typename T> 154 struct is_unary_or_binary_function_impl<T&> 155 { static const bool value = false; }; 156 157 template<typename T> 158 struct is_unary_or_binary_function : is_unary_or_binary_function_impl<T> 159 {}; 160 161 template<typename T, typename Tag = void, bool = is_unary_or_binary_function<T>::value> 162 class ebo_functor_holder 163 { 164 BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder) 165 166 public: 167 typedef T functor_type; 168 ebo_functor_holder()169 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder() 170 : t_() 171 {} 172 ebo_functor_holder(const T & t)173 BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(const T &t) 174 : t_(t) 175 {} 176 ebo_functor_holder(BOOST_RV_REF (T)t)177 BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(BOOST_RV_REF(T) t) 178 : t_(::boost::move(t)) 179 {} 180 181 template<class Arg1, class Arg2> ebo_functor_holder(BOOST_FWD_REF (Arg1)arg1,BOOST_FWD_REF (Arg2)arg2)182 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2) 183 : t_(::boost::forward<Arg1>(arg1), ::boost::forward<Arg2>(arg2)) 184 {} 185 ebo_functor_holder(const ebo_functor_holder & x)186 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(const ebo_functor_holder &x) 187 : t_(x.t_) 188 {} 189 ebo_functor_holder(BOOST_RV_REF (ebo_functor_holder)x)190 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_RV_REF(ebo_functor_holder) x) 191 : t_(x.t_) 192 {} 193 operator =(BOOST_COPY_ASSIGN_REF (ebo_functor_holder)x)194 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_COPY_ASSIGN_REF(ebo_functor_holder) x) 195 { 196 this->get() = x.get(); 197 return *this; 198 } 199 operator =(BOOST_RV_REF (ebo_functor_holder)x)200 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(ebo_functor_holder) x) 201 { 202 this->get() = ::boost::move(x.get()); 203 return *this; 204 } 205 operator =(const T & x)206 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(const T &x) 207 { 208 this->get() = x; 209 return *this; 210 } 211 operator =(BOOST_RV_REF (T)x)212 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(T) x) 213 { 214 this->get() = ::boost::move(x); 215 return *this; 216 } 217 get()218 BOOST_INTRUSIVE_FORCEINLINE T& get(){return t_;} get() const219 BOOST_INTRUSIVE_FORCEINLINE const T& get()const{return t_;} 220 221 private: 222 T t_; 223 }; 224 225 template<typename T, typename Tag> 226 class ebo_functor_holder<T, Tag, false> 227 : public T 228 { 229 BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder) 230 231 public: 232 typedef T functor_type; 233 ebo_functor_holder()234 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder() 235 : T() 236 {} 237 ebo_functor_holder(const T & t)238 BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(const T &t) 239 : T(t) 240 {} 241 ebo_functor_holder(BOOST_RV_REF (T)t)242 BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(BOOST_RV_REF(T) t) 243 : T(::boost::move(t)) 244 {} 245 246 template<class Arg1, class Arg2> ebo_functor_holder(BOOST_FWD_REF (Arg1)arg1,BOOST_FWD_REF (Arg2)arg2)247 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2) 248 : T(::boost::forward<Arg1>(arg1), ::boost::forward<Arg2>(arg2)) 249 {} 250 ebo_functor_holder(const ebo_functor_holder & x)251 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(const ebo_functor_holder &x) 252 : T(static_cast<const T&>(x)) 253 {} 254 ebo_functor_holder(BOOST_RV_REF (ebo_functor_holder)x)255 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_RV_REF(ebo_functor_holder) x) 256 : T(BOOST_MOVE_BASE(T, x)) 257 {} 258 operator =(BOOST_COPY_ASSIGN_REF (ebo_functor_holder)x)259 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_COPY_ASSIGN_REF(ebo_functor_holder) x) 260 { 261 const ebo_functor_holder&r = x; 262 this->get() = r; 263 return *this; 264 } 265 operator =(BOOST_RV_REF (ebo_functor_holder)x)266 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(ebo_functor_holder) x) 267 { 268 this->get() = ::boost::move(x.get()); 269 return *this; 270 } 271 operator =(const T & x)272 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(const T &x) 273 { 274 this->get() = x; 275 return *this; 276 } 277 operator =(BOOST_RV_REF (T)x)278 BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(T) x) 279 { 280 this->get() = ::boost::move(x); 281 return *this; 282 } 283 get()284 BOOST_INTRUSIVE_FORCEINLINE T& get(){return *this;} get() const285 BOOST_INTRUSIVE_FORCEINLINE const T& get()const{return *this;} 286 }; 287 288 } //namespace detail { 289 } //namespace intrusive { 290 } //namespace boost { 291 292 #endif //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP 293