/usr/include/boost/move/detail
Edit: /usr/include/boost/move/detail/meta_utils.hpp (15530B)
//////////////////////////////////////////////////////////////////////////////
//
// (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
#if defined(BOOST_HAS_PRAGMA_ONCE)
# pragma once
#endif
#include
#include //forceinline
#include
#include //for std::size_t
//Small meta-typetraits to support move
namespace boost {
//Forward declare boost::rv
template class rv;
namespace move_detail {
//////////////////////////////////////
// is_different
//////////////////////////////////////
template
struct is_different
{
static const bool value = !is_same::value;
};
//////////////////////////////////////
// apply
//////////////////////////////////////
template
struct apply
{
typedef typename F::template apply::type type;
};
//////////////////////////////////////
// bool_
//////////////////////////////////////
template< bool C_ >
struct bool_ : integral_constant
{
operator bool() const { return C_; }
bool operator()() const { return C_; }
};
typedef bool_ true_;
typedef bool_ false_;
//////////////////////////////////////
// nat
//////////////////////////////////////
struct nat{};
struct nat2{};
struct nat3{};
//////////////////////////////////////
// yes_type/no_type
//////////////////////////////////////
typedef char yes_type;
struct no_type
{
char _[2];
};
//////////////////////////////////////
// natify
//////////////////////////////////////
template struct natify{};
//////////////////////////////////////
// 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
//////////////////////////////////////
// remove_pointer
//////////////////////////////////////
template< class T > struct remove_pointer { typedef T type; };
template< class T > struct remove_pointer { typedef T type; };
template< class T > struct remove_pointer { typedef T type; };
template< class T > struct remove_pointer { typedef T type; };
template< class T > struct remove_pointer { typedef T type; };
//////////////////////////////////////
// add_pointer
//////////////////////////////////////
template< class T >
struct add_pointer
{
typedef typename remove_reference::type* type;
};
//////////////////////////////////////
// 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_lvalue_reference
//////////////////////////////////////
template
struct is_lvalue_reference
{
static const bool value = false;
};
template
struct is_lvalue_reference
{
static const bool value = true;
};
//////////////////////////////////////
// identity
//////////////////////////////////////
template
struct identity
{
typedef T type;
typedef typename add_const_lvalue_reference::type reference;
reference operator()(reference t)
{ return t; }
};
//////////////////////////////////////
// is_class_or_union
//////////////////////////////////////
template
struct is_class_or_union
{
struct twochar { char dummy[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_;
BOOST_MOVE_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {}
BOOST_MOVE_FORCEINLINE operator T& () const { return v_; }
private:
addr_impl_ref & operator=(const addr_impl_ref &);
};
template
struct addressof_impl
{
BOOST_MOVE_FORCEINLINE static T * f( T & v, long )
{
return reinterpret_cast(
&const_cast(reinterpret_cast(v)));
}
BOOST_MOVE_FORCEINLINE static T * f( T * v, int )
{ return v; }
};
template
BOOST_MOVE_FORCEINLINE 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
template ::value>
struct is_same_or_convertible
: is_convertible
{};
template
struct is_same_or_convertible
{
static const bool value = true;
};
template<
bool C
, typename F1
, typename F2
>
struct eval_if_c
: if_c::type
{};
template<
typename C
, typename T1
, typename T2
>
struct eval_if
: if_::type
{};
#if defined(BOOST_GCC) && (BOOST_GCC <= 40000)
#define BOOST_MOVE_HELPERS_RETURN_SFINAE_BROKEN
#endif
template
struct enable_if_convertible
: enable_if< is_convertible, R>
{};
template
struct disable_if_convertible
: disable_if< is_convertible, R>
{};
template
struct enable_if_same_or_convertible
: enable_if< is_same_or_convertible, R>
{};
template
struct disable_if_same_or_convertible
: disable_if< is_same_or_convertible, R>
{};
//////////////////////////////////////////////////////////////////////////////
//
// and_
//
//////////////////////////////////////////////////////////////////////////////
template
struct and_impl
: and_impl
{};
template<>
struct and_impl
{
static const bool value = true;
};
template
struct and_impl
{
static const bool value = false;
};
template
struct and_
: and_impl
{};
//////////////////////////////////////////////////////////////////////////////
//
// or_
//
//////////////////////////////////////////////////////////////////////////////
template
struct or_impl
: or_impl
{};
template<>
struct or_impl
{
static const bool value = false;
};
template
struct or_impl
{
static const bool value = true;
};
template
struct or_
: or_impl
{};
//////////////////////////////////////////////////////////////////////////////
//
// not_
//
//////////////////////////////////////////////////////////////////////////////
template
struct not_
{
static const bool value = !T::value;
};
//////////////////////////////////////////////////////////////////////////////
//
// enable_if_and / disable_if_and / enable_if_or / disable_if_or
//
//////////////////////////////////////////////////////////////////////////////
template
struct enable_if_and
: enable_if_c< and_::value, R>
{};
template
struct disable_if_and
: disable_if_c< and_::value, R>
{};
template
struct enable_if_or
: enable_if_c< or_::value, R>
{};
template
struct disable_if_or
: disable_if_c< or_::value, R>
{};
//////////////////////////////////////////////////////////////////////////////
//
// 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