annotate DEPENDENCIES/generic/include/boost/move/detail/meta_utils.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 //////////////////////////////////////////////////////////////////////////////
Chris@16 2 //
Chris@101 3 // (C) Copyright Ion Gaztanaga 2012-2015.
Chris@16 4 // Distributed under the Boost Software License, Version 1.0.
Chris@16 5 // (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 6 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 7 //
Chris@16 8 // See http://www.boost.org/libs/move for documentation.
Chris@16 9 //
Chris@16 10 //////////////////////////////////////////////////////////////////////////////
Chris@16 11
Chris@16 12 //! \file
Chris@16 13
Chris@16 14 #ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
Chris@16 15 #define BOOST_MOVE_DETAIL_META_UTILS_HPP
Chris@16 16
Chris@101 17 #ifndef BOOST_CONFIG_HPP
Chris@101 18 # include <boost/config.hpp>
Chris@101 19 #endif
Chris@101 20 #
Chris@101 21 #if defined(BOOST_HAS_PRAGMA_ONCE)
Chris@101 22 # pragma once
Chris@101 23 #endif
Chris@101 24 #include <boost/move/detail/meta_utils_core.hpp>
Chris@101 25 #include <cstddef> //for std::size_t
Chris@16 26
Chris@16 27 //Small meta-typetraits to support move
Chris@16 28
Chris@16 29 namespace boost {
Chris@101 30
Chris@101 31 //Forward declare boost::rv
Chris@101 32 template <class T> class rv;
Chris@101 33
Chris@16 34 namespace move_detail {
Chris@16 35
Chris@101 36 //////////////////////////////////////
Chris@101 37 // nat
Chris@101 38 //////////////////////////////////////
Chris@101 39 struct nat{};
Chris@16 40
Chris@101 41 //////////////////////////////////////
Chris@101 42 // natify
Chris@101 43 //////////////////////////////////////
Chris@101 44 template <class T> struct natify{};
Chris@16 45
Chris@101 46 //////////////////////////////////////
Chris@101 47 // remove_reference
Chris@101 48 //////////////////////////////////////
Chris@101 49 template<class T>
Chris@101 50 struct remove_reference
Chris@16 51 {
Chris@16 52 typedef T type;
Chris@16 53 };
Chris@16 54
Chris@101 55 template<class T>
Chris@101 56 struct remove_reference<T&>
Chris@16 57 {
Chris@16 58 typedef T type;
Chris@16 59 };
Chris@16 60
Chris@101 61 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 62
Chris@101 63 template<class T>
Chris@101 64 struct remove_reference<T&&>
Chris@16 65 {
Chris@101 66 typedef T type;
Chris@16 67 };
Chris@16 68
Chris@101 69 #else
Chris@16 70
Chris@101 71 template<class T>
Chris@101 72 struct remove_reference< rv<T> >
Chris@101 73 {
Chris@101 74 typedef T type;
Chris@101 75 };
Chris@16 76
Chris@101 77 template<class T>
Chris@101 78 struct remove_reference< rv<T> &>
Chris@101 79 {
Chris@101 80 typedef T type;
Chris@101 81 };
Chris@101 82
Chris@101 83 template<class T>
Chris@101 84 struct remove_reference< const rv<T> &>
Chris@101 85 {
Chris@101 86 typedef T type;
Chris@101 87 };
Chris@101 88
Chris@101 89
Chris@101 90 #endif
Chris@101 91
Chris@101 92 //////////////////////////////////////
Chris@101 93 // add_const
Chris@101 94 //////////////////////////////////////
Chris@101 95 template<class T>
Chris@101 96 struct add_const
Chris@101 97 {
Chris@101 98 typedef const T type;
Chris@101 99 };
Chris@101 100
Chris@101 101 template<class T>
Chris@101 102 struct add_const<T&>
Chris@101 103 {
Chris@101 104 typedef const T& type;
Chris@101 105 };
Chris@101 106
Chris@101 107 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 108
Chris@101 109 template<class T>
Chris@101 110 struct add_const<T&&>
Chris@101 111 {
Chris@101 112 typedef T&& type;
Chris@101 113 };
Chris@101 114
Chris@101 115 #endif
Chris@101 116
Chris@101 117 //////////////////////////////////////
Chris@101 118 // add_lvalue_reference
Chris@101 119 //////////////////////////////////////
Chris@101 120 template<class T>
Chris@101 121 struct add_lvalue_reference
Chris@101 122 { typedef T& type; };
Chris@101 123
Chris@101 124 template<class T> struct add_lvalue_reference<T&> { typedef T& type; };
Chris@101 125 template<> struct add_lvalue_reference<void> { typedef void type; };
Chris@101 126 template<> struct add_lvalue_reference<const void> { typedef const void type; };
Chris@101 127 template<> struct add_lvalue_reference<volatile void> { typedef volatile void type; };
Chris@101 128 template<> struct add_lvalue_reference<const volatile void>{ typedef const volatile void type; };
Chris@101 129
Chris@101 130 template<class T>
Chris@101 131 struct add_const_lvalue_reference
Chris@101 132 {
Chris@101 133 typedef typename remove_reference<T>::type t_unreferenced;
Chris@101 134 typedef typename add_const<t_unreferenced>::type t_unreferenced_const;
Chris@101 135 typedef typename add_lvalue_reference
Chris@101 136 <t_unreferenced_const>::type type;
Chris@101 137 };
Chris@101 138
Chris@101 139 //////////////////////////////////////
Chris@101 140 // is_lvalue_reference
Chris@101 141 //////////////////////////////////////
Chris@16 142 template<class T>
Chris@16 143 struct is_lvalue_reference
Chris@101 144 {
Chris@101 145 static const bool value = false;
Chris@101 146 };
Chris@16 147
Chris@16 148 template<class T>
Chris@16 149 struct is_lvalue_reference<T&>
Chris@101 150 {
Chris@101 151 static const bool value = true;
Chris@101 152 };
Chris@16 153
Chris@101 154 //////////////////////////////////////
Chris@101 155 // is_class_or_union
Chris@101 156 //////////////////////////////////////
Chris@16 157 template<class T>
Chris@16 158 struct is_class_or_union
Chris@16 159 {
Chris@101 160 struct twochar { char dummy[2]; };
Chris@16 161 template <class U>
Chris@16 162 static char is_class_or_union_tester(void(U::*)(void));
Chris@16 163 template <class U>
Chris@16 164 static twochar is_class_or_union_tester(...);
Chris@16 165 static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);
Chris@16 166 };
Chris@16 167
Chris@101 168 //////////////////////////////////////
Chris@101 169 // addressof
Chris@101 170 //////////////////////////////////////
Chris@101 171 template<class T>
Chris@101 172 struct addr_impl_ref
Chris@16 173 {
Chris@16 174 T & v_;
Chris@16 175 inline addr_impl_ref( T & v ): v_( v ) {}
Chris@16 176 inline operator T& () const { return v_; }
Chris@16 177
Chris@16 178 private:
Chris@16 179 addr_impl_ref & operator=(const addr_impl_ref &);
Chris@16 180 };
Chris@16 181
Chris@101 182 template<class T>
Chris@101 183 struct addressof_impl
Chris@16 184 {
Chris@16 185 static inline T * f( T & v, long )
Chris@16 186 {
Chris@16 187 return reinterpret_cast<T*>(
Chris@16 188 &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
Chris@16 189 }
Chris@16 190
Chris@16 191 static inline T * f( T * v, int )
Chris@16 192 { return v; }
Chris@16 193 };
Chris@16 194
Chris@16 195 template<class T>
Chris@16 196 inline T * addressof( T & v )
Chris@16 197 {
Chris@16 198 return ::boost::move_detail::addressof_impl<T>::f
Chris@16 199 ( ::boost::move_detail::addr_impl_ref<T>( v ), 0 );
Chris@16 200 }
Chris@16 201
Chris@101 202 //////////////////////////////////////
Chris@101 203 // has_pointer_type
Chris@101 204 //////////////////////////////////////
Chris@101 205 template <class T>
Chris@101 206 struct has_pointer_type
Chris@101 207 {
Chris@101 208 struct two { char c[2]; };
Chris@101 209 template <class U> static two test(...);
Chris@101 210 template <class U> static char test(typename U::pointer* = 0);
Chris@101 211 static const bool value = sizeof(test<T>(0)) == 1;
Chris@101 212 };
Chris@101 213
Chris@101 214 //////////////////////////////////////
Chris@101 215 // is_convertible
Chris@101 216 //////////////////////////////////////
Chris@101 217 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
Chris@101 218
Chris@101 219 //use intrinsic since in MSVC
Chris@101 220 //overaligned types can't go through ellipsis
Chris@101 221 template <class T, class U>
Chris@101 222 struct is_convertible
Chris@101 223 {
Chris@101 224 static const bool value = __is_convertible_to(T, U);
Chris@101 225 };
Chris@101 226
Chris@101 227 #else
Chris@101 228
Chris@101 229 template <class T, class U>
Chris@101 230 class is_convertible
Chris@101 231 {
Chris@101 232 typedef typename add_lvalue_reference<T>::type t_reference;
Chris@101 233 typedef char true_t;
Chris@101 234 class false_t { char dummy[2]; };
Chris@101 235 static false_t dispatch(...);
Chris@101 236 static true_t dispatch(U);
Chris@101 237 static t_reference trigger();
Chris@101 238 public:
Chris@101 239 static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
Chris@101 240 };
Chris@101 241
Chris@101 242 #endif
Chris@101 243
Chris@101 244 //////////////////////////////////////////////////////////////////////////////
Chris@101 245 //
Chris@101 246 // has_move_emulation_enabled_impl
Chris@101 247 //
Chris@101 248 //////////////////////////////////////////////////////////////////////////////
Chris@101 249 template<class T>
Chris@101 250 struct has_move_emulation_enabled_impl
Chris@101 251 : is_convertible< T, ::boost::rv<T>& >
Chris@101 252 {};
Chris@101 253
Chris@101 254 template<class T>
Chris@101 255 struct has_move_emulation_enabled_impl<T&>
Chris@101 256 { static const bool value = false; };
Chris@101 257
Chris@101 258 template<class T>
Chris@101 259 struct has_move_emulation_enabled_impl< ::boost::rv<T> >
Chris@101 260 { static const bool value = false; };
Chris@101 261
Chris@101 262 //////////////////////////////////////////////////////////////////////////////
Chris@101 263 //
Chris@101 264 // is_rv_impl
Chris@101 265 //
Chris@101 266 //////////////////////////////////////////////////////////////////////////////
Chris@101 267
Chris@101 268 template <class T>
Chris@101 269 struct is_rv_impl
Chris@101 270 { static const bool value = false; };
Chris@101 271
Chris@101 272 template <class T>
Chris@101 273 struct is_rv_impl< rv<T> >
Chris@101 274 { static const bool value = true; };
Chris@101 275
Chris@101 276 template <class T>
Chris@101 277 struct is_rv_impl< const rv<T> >
Chris@101 278 { static const bool value = true; };
Chris@101 279
Chris@101 280 // Code from Jeffrey Lee Hellrung, many thanks
Chris@101 281
Chris@101 282 template< class T >
Chris@101 283 struct is_rvalue_reference
Chris@101 284 { static const bool value = false; };
Chris@101 285
Chris@101 286 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 287
Chris@101 288 template< class T >
Chris@101 289 struct is_rvalue_reference< T&& >
Chris@101 290 { static const bool value = true; };
Chris@101 291
Chris@101 292 #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 293
Chris@101 294 template< class T >
Chris@101 295 struct is_rvalue_reference< boost::rv<T>& >
Chris@101 296 { static const bool value = true; };
Chris@101 297
Chris@101 298 template< class T >
Chris@101 299 struct is_rvalue_reference< const boost::rv<T>& >
Chris@101 300 { static const bool value = true; };
Chris@101 301
Chris@101 302 #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 303
Chris@101 304 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 305
Chris@101 306 template< class T >
Chris@101 307 struct add_rvalue_reference
Chris@101 308 { typedef T&& type; };
Chris@101 309
Chris@101 310 #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 311
Chris@101 312 namespace detail_add_rvalue_reference
Chris@101 313 {
Chris@101 314 template< class T
Chris@101 315 , bool emulation = has_move_emulation_enabled_impl<T>::value
Chris@101 316 , bool rv = is_rv_impl<T>::value >
Chris@101 317 struct add_rvalue_reference_impl { typedef T type; };
Chris@101 318
Chris@101 319 template< class T, bool emulation>
Chris@101 320 struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; };
Chris@101 321
Chris@101 322 template< class T, bool rv >
Chris@101 323 struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv<T>& type; };
Chris@101 324 } // namespace detail_add_rvalue_reference
Chris@101 325
Chris@101 326 template< class T >
Chris@101 327 struct add_rvalue_reference
Chris@101 328 : detail_add_rvalue_reference::add_rvalue_reference_impl<T>
Chris@101 329 { };
Chris@101 330
Chris@101 331 template< class T >
Chris@101 332 struct add_rvalue_reference<T &>
Chris@101 333 { typedef T & type; };
Chris@101 334
Chris@101 335 #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 336
Chris@101 337 template< class T > struct remove_rvalue_reference { typedef T type; };
Chris@101 338
Chris@101 339 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 340 template< class T > struct remove_rvalue_reference< T&& > { typedef T type; };
Chris@101 341 #else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 342 template< class T > struct remove_rvalue_reference< rv<T> > { typedef T type; };
Chris@101 343 template< class T > struct remove_rvalue_reference< const rv<T> > { typedef T type; };
Chris@101 344 template< class T > struct remove_rvalue_reference< volatile rv<T> > { typedef T type; };
Chris@101 345 template< class T > struct remove_rvalue_reference< const volatile rv<T> > { typedef T type; };
Chris@101 346 template< class T > struct remove_rvalue_reference< rv<T>& > { typedef T type; };
Chris@101 347 template< class T > struct remove_rvalue_reference< const rv<T>& > { typedef T type; };
Chris@101 348 template< class T > struct remove_rvalue_reference< volatile rv<T>& > { typedef T type; };
Chris@101 349 template< class T > struct remove_rvalue_reference< const volatile rv<T>& >{ typedef T type; };
Chris@101 350 #endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@101 351
Chris@101 352 // Ideas from Boost.Move review, Jeffrey Lee Hellrung:
Chris@101 353 //
Chris@101 354 //- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ?
Chris@101 355 // Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue
Chris@101 356 // references the same as wrt real rvalue references, i.e., add_reference< rv<T>& > -> T& rather than
Chris@101 357 // rv<T>& (since T&& & -> T&).
Chris@101 358 //
Chris@101 359 //- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...?
Chris@101 360 //
Chris@101 361 //- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated
Chris@101 362 // rvalue references in C++03. This may be necessary to prevent "accidental moves".
Chris@101 363
Chris@16 364 } //namespace move_detail {
Chris@16 365 } //namespace boost {
Chris@16 366
Chris@16 367 #endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP