diff options
author | Stefan Radomski <github@mintwerk.de> | 2016-05-12 13:12:33 (GMT) |
---|---|---|
committer | Stefan Radomski <github@mintwerk.de> | 2016-05-12 13:12:33 (GMT) |
commit | b62e7979600feee23dc7cdb61042a8fc7673122b (patch) | |
tree | f7351372f37979dd2d048e0b68a16a4cd3b2aadb /contrib/src/boost/move/detail/meta_utils.hpp | |
parent | 1b11b310be61e51b3ac5ebb83f7c8a33aef3d6e8 (diff) | |
download | uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.zip uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.gz uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.bz2 |
Major Refactoring v2.0
Diffstat (limited to 'contrib/src/boost/move/detail/meta_utils.hpp')
-rw-r--r-- | contrib/src/boost/move/detail/meta_utils.hpp | 564 |
1 files changed, 564 insertions, 0 deletions
diff --git a/contrib/src/boost/move/detail/meta_utils.hpp b/contrib/src/boost/move/detail/meta_utils.hpp new file mode 100644 index 0000000..323c13a --- /dev/null +++ b/contrib/src/boost/move/detail/meta_utils.hpp @@ -0,0 +1,564 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2012-2015. +// 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 + +#ifndef BOOST_CONFIG_HPP +# include <boost/config.hpp> +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif +#include <boost/move/detail/meta_utils_core.hpp> +#include <cstddef> //for std::size_t + +//Small meta-typetraits to support move + +namespace boost { + +//Forward declare boost::rv +template <class T> class rv; + +namespace move_detail { + +////////////////////////////////////// +// is_different +////////////////////////////////////// +template<class T, class U> +struct is_different +{ + static const bool value = !is_same<T, U>::value; +}; + +////////////////////////////////////// +// apply +////////////////////////////////////// +template<class F, class Param> +struct apply +{ + typedef typename F::template apply<Param>::type type; +}; + +////////////////////////////////////// +// bool_ +////////////////////////////////////// + +template< bool C_ > +struct bool_ : integral_constant<bool, C_> +{ + operator bool() const { return C_; } + bool operator()() const { return C_; } +}; + +typedef bool_<true> true_; +typedef bool_<false> false_; + +////////////////////////////////////// +// nat +////////////////////////////////////// +struct nat{}; + +////////////////////////////////////// +// yes_type/no_type +////////////////////////////////////// +typedef char yes_type; + +struct no_type +{ + char _[2]; +}; + +////////////////////////////////////// +// natify +////////////////////////////////////// +template <class T> struct natify{}; + +////////////////////////////////////// +// remove_reference +////////////////////////////////////// +template<class T> +struct remove_reference +{ + typedef T type; +}; + +template<class T> +struct remove_reference<T&> +{ + typedef T type; +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template<class T> +struct remove_reference<T&&> +{ + typedef T type; +}; + +#else + +template<class T> +struct remove_reference< rv<T> > +{ + typedef T type; +}; + +template<class T> +struct remove_reference< rv<T> &> +{ + typedef T type; +}; + +template<class T> +struct remove_reference< const rv<T> &> +{ + typedef T type; +}; + +#endif + +////////////////////////////////////// +// remove_pointer +////////////////////////////////////// + +template< class T > struct remove_pointer { typedef T type; }; +template< class T > struct remove_pointer<T*> { typedef T type; }; +template< class T > struct remove_pointer<T* const> { typedef T type; }; +template< class T > struct remove_pointer<T* volatile> { typedef T type; }; +template< class T > struct remove_pointer<T* const volatile> { typedef T type; }; + +////////////////////////////////////// +// add_pointer +////////////////////////////////////// +template< class T > +struct add_pointer +{ + typedef typename remove_reference<T>::type* type; +}; + +////////////////////////////////////// +// add_const +////////////////////////////////////// +template<class T> +struct add_const +{ + typedef const T type; +}; + +template<class T> +struct add_const<T&> +{ + typedef const T& type; +}; + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + +template<class T> +struct add_const<T&&> +{ + typedef T&& type; +}; + +#endif + +////////////////////////////////////// +// add_lvalue_reference +////////////////////////////////////// +template<class T> +struct add_lvalue_reference +{ typedef T& type; }; + +template<class T> struct add_lvalue_reference<T&> { typedef T& type; }; +template<> struct add_lvalue_reference<void> { typedef void type; }; +template<> struct add_lvalue_reference<const void> { typedef const void type; }; +template<> struct add_lvalue_reference<volatile void> { typedef volatile void type; }; +template<> struct add_lvalue_reference<const volatile void>{ typedef const volatile void type; }; + +template<class T> +struct add_const_lvalue_reference +{ + typedef typename remove_reference<T>::type t_unreferenced; + typedef typename add_const<t_unreferenced>::type t_unreferenced_const; + typedef typename add_lvalue_reference + <t_unreferenced_const>::type type; +}; + +////////////////////////////////////// +// is_lvalue_reference +////////////////////////////////////// +template<class T> +struct is_lvalue_reference +{ + static const bool value = false; +}; + +template<class T> +struct is_lvalue_reference<T&> +{ + static const bool value = true; +}; + + +////////////////////////////////////// +// identity +////////////////////////////////////// +template <class T> +struct identity +{ + typedef T type; + typedef typename add_const_lvalue_reference<T>::type reference; + reference operator()(reference t) + { return t; } +}; + +////////////////////////////////////// +// is_class_or_union +////////////////////////////////////// +template<class T> +struct is_class_or_union +{ + struct twochar { char dummy[2]; }; + template <class U> + static char is_class_or_union_tester(void(U::*)(void)); + template <class U> + static twochar is_class_or_union_tester(...); + static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char); +}; + +////////////////////////////////////// +// addressof +////////////////////////////////////// +template<class T> +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<class T> +struct addressof_impl +{ + static inline T * f( T & v, long ) + { + return reinterpret_cast<T*>( + &const_cast<char&>(reinterpret_cast<const volatile char &>(v))); + } + + static inline T * f( T * v, int ) + { return v; } +}; + +template<class T> +inline T * addressof( T & v ) +{ + return ::boost::move_detail::addressof_impl<T>::f + ( ::boost::move_detail::addr_impl_ref<T>( v ), 0 ); +} + +////////////////////////////////////// +// has_pointer_type +////////////////////////////////////// +template <class T> +struct has_pointer_type +{ + struct two { char c[2]; }; + template <class U> static two test(...); + template <class U> static char test(typename U::pointer* = 0); + static const bool value = sizeof(test<T>(0)) == 1; +}; + +////////////////////////////////////// +// is_convertible +////////////////////////////////////// +#if defined(_MSC_VER) && (_MSC_VER >= 1400) + +//use intrinsic since in MSVC +//overaligned types can't go through ellipsis +template <class T, class U> +struct is_convertible +{ + static const bool value = __is_convertible_to(T, U); +}; + +#else + +template <class T, class U> +class is_convertible +{ + typedef typename add_lvalue_reference<T>::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 + +template< + bool C + , typename F1 + , typename F2 + > +struct eval_if_c + : if_c<C,F1,F2>::type +{}; + +template< + typename C + , typename T1 + , typename T2 + > +struct eval_if + : if_<C,T1,T2>::type +{}; + + +#if defined(BOOST_GCC) && (BOOST_GCC <= 40000) +#define BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN +#endif + +template<class T, class U, class R = void> +struct enable_if_convertible + : enable_if< is_convertible<T, U>, R> +{}; + +template<class T, class U, class R = void> +struct disable_if_convertible + : disable_if< is_convertible<T, U>, R> +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// and_ +// +////////////////////////////////////////////////////////////////////////////// +template<bool, class B = true_, class C = true_, class D = true_> +struct and_impl + : and_impl<B::value, C, D> +{}; + +template<> +struct and_impl<true, true_, true_, true_> +{ + static const bool value = true; +}; + +template<class B, class C, class D> +struct and_impl<false, B, C, D> +{ + static const bool value = false; +}; + +template<class A, class B, class C = true_, class D = true_> +struct and_ + : and_impl<A::value, B, C, D> +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// or_ +// +////////////////////////////////////////////////////////////////////////////// +template<bool, class B = false_, class C = false_, class D = false_> +struct or_impl + : or_impl<B::value, C, D> +{}; + +template<> +struct or_impl<false, false_, false_, false_> +{ + static const bool value = false; +}; + +template<class B, class C, class D> +struct or_impl<true, B, C, D> +{ + static const bool value = true; +}; + +template<class A, class B, class C = false_, class D = false_> +struct or_ + : or_impl<A::value, B, C, D> +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// not_ +// +////////////////////////////////////////////////////////////////////////////// +template<class T> +struct not_ +{ + static const bool value = !T::value; +}; + +////////////////////////////////////////////////////////////////////////////// +// +// enable_if_and / disable_if_and / enable_if_or / disable_if_or +// +////////////////////////////////////////////////////////////////////////////// + +template<class R, class A, class B, class C = true_, class D = true_> +struct enable_if_and + : enable_if_c< and_<A, B, C, D>::value, R> +{}; + +template<class R, class A, class B, class C = true_, class D = true_> +struct disable_if_and + : disable_if_c< and_<A, B, C, D>::value, R> +{}; + +template<class R, class A, class B, class C = false_, class D = false_> +struct enable_if_or + : enable_if_c< or_<A, B, C, D>::value, R> +{}; + +template<class R, class A, class B, class C = false_, class D = false_> +struct disable_if_or + : disable_if_c< or_<A, B, C, D>::value, R> +{}; + +////////////////////////////////////////////////////////////////////////////// +// +// has_move_emulation_enabled_impl +// +////////////////////////////////////////////////////////////////////////////// +template<class T> +struct has_move_emulation_enabled_impl + : is_convertible< T, ::boost::rv<T>& > +{}; + +template<class T> +struct has_move_emulation_enabled_impl<T&> +{ static const bool value = false; }; + +template<class T> +struct has_move_emulation_enabled_impl< ::boost::rv<T> > +{ static const bool value = false; }; + +////////////////////////////////////////////////////////////////////////////// +// +// is_rv_impl +// +////////////////////////////////////////////////////////////////////////////// + +template <class T> +struct is_rv_impl +{ static const bool value = false; }; + +template <class T> +struct is_rv_impl< rv<T> > +{ static const bool value = true; }; + +template <class T> +struct is_rv_impl< const rv<T> > +{ 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<T>& > +{ static const bool value = true; }; + +template< class T > +struct is_rvalue_reference< const boost::rv<T>& > +{ 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<T>::value + , bool rv = is_rv_impl<T>::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<T>& type; }; +} // namespace detail_add_rvalue_reference + +template< class T > +struct add_rvalue_reference + : detail_add_rvalue_reference::add_rvalue_reference_impl<T> +{ }; + +template< class T > +struct add_rvalue_reference<T &> +{ 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<T> > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const rv<T> > { typedef T type; }; + template< class T > struct remove_rvalue_reference< volatile rv<T> > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const volatile rv<T> > { typedef T type; }; + template< class T > struct remove_rvalue_reference< rv<T>& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const rv<T>& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< volatile rv<T>& > { typedef T type; }; + template< class T > struct remove_rvalue_reference< const volatile rv<T>& >{ 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>& > -> T& rather than +// rv<T>& (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 { + +#endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP |