From 08c1e93fa36a49f49325a07fe91ff92c964c2b6c Mon Sep 17 00:00:00 2001 From: Chanho Park Date: Thu, 11 Dec 2014 18:55:56 +0900 Subject: Imported Upstream version 1.57.0 --- boost/move/detail/meta_utils.hpp | 476 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 476 insertions(+) create mode 100644 boost/move/detail/meta_utils.hpp (limited to 'boost/move/detail/meta_utils.hpp') diff --git a/boost/move/detail/meta_utils.hpp b/boost/move/detail/meta_utils.hpp new file mode 100644 index 0000000000..0df00864ae --- /dev/null +++ b/boost/move/detail/meta_utils.hpp @@ -0,0 +1,476 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2012-2012. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/move for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +//! \file + +#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP +#define BOOST_MOVE_DETAIL_META_UTILS_HPP + +#include +#include //for std::size_t + +//Small meta-typetraits to support move + +namespace boost { + +//Forward declare boost::rv +template class rv; + +namespace move_detail { + +////////////////////////////////////// +// nat +////////////////////////////////////// +struct nat{}; + +////////////////////////////////////// +// natify +////////////////////////////////////// +template struct natify{}; + +////////////////////////////////////// +// if_c +////////////////////////////////////// +template +struct if_c +{ + typedef T1 type; +}; + +template +struct if_c +{ + typedef T2 type; +}; + +////////////////////////////////////// +// if_ +////////////////////////////////////// +template +struct if_ +{ + typedef typename if_c<0 != T1::value, T2, T3>::type type; +}; + +//enable_if_ +template +struct enable_if_c +{ + typedef T type; +}; + +////////////////////////////////////// +// enable_if_c +////////////////////////////////////// +template +struct enable_if_c {}; + +////////////////////////////////////// +// enable_if +////////////////////////////////////// +template +struct enable_if : public enable_if_c {}; + +////////////////////////////////////// +// disable_if +////////////////////////////////////// +template +struct disable_if : public enable_if_c {}; + +////////////////////////////////////// +// integral_constant +////////////////////////////////////// +template +struct integral_constant +{ + static const T value = v; + typedef T value_type; + typedef integral_constant type; +}; + +typedef integral_constant true_type; +typedef integral_constant false_type; + +////////////////////////////////////// +// identity +////////////////////////////////////// +template +struct identity +{ + typedef T type; +}; + +////////////////////////////////////// +// remove_reference +////////////////////////////////////// +template +struct remove_reference +{ + typedef T type; +}; + +template +struct remove_reference +{ + typedef T type; +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template +struct remove_reference +{ + typedef T type; +}; + +#else + +template +struct remove_reference< rv > +{ + typedef T type; +}; + +template +struct remove_reference< rv &> +{ + typedef T type; +}; + +template +struct remove_reference< const rv &> +{ + typedef T type; +}; + + +#endif + +////////////////////////////////////// +// add_const +////////////////////////////////////// +template +struct add_const +{ + typedef const T type; +}; + +template +struct add_const +{ + typedef const T& type; +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template +struct add_const +{ + typedef T&& type; +}; + +#endif + +////////////////////////////////////// +// add_lvalue_reference +////////////////////////////////////// +template +struct add_lvalue_reference +{ + typedef T& type; +}; + +template +struct add_lvalue_reference +{ + typedef T& type; +}; + +template<> +struct add_lvalue_reference +{ + typedef void type; +}; + +template<> +struct add_lvalue_reference +{ + typedef const void type; +}; + +template<> +struct add_lvalue_reference +{ + typedef volatile void type; +}; + +template<> +struct add_lvalue_reference +{ + typedef const volatile void type; +}; + +template +struct add_const_lvalue_reference +{ + typedef typename remove_reference::type t_unreferenced; + typedef typename add_const::type t_unreferenced_const; + typedef typename add_lvalue_reference + ::type type; +}; + + +////////////////////////////////////// +// is_same +////////////////////////////////////// +template +struct is_same +{ + static const bool value = false; +}; + +template +struct is_same +{ + static const bool value = true; +}; + +////////////////////////////////////// +// is_lvalue_reference +////////////////////////////////////// +template +struct is_lvalue_reference +{ + static const bool value = false; +}; + +template +struct is_lvalue_reference +{ + static const bool value = true; +}; + +////////////////////////////////////// +// is_class_or_union +////////////////////////////////////// +template +struct is_class_or_union +{ + struct twochar { char _[2]; }; + template + static char is_class_or_union_tester(void(U::*)(void)); + template + static twochar is_class_or_union_tester(...); + static const bool value = sizeof(is_class_or_union_tester(0)) == sizeof(char); +}; + +////////////////////////////////////// +// addressof +////////////////////////////////////// +template +struct addr_impl_ref +{ + T & v_; + inline addr_impl_ref( T & v ): v_( v ) {} + inline operator T& () const { return v_; } + + private: + addr_impl_ref & operator=(const addr_impl_ref &); +}; + +template +struct addressof_impl +{ + static inline T * f( T & v, long ) + { + return reinterpret_cast( + &const_cast(reinterpret_cast(v))); + } + + static inline T * f( T * v, int ) + { return v; } +}; + +template +inline T * addressof( T & v ) +{ + return ::boost::move_detail::addressof_impl::f + ( ::boost::move_detail::addr_impl_ref( v ), 0 ); +} + +////////////////////////////////////// +// has_pointer_type +////////////////////////////////////// +template +struct has_pointer_type +{ + struct two { char c[2]; }; + template static two test(...); + template static char test(typename U::pointer* = 0); + static const bool value = sizeof(test(0)) == 1; +}; + +////////////////////////////////////// +// is_convertible +////////////////////////////////////// +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + +//use intrinsic since in MSVC +//overaligned types can't go through ellipsis +template +struct is_convertible +{ + static const bool value = __is_convertible_to(T, U); +}; + +#else + +template +class is_convertible +{ + typedef typename add_lvalue_reference::type t_reference; + typedef char true_t; + class false_t { char dummy[2]; }; + static false_t dispatch(...); + static true_t dispatch(U); + static t_reference trigger(); + public: + static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t); +}; + +#endif + +////////////////////////////////////////////////////////////////////////////// +// +// has_move_emulation_enabled_impl +// +////////////////////////////////////////////////////////////////////////////// +template +struct has_move_emulation_enabled_impl + : is_convertible< T, ::boost::rv& > +{}; + +template +struct has_move_emulation_enabled_impl +{ static const bool value = false; }; + +template +struct has_move_emulation_enabled_impl< ::boost::rv > +{ static const bool value = false; }; + +////////////////////////////////////////////////////////////////////////////// +// +// is_rv_impl +// +////////////////////////////////////////////////////////////////////////////// + +template +struct is_rv_impl +{ static const bool value = false; }; + +template +struct is_rv_impl< rv > +{ static const bool value = true; }; + +template +struct is_rv_impl< const rv > +{ static const bool value = true; }; + +// Code from Jeffrey Lee Hellrung, many thanks + +template< class T > +struct is_rvalue_reference +{ static const bool value = false; }; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template< class T > +struct is_rvalue_reference< T&& > +{ static const bool value = true; }; + +#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template< class T > +struct is_rvalue_reference< boost::rv& > +{ static const bool value = true; }; + +template< class T > +struct is_rvalue_reference< const boost::rv& > +{ static const bool value = true; }; + +#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template< class T > +struct add_rvalue_reference +{ typedef T&& type; }; + +#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +namespace detail_add_rvalue_reference +{ + template< class T + , bool emulation = has_move_emulation_enabled_impl::value + , bool rv = is_rv_impl::value > + struct add_rvalue_reference_impl { typedef T type; }; + + template< class T, bool emulation> + struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; }; + + template< class T, bool rv > + struct add_rvalue_reference_impl< T, true, rv > { typedef ::boost::rv& type; }; +} // namespace detail_add_rvalue_reference + +template< class T > +struct add_rvalue_reference + : detail_add_rvalue_reference::add_rvalue_reference_impl +{ }; + +template< class T > +struct add_rvalue_reference +{ typedef T & type; }; + +#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template< class T > struct remove_rvalue_reference { typedef T type; }; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template< class T > struct remove_rvalue_reference< T&& > { typedef T type; }; +#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template< class T > struct remove_rvalue_reference< rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< volatile rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const volatile rv > { typedef T type; }; + template< class T > struct remove_rvalue_reference< rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< volatile rv& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const volatile rv& >{ typedef T type; }; +#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +// Ideas from Boost.Move review, Jeffrey Lee Hellrung: +// +//- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ? +// Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue +// references the same as wrt real rvalue references, i.e., add_reference< rv& > -> T& rather than +// rv& (since T&& & -> T&). +// +//- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...? +// +//- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated +// rvalue references in C++03. This may be necessary to prevent "accidental moves". + +} //namespace move_detail { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP -- cgit v1.2.3