mirror of
https://git.suyu.dev/suyu/ext-boost.git
synced 2026-01-07 06:58:10 +01:00
Add container library (for static_vector)
This commit is contained in:
parent
b060148c08
commit
7dabdd81b0
166 changed files with 77078 additions and 0 deletions
274
boost/move/algorithm.hpp
Normal file
274
boost/move/algorithm.hpp
Normal file
|
|
@ -0,0 +1,274 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_ALGORITHM_HPP
|
||||
#define BOOST_MOVE_ALGORITHM_HPP
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/move/iterator.hpp>
|
||||
#include <boost/detail/no_exceptions_support.hpp>
|
||||
|
||||
#include <algorithm> //copy, copy_backward
|
||||
#include <memory> //uninitialized_copy
|
||||
|
||||
namespace boost {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
|
||||
|
||||
//! <b>Effects</b>: Moves elements in the range [first,last) into the range [result,result + (last -
|
||||
//! first)) starting from first and proceeding to last. For each non-negative integer n < (last-first),
|
||||
//! performs *(result + n) = ::boost::move (*(first + n)).
|
||||
//!
|
||||
//! <b>Effects</b>: result + (last - first).
|
||||
//!
|
||||
//! <b>Requires</b>: result shall not be in the range [first,last).
|
||||
//!
|
||||
//! <b>Complexity</b>: Exactly last - first move assignments.
|
||||
template <typename I, // I models InputIterator
|
||||
typename O> // O models OutputIterator
|
||||
O move(I f, I l, O result)
|
||||
{
|
||||
while (f != l) {
|
||||
*result = ::boost::move(*f);
|
||||
++f; ++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move_backward
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! <b>Effects</b>: Moves elements in the range [first,last) into the range
|
||||
//! [result - (last-first),result) starting from last - 1 and proceeding to
|
||||
//! first. For each positive integer n <= (last - first),
|
||||
//! performs *(result - n) = ::boost::move(*(last - n)).
|
||||
//!
|
||||
//! <b>Requires</b>: result shall not be in the range [first,last).
|
||||
//!
|
||||
//! <b>Returns</b>: result - (last - first).
|
||||
//!
|
||||
//! <b>Complexity</b>: Exactly last - first assignments.
|
||||
template <typename I, // I models BidirectionalIterator
|
||||
typename O> // O models BidirectionalIterator
|
||||
O move_backward(I f, I l, O result)
|
||||
{
|
||||
while (f != l) {
|
||||
--l; --result;
|
||||
*result = ::boost::move(*l);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
using ::std::move_backward;
|
||||
|
||||
#endif //!defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_move
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! \code
|
||||
//! for (; first != last; ++result, ++first)
|
||||
//! new (static_cast<void*>(&*result))
|
||||
//! typename iterator_traits<ForwardIterator>::value_type(boost::move(*first));
|
||||
//! \endcode
|
||||
//!
|
||||
//! <b>Returns</b>: result
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
F uninitialized_move(I f, I l, F r
|
||||
/// @cond
|
||||
// ,typename ::boost::move_detail::enable_if<has_move_emulation_enabled<typename std::iterator_traits<I>::value_type> >::type* = 0
|
||||
/// @endcond
|
||||
)
|
||||
{
|
||||
typedef typename std::iterator_traits<I>::value_type input_value_type;
|
||||
|
||||
F back = r;
|
||||
BOOST_TRY{
|
||||
while (f != l) {
|
||||
void * const addr = static_cast<void*>(::boost::move_detail::addressof(*r));
|
||||
::new(addr) input_value_type(::boost::move(*f));
|
||||
++f; ++r;
|
||||
}
|
||||
}
|
||||
BOOST_CATCH(...){
|
||||
for (; back != r; ++back){
|
||||
back->~input_value_type();
|
||||
}
|
||||
BOOST_RETHROW;
|
||||
}
|
||||
BOOST_CATCH_END
|
||||
return r;
|
||||
}
|
||||
|
||||
/// @cond
|
||||
/*
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
F uninitialized_move(I f, I l, F r,
|
||||
typename ::boost::move_detail::disable_if<has_move_emulation_enabled<typename std::iterator_traits<I>::value_type> >::type* = 0)
|
||||
{
|
||||
return std::uninitialized_copy(f, l, r);
|
||||
}
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// uninitialized_copy_or_move
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace move_detail {
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F uninitialized_move_move_iterator(I f, I l, F r
|
||||
// ,typename ::boost::move_detail::enable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0
|
||||
)
|
||||
{
|
||||
return ::boost::uninitialized_move(f, l, r);
|
||||
}
|
||||
/*
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
F uninitialized_move_move_iterator(I f, I l, F r,
|
||||
typename ::boost::move_detail::disable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0)
|
||||
{
|
||||
return std::uninitialized_copy(f.base(), l.base(), r);
|
||||
}
|
||||
*/
|
||||
} //namespace move_detail {
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F uninitialized_copy_or_move(I f, I l, F r,
|
||||
typename ::boost::move_detail::enable_if< move_detail::is_move_iterator<I> >::type* = 0)
|
||||
{
|
||||
return ::boost::move_detail::uninitialized_move_move_iterator(f, l, r);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// copy_or_move
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace move_detail {
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F move_move_iterator(I f, I l, F r
|
||||
// ,typename ::boost::move_detail::enable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0
|
||||
)
|
||||
{
|
||||
return ::boost::move(f, l, r);
|
||||
}
|
||||
/*
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
F move_move_iterator(I f, I l, F r,
|
||||
typename ::boost::move_detail::disable_if< has_move_emulation_enabled<typename I::value_type> >::type* = 0)
|
||||
{
|
||||
return std::copy(f.base(), l.base(), r);
|
||||
}
|
||||
*/
|
||||
|
||||
} //namespace move_detail {
|
||||
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F copy_or_move(I f, I l, F r,
|
||||
typename ::boost::move_detail::enable_if< move_detail::is_move_iterator<I> >::type* = 0)
|
||||
{
|
||||
return ::boost::move_detail::move_move_iterator(f, l, r);
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! \code
|
||||
//! for (; first != last; ++result, ++first)
|
||||
//! new (static_cast<void*>(&*result))
|
||||
//! typename iterator_traits<ForwardIterator>::value_type(*first);
|
||||
//! \endcode
|
||||
//!
|
||||
//! <b>Returns</b>: result
|
||||
//!
|
||||
//! <b>Note</b>: This function is provided because
|
||||
//! <i>std::uninitialized_copy</i> from some STL implementations
|
||||
//! is not compatible with <i>move_iterator</i>
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F uninitialized_copy_or_move(I f, I l, F r
|
||||
/// @cond
|
||||
,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator<I> >::type* = 0
|
||||
/// @endcond
|
||||
)
|
||||
{
|
||||
return std::uninitialized_copy(f, l, r);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>:
|
||||
//! \code
|
||||
//! for (; first != last; ++result, ++first)
|
||||
//! *result = *first;
|
||||
//! \endcode
|
||||
//!
|
||||
//! <b>Returns</b>: result
|
||||
//!
|
||||
//! <b>Note</b>: This function is provided because
|
||||
//! <i>std::uninitialized_copy</i> from some STL implementations
|
||||
//! is not compatible with <i>move_iterator</i>
|
||||
template
|
||||
<typename I, // I models InputIterator
|
||||
typename F> // F models ForwardIterator
|
||||
inline F copy_or_move(I f, I l, F r
|
||||
/// @cond
|
||||
,typename ::boost::move_detail::disable_if< move_detail::is_move_iterator<I> >::type* = 0
|
||||
/// @endcond
|
||||
)
|
||||
{
|
||||
return std::copy(f, l, r);
|
||||
}
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_ALGORITHM_HPP
|
||||
446
boost/move/core.hpp
Normal file
446
boost/move/core.hpp
Normal file
|
|
@ -0,0 +1,446 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
//! This header implements macros to define movable classes and
|
||||
//! move-aware functions
|
||||
|
||||
#ifndef BOOST_MOVE_CORE_HPP
|
||||
#define BOOST_MOVE_CORE_HPP
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
|
||||
//boost_move_no_copy_constructor_or_assign typedef
|
||||
//used to detect noncopyable types for other Boost libraries.
|
||||
#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
#define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
|
||||
private:\
|
||||
TYPE(TYPE &);\
|
||||
TYPE& operator=(TYPE &);\
|
||||
public:\
|
||||
typedef int boost_move_no_copy_constructor_or_assign; \
|
||||
private:\
|
||||
//
|
||||
#else
|
||||
#define BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE) \
|
||||
public:\
|
||||
TYPE(TYPE const &) = delete;\
|
||||
TYPE& operator=(TYPE const &) = delete;\
|
||||
public:\
|
||||
typedef int boost_move_no_copy_constructor_or_assign; \
|
||||
private:\
|
||||
//
|
||||
#endif //BOOST_NO_CXX11_DELETED_FUNCTIONS
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
#include <boost/move/detail/meta_utils.hpp>
|
||||
|
||||
//Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4) && \
|
||||
(\
|
||||
defined(BOOST_GCC) || \
|
||||
(defined(BOOST_INTEL) && (BOOST_INTEL_CXX_VERSION >= 1300)) \
|
||||
)
|
||||
#define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS __attribute__((__may_alias__))
|
||||
#else
|
||||
#define BOOST_MOVE_ATTRIBUTE_MAY_ALIAS
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// struct rv
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
template <class T>
|
||||
class rv
|
||||
: public ::boost::move_detail::if_c
|
||||
< ::boost::move_detail::is_class_or_union<T>::value
|
||||
, T
|
||||
, ::boost::move_detail::nat
|
||||
>::type
|
||||
{
|
||||
rv();
|
||||
~rv() throw();
|
||||
rv(rv const&);
|
||||
void operator=(rv const&);
|
||||
} BOOST_MOVE_ATTRIBUTE_MAY_ALIAS;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// is_rv
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace move_detail {
|
||||
|
||||
template <class T>
|
||||
struct is_rv
|
||||
//Derive from integral constant because some Boost code assummes it has
|
||||
//a "type" internal typedef
|
||||
: integral_constant<bool, ::boost::move_detail::is_rv_impl<T>::value >
|
||||
{};
|
||||
|
||||
} //namespace move_detail {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// has_move_emulation_enabled
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
template<class T>
|
||||
struct has_move_emulation_enabled
|
||||
: ::boost::move_detail::has_move_emulation_enabled_impl<T>
|
||||
{};
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
#define BOOST_RV_REF(TYPE)\
|
||||
::boost::rv< TYPE >& \
|
||||
//
|
||||
|
||||
#define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
|
||||
::boost::rv< TYPE<ARG1, ARG2> >& \
|
||||
//
|
||||
|
||||
#define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
|
||||
::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
|
||||
//
|
||||
|
||||
#define BOOST_RV_REF_BEG\
|
||||
::boost::rv< \
|
||||
//
|
||||
|
||||
#define BOOST_RV_REF_END\
|
||||
>& \
|
||||
//
|
||||
|
||||
#define BOOST_FWD_REF(TYPE)\
|
||||
const TYPE & \
|
||||
//
|
||||
|
||||
#define BOOST_COPY_ASSIGN_REF(TYPE)\
|
||||
const ::boost::rv< TYPE >& \
|
||||
//
|
||||
|
||||
#define BOOST_COPY_ASSIGN_REF_BEG \
|
||||
const ::boost::rv< \
|
||||
//
|
||||
|
||||
#define BOOST_COPY_ASSIGN_REF_END \
|
||||
>& \
|
||||
//
|
||||
|
||||
#define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
|
||||
const ::boost::rv< TYPE<ARG1, ARG2> >& \
|
||||
//
|
||||
|
||||
#define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
|
||||
const ::boost::rv< TYPE<ARG1, ARG2, ARG3> >& \
|
||||
//
|
||||
|
||||
#define BOOST_CATCH_CONST_RLVALUE(TYPE)\
|
||||
const ::boost::rv< TYPE >& \
|
||||
//
|
||||
|
||||
namespace boost {
|
||||
namespace move_detail {
|
||||
|
||||
template <class Ret, class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< ::boost::move_detail::is_lvalue_reference<Ret>::value ||
|
||||
!::boost::has_move_emulation_enabled<T>::value
|
||||
, T&>::type
|
||||
move_return(T& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class Ret, class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< !::boost::move_detail::is_lvalue_reference<Ret>::value &&
|
||||
::boost::has_move_emulation_enabled<T>::value
|
||||
, ::boost::rv<T>&>::type
|
||||
move_return(T& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return *static_cast< ::boost::rv<T>* >(::boost::move_detail::addressof(x));
|
||||
}
|
||||
|
||||
template <class Ret, class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< !::boost::move_detail::is_lvalue_reference<Ret>::value &&
|
||||
::boost::has_move_emulation_enabled<T>::value
|
||||
, ::boost::rv<T>&>::type
|
||||
move_return(::boost::rv<T>& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
} //namespace move_detail {
|
||||
} //namespace boost {
|
||||
|
||||
#define BOOST_MOVE_RET(RET_TYPE, REF)\
|
||||
boost::move_detail::move_return< RET_TYPE >(REF)
|
||||
//
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BOOST_MOVABLE_BUT_NOT_COPYABLE
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
|
||||
BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
|
||||
public:\
|
||||
operator ::boost::rv<TYPE>&() \
|
||||
{ return *static_cast< ::boost::rv<TYPE>* >(this); }\
|
||||
operator const ::boost::rv<TYPE>&() const \
|
||||
{ return *static_cast<const ::boost::rv<TYPE>* >(this); }\
|
||||
private:\
|
||||
//
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// BOOST_COPYABLE_AND_MOVABLE
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
|
||||
public:\
|
||||
TYPE& operator=(TYPE &t)\
|
||||
{ this->operator=(static_cast<const ::boost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}\
|
||||
public:\
|
||||
operator ::boost::rv<TYPE>&() \
|
||||
{ return *static_cast< ::boost::rv<TYPE>* >(this); }\
|
||||
operator const ::boost::rv<TYPE>&() const \
|
||||
{ return *static_cast<const ::boost::rv<TYPE>* >(this); }\
|
||||
private:\
|
||||
//
|
||||
|
||||
#define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
|
||||
public:\
|
||||
operator ::boost::rv<TYPE>&() \
|
||||
{ return *static_cast< ::boost::rv<TYPE>* >(this); }\
|
||||
operator const ::boost::rv<TYPE>&() const \
|
||||
{ return *static_cast<const ::boost::rv<TYPE>* >(this); }\
|
||||
private:\
|
||||
//
|
||||
|
||||
namespace boost{
|
||||
namespace move_detail{
|
||||
|
||||
template< class T>
|
||||
struct forward_type
|
||||
{ typedef const T &type; };
|
||||
|
||||
template< class T>
|
||||
struct forward_type< boost::rv<T> >
|
||||
{ typedef T type; };
|
||||
|
||||
}}
|
||||
|
||||
#else //BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
//Compiler workaround detection
|
||||
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5) && !defined(__clang__)
|
||||
//Pre-standard rvalue binding rules
|
||||
#define BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
#elif defined(_MSC_VER) && (_MSC_VER == 1600)
|
||||
//Standard rvalue binding rules but with some bugs
|
||||
#define BOOST_MOVE_MSVC_10_MEMBER_RVALUE_REF_BUG
|
||||
#define BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG
|
||||
//Use standard library for MSVC to avoid namespace issues as
|
||||
//some move calls in the STL are not fully qualified.
|
||||
//#define BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
|
||||
#elif defined(_MSC_VER) && (_MSC_VER == 1700)
|
||||
#define BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//! This macro marks a type as movable but not copyable, disabling copy construction
|
||||
//! and assignment. The user will need to write a move constructor/assignment as explained
|
||||
//! in the documentation to fully write a movable but not copyable class.
|
||||
#define BOOST_MOVABLE_BUT_NOT_COPYABLE(TYPE)\
|
||||
BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
|
||||
public:\
|
||||
typedef int boost_move_emulation_t;\
|
||||
//
|
||||
|
||||
//! This macro marks a type as copyable and movable.
|
||||
//! The user will need to write a move constructor/assignment and a copy assignment
|
||||
//! as explained in the documentation to fully write a copyable and movable class.
|
||||
#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
|
||||
//
|
||||
|
||||
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
#define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
|
||||
//
|
||||
#endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
namespace boost {
|
||||
|
||||
//!This trait yields to a compile-time true boolean if T was marked as
|
||||
//!BOOST_MOVABLE_BUT_NOT_COPYABLE or BOOST_COPYABLE_AND_MOVABLE and
|
||||
//!rvalue references are not available on the platform. False otherwise.
|
||||
template<class T>
|
||||
struct has_move_emulation_enabled
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
} //namespace boost{
|
||||
|
||||
//!This macro is used to achieve portable syntax in move
|
||||
//!constructors and assignments for classes marked as
|
||||
//!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE
|
||||
#define BOOST_RV_REF(TYPE)\
|
||||
TYPE && \
|
||||
//
|
||||
|
||||
//!This macro is used to achieve portable syntax in move
|
||||
//!constructors and assignments for template classes marked as
|
||||
//!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
|
||||
//!As macros have problems with comma-separated template arguments,
|
||||
//!the template argument must be preceded with BOOST_RV_REF_BEG
|
||||
//!and ended with BOOST_RV_REF_END
|
||||
#define BOOST_RV_REF_BEG\
|
||||
\
|
||||
//
|
||||
|
||||
//!This macro is used to achieve portable syntax in move
|
||||
//!constructors and assignments for template classes marked as
|
||||
//!BOOST_COPYABLE_AND_MOVABLE or BOOST_MOVABLE_BUT_NOT_COPYABLE.
|
||||
//!As macros have problems with comma-separated template arguments,
|
||||
//!the template argument must be preceded with BOOST_RV_REF_BEG
|
||||
//!and ended with BOOST_RV_REF_END
|
||||
#define BOOST_RV_REF_END\
|
||||
&& \
|
||||
|
||||
//!This macro is used to achieve portable syntax in copy
|
||||
//!assignment for classes marked as BOOST_COPYABLE_AND_MOVABLE.
|
||||
#define BOOST_COPY_ASSIGN_REF(TYPE)\
|
||||
const TYPE & \
|
||||
//
|
||||
|
||||
//! This macro is used to implement portable perfect forwarding
|
||||
//! as explained in the documentation.
|
||||
#define BOOST_FWD_REF(TYPE)\
|
||||
TYPE && \
|
||||
//
|
||||
|
||||
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
#define BOOST_RV_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
|
||||
TYPE<ARG1, ARG2> && \
|
||||
//
|
||||
|
||||
#define BOOST_RV_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
|
||||
TYPE<ARG1, ARG2, ARG3> && \
|
||||
//
|
||||
|
||||
#define BOOST_COPY_ASSIGN_REF_BEG \
|
||||
const \
|
||||
//
|
||||
|
||||
#define BOOST_COPY_ASSIGN_REF_END \
|
||||
& \
|
||||
//
|
||||
|
||||
#define BOOST_COPY_ASSIGN_REF_2_TEMPL_ARGS(TYPE, ARG1, ARG2)\
|
||||
const TYPE<ARG1, ARG2> & \
|
||||
//
|
||||
|
||||
#define BOOST_COPY_ASSIGN_REF_3_TEMPL_ARGS(TYPE, ARG1, ARG2, ARG3)\
|
||||
const TYPE<ARG1, ARG2, ARG3>& \
|
||||
//
|
||||
|
||||
#define BOOST_CATCH_CONST_RLVALUE(TYPE)\
|
||||
const TYPE & \
|
||||
//
|
||||
|
||||
|
||||
#endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
#if !defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
//!This macro is used to achieve portable move return semantics.
|
||||
//!The C++11 Standard allows implicit move returns when the object to be returned
|
||||
//!is designated by a lvalue and:
|
||||
//! - The criteria for elision of a copy operation are met OR
|
||||
//! - The criteria would be met save for the fact that the source object is a function parameter
|
||||
//!
|
||||
//!For C++11 conforming compilers this macros only yields to REF:
|
||||
//! <code>return BOOST_MOVE_RET(RET_TYPE, REF);</code> -> <code>return REF;</code>
|
||||
//!
|
||||
//!For compilers without rvalue references
|
||||
//!this macro does an explicit move if the move emulation is activated
|
||||
//!and the return type (RET_TYPE) is not a reference.
|
||||
//!
|
||||
//!For non-conforming compilers with rvalue references like Visual 2010 & 2012,
|
||||
//!an explicit move is performed if RET_TYPE is not a reference.
|
||||
//!
|
||||
//! <b>Caution</b>: When using this macro in non-conforming or C++03
|
||||
//!compilers, a move will be performed even if the C++11 standard does not allow it
|
||||
//!(e.g. returning a static variable). The user is responsible for using this macro
|
||||
//!only to return local objects that met C++11 criteria.
|
||||
#define BOOST_MOVE_RET(RET_TYPE, REF)\
|
||||
REF
|
||||
//
|
||||
|
||||
#else //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
#include <boost/move/detail/meta_utils.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace move_detail {
|
||||
|
||||
template <class Ret, class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< ::boost::move_detail::is_lvalue_reference<Ret>::value
|
||||
, T&>::type
|
||||
move_return(T& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class Ret, class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< !::boost::move_detail::is_lvalue_reference<Ret>::value
|
||||
, Ret && >::type
|
||||
move_return(T&& t) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast< Ret&& >(t);
|
||||
}
|
||||
|
||||
} //namespace move_detail {
|
||||
} //namespace boost {
|
||||
|
||||
#define BOOST_MOVE_RET(RET_TYPE, REF)\
|
||||
boost::move_detail::move_return< RET_TYPE >(REF)
|
||||
//
|
||||
|
||||
#endif //!defined(BOOST_MOVE_MSVC_AUTO_MOVE_RETURN_BUG) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
namespace boost {
|
||||
namespace move_detail {
|
||||
|
||||
template< class T> struct forward_type { typedef T type; };
|
||||
|
||||
}}
|
||||
|
||||
#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_CORE_HPP
|
||||
187
boost/move/default_delete.hpp
Normal file
187
boost/move/default_delete.hpp
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014. 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.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
|
||||
#define BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
#include <boost/move/detail/workaround.hpp>
|
||||
#include <boost/move/detail/unique_ptr_meta_utils.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#include <cstddef> //For std::size_t,std::nullptr_t
|
||||
|
||||
//!\file
|
||||
//! Describes the default deleter (destruction policy) of <tt>unique_ptr</tt>: <tt>default_delete</tt>.
|
||||
|
||||
namespace boost{
|
||||
namespace move_upd {
|
||||
|
||||
namespace bmupmu = ::boost::move_upmu;
|
||||
|
||||
////////////////////////////////////////
|
||||
//// enable_def_del
|
||||
////////////////////////////////////////
|
||||
|
||||
//compatible with a pointer type T*:
|
||||
//When either Y* is convertible to T*
|
||||
//Y is U[N] and T is U cv []
|
||||
template<class U, class T>
|
||||
struct def_del_compatible_cond
|
||||
: bmupmu::is_convertible<U*, T*>
|
||||
{};
|
||||
|
||||
template<class U, class T, std::size_t N>
|
||||
struct def_del_compatible_cond<U[N], T[]>
|
||||
: def_del_compatible_cond<U[], T[]>
|
||||
{};
|
||||
|
||||
template<class U, class T, class Type = bmupmu::nat>
|
||||
struct enable_def_del
|
||||
: bmupmu::enable_if_c<def_del_compatible_cond<U, T>::value, Type>
|
||||
{};
|
||||
|
||||
////////////////////////////////////////
|
||||
//// enable_defdel_call
|
||||
////////////////////////////////////////
|
||||
|
||||
//When 2nd is T[N], 1st(*)[N] shall be convertible to T(*)[N];
|
||||
//When 2nd is T[], 1st(*)[] shall be convertible to T(*)[];
|
||||
//Otherwise, 1st* shall be convertible to 2nd*.
|
||||
|
||||
template<class U, class T, class Type = bmupmu::nat>
|
||||
struct enable_defdel_call
|
||||
: public enable_def_del<U, T, Type>
|
||||
{};
|
||||
|
||||
template<class U, class T, class Type>
|
||||
struct enable_defdel_call<U, T[], Type>
|
||||
: public enable_def_del<U[], T[], Type>
|
||||
{};
|
||||
|
||||
template<class U, class T, class Type, std::size_t N>
|
||||
struct enable_defdel_call<U, T[N], Type>
|
||||
: public enable_def_del<U[N], T[N], Type>
|
||||
{};
|
||||
|
||||
////////////////////////////////////////
|
||||
//// Some bool literal zero conversion utilities
|
||||
////////////////////////////////////////
|
||||
|
||||
struct bool_conversion {int for_bool; int for_arg(); };
|
||||
typedef int bool_conversion::* explicit_bool_arg;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_CXX11_DECLTYPE)
|
||||
typedef decltype(nullptr) nullptr_type;
|
||||
#elif !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
typedef std::nullptr_t nullptr_type;
|
||||
#else
|
||||
typedef int (bool_conversion::*nullptr_type)();
|
||||
#endif
|
||||
|
||||
} //namespace move_upd {
|
||||
|
||||
namespace movelib {
|
||||
|
||||
namespace bmupd = boost::move_upd;
|
||||
namespace bmupmu = ::boost::move_upmu;
|
||||
|
||||
//!The class template <tt>default_delete</tt> serves as the default deleter
|
||||
//!(destruction policy) for the class template <tt>unique_ptr</tt>.
|
||||
//!
|
||||
//! \tparam T The type to be deleted. It may be an incomplete type
|
||||
template <class T>
|
||||
struct default_delete
|
||||
{
|
||||
//! Default constructor.
|
||||
//!
|
||||
BOOST_CONSTEXPR default_delete()
|
||||
//Avoid "defaulted on its first declaration must not have an exception-specification" error for GCC 4.6
|
||||
#if !defined(BOOST_GCC) || (BOOST_GCC < 40600 && BOOST_GCC >= 40700) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
BOOST_NOEXCEPT
|
||||
#endif
|
||||
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
= default;
|
||||
#else
|
||||
{};
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
default_delete(const default_delete&) BOOST_NOEXCEPT = default;
|
||||
default_delete &operator=(const default_delete&) BOOST_NOEXCEPT = default;
|
||||
#else
|
||||
typedef typename bmupmu::remove_extent<T>::type element_type;
|
||||
#endif
|
||||
|
||||
//! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
|
||||
//!
|
||||
//! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
||||
//! - If T is not an array type and U* is implicitly convertible to T*.
|
||||
//! - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
|
||||
template <class U>
|
||||
default_delete(const default_delete<U>&
|
||||
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_def_del<U BOOST_MOVE_I T>::type* =0)
|
||||
) BOOST_NOEXCEPT
|
||||
{
|
||||
//If T is not an array type, U derives from T
|
||||
//and T has no virtual destructor, then you have a problem
|
||||
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Constructs a default_delete object from another <tt>default_delete<U></tt> object.
|
||||
//!
|
||||
//! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
||||
//! - If T is not an array type and U* is implicitly convertible to T*.
|
||||
//! - If T is an array type and U* is a more CV qualified pointer to remove_extent<T>::type.
|
||||
template <class U>
|
||||
BOOST_MOVE_DOC1ST(default_delete&,
|
||||
typename bmupd::enable_def_del<U BOOST_MOVE_I T BOOST_MOVE_I default_delete &>::type)
|
||||
operator=(const default_delete<U>&) BOOST_NOEXCEPT
|
||||
{
|
||||
//If T is not an array type, U derives from T
|
||||
//and T has no virtual destructor, then you have a problem
|
||||
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: if T is not an array type, calls <tt>delete</tt> on static_cast<T*>(ptr),
|
||||
//! otherwise calls <tt>delete[]</tt> on static_cast<remove_extent<T>::type*>(ptr).
|
||||
//!
|
||||
//! <b>Remarks</b>: If U is an incomplete type, the program is ill-formed.
|
||||
//! This operator shall not participate in overload resolution unless:
|
||||
//! - T is not an array type and U* is convertible to T*, OR
|
||||
//! - T is an array type, and remove_cv<U>::type is the same type as
|
||||
//! remove_cv<remove_extent<T>::type>::type and U* is convertible to remove_extent<T>::type*.
|
||||
template <class U>
|
||||
BOOST_MOVE_DOC1ST(void, typename bmupd::enable_defdel_call<U BOOST_MOVE_I T BOOST_MOVE_I void>::type)
|
||||
operator()(U* ptr) const BOOST_NOEXCEPT
|
||||
{
|
||||
//U must be a complete type
|
||||
BOOST_STATIC_ASSERT(sizeof(U) > 0);
|
||||
//If T is not an array type, U derives from T
|
||||
//and T has no virtual destructor, then you have a problem
|
||||
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor<default_delete, U>::value ));
|
||||
element_type * const p = static_cast<element_type*>(ptr);
|
||||
bmupmu::is_array<T>::value ? delete [] p : delete p;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Same as <tt>(*this)(static_cast<element_type*>(nullptr))</tt>.
|
||||
//!
|
||||
void operator()(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) const BOOST_NOEXCEPT
|
||||
{ BOOST_STATIC_ASSERT(sizeof(element_type) > 0); }
|
||||
};
|
||||
|
||||
} //namespace movelib {
|
||||
} //namespace boost{
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_DEFAULT_DELETE_HPP_INCLUDED
|
||||
18
boost/move/detail/config_begin.hpp
Normal file
18
boost/move/detail/config_begin.hpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef BOOST_CONFIG_HPP
|
||||
#include <boost/config.hpp>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning (push)
|
||||
# pragma warning (disable : 4996) // "function": was declared deprecated (_CRT_SECURE_NO_DEPRECATE/_SCL_SECURE_NO_WARNINGS)
|
||||
# pragma warning (disable : 4675) // "function": resolved overload was found by argument-dependent lookup
|
||||
#endif
|
||||
12
boost/move/detail/config_end.hpp
Normal file
12
boost/move/detail/config_end.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#if defined BOOST_MSVC
|
||||
# pragma warning (pop)
|
||||
#endif
|
||||
476
boost/move/detail/meta_utils.hpp
Normal file
476
boost/move/detail/meta_utils.hpp
Normal file
|
|
@ -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 <boost/move/detail/config_begin.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 {
|
||||
|
||||
//////////////////////////////////////
|
||||
// nat
|
||||
//////////////////////////////////////
|
||||
struct nat{};
|
||||
|
||||
//////////////////////////////////////
|
||||
// natify
|
||||
//////////////////////////////////////
|
||||
template <class T> struct natify{};
|
||||
|
||||
//////////////////////////////////////
|
||||
// if_c
|
||||
//////////////////////////////////////
|
||||
template<bool C, typename T1, typename T2>
|
||||
struct if_c
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
template<typename T1, typename T2>
|
||||
struct if_c<false,T1,T2>
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// if_
|
||||
//////////////////////////////////////
|
||||
template<typename T1, typename T2, typename T3>
|
||||
struct if_
|
||||
{
|
||||
typedef typename if_c<0 != T1::value, T2, T3>::type type;
|
||||
};
|
||||
|
||||
//enable_if_
|
||||
template <bool B, class T = nat>
|
||||
struct enable_if_c
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// enable_if_c
|
||||
//////////////////////////////////////
|
||||
template <class T>
|
||||
struct enable_if_c<false, T> {};
|
||||
|
||||
//////////////////////////////////////
|
||||
// enable_if
|
||||
//////////////////////////////////////
|
||||
template <class Cond, class T = nat>
|
||||
struct enable_if : public enable_if_c<Cond::value, T> {};
|
||||
|
||||
//////////////////////////////////////
|
||||
// disable_if
|
||||
//////////////////////////////////////
|
||||
template <class Cond, class T = nat>
|
||||
struct disable_if : public enable_if_c<!Cond::value, T> {};
|
||||
|
||||
//////////////////////////////////////
|
||||
// integral_constant
|
||||
//////////////////////////////////////
|
||||
template<class T, T v>
|
||||
struct integral_constant
|
||||
{
|
||||
static const T value = v;
|
||||
typedef T value_type;
|
||||
typedef integral_constant<T, v> type;
|
||||
};
|
||||
|
||||
typedef integral_constant<bool, true > true_type;
|
||||
typedef integral_constant<bool, false > false_type;
|
||||
|
||||
//////////////////////////////////////
|
||||
// identity
|
||||
//////////////////////////////////////
|
||||
template <class T>
|
||||
struct identity
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// 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
|
||||
|
||||
//////////////////////////////////////
|
||||
// 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_same
|
||||
//////////////////////////////////////
|
||||
template<class T, class U>
|
||||
struct is_same
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_same<T, T>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// 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;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// is_class_or_union
|
||||
//////////////////////////////////////
|
||||
template<class T>
|
||||
struct is_class_or_union
|
||||
{
|
||||
struct twochar { char _[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
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 {
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
|
||||
163
boost/move/detail/move_helpers.hpp
Normal file
163
boost/move/detail/move_helpers.hpp
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2010-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.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_MOVE_MOVE_HELPERS_HPP
|
||||
#define BOOST_MOVE_MOVE_HELPERS_HPP
|
||||
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/move/detail/meta_utils.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
#define BOOST_MOVE_CATCH_CONST(U) \
|
||||
typename ::boost::move_detail::if_< ::boost::move_detail::is_class_or_union<U>, BOOST_CATCH_CONST_RLVALUE(U), const U &>::type
|
||||
#define BOOST_MOVE_CATCH_RVALUE(U)\
|
||||
typename ::boost::move_detail::if_< ::boost::move_detail::is_class_or_union<U>, BOOST_RV_REF(U), ::boost::move_detail::nat>::type
|
||||
#define BOOST_MOVE_CATCH_FWD(U) BOOST_FWD_REF(U)
|
||||
#else
|
||||
#define BOOST_MOVE_CATCH_CONST(U) const U &
|
||||
#define BOOST_MOVE_CATCH_RVALUE(U) U &&
|
||||
#define BOOST_MOVE_CATCH_FWD(U) U &&
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\
|
||||
RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\
|
||||
{ return FWD_FUNCTION(static_cast<const TYPE&>(x)); }\
|
||||
\
|
||||
RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
|
||||
{ return FWD_FUNCTION(::boost::move(x)); }\
|
||||
\
|
||||
RETURN_VALUE PUB_FUNCTION(TYPE &x)\
|
||||
{ return FWD_FUNCTION(const_cast<const TYPE &>(x)); }\
|
||||
\
|
||||
template<class BOOST_MOVE_TEMPL_PARAM>\
|
||||
typename ::boost::move_detail::enable_if_c\
|
||||
< ::boost::move_detail::is_class_or_union<TYPE>::value &&\
|
||||
::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value &&\
|
||||
!::boost::has_move_emulation_enabled<BOOST_MOVE_TEMPL_PARAM>::value\
|
||||
, RETURN_VALUE >::type\
|
||||
PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\
|
||||
{ return FWD_FUNCTION(u); }\
|
||||
\
|
||||
template<class BOOST_MOVE_TEMPL_PARAM>\
|
||||
typename ::boost::move_detail::enable_if_c\
|
||||
< (!::boost::move_detail::is_class_or_union<BOOST_MOVE_TEMPL_PARAM>::value || \
|
||||
!::boost::move_detail::is_rv<BOOST_MOVE_TEMPL_PARAM>::value) && \
|
||||
!::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value \
|
||||
, RETURN_VALUE >::type\
|
||||
PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\
|
||||
{\
|
||||
TYPE t(u);\
|
||||
return FWD_FUNCTION(::boost::move(t));\
|
||||
}\
|
||||
//
|
||||
|
||||
#elif (defined(_MSC_VER) && (_MSC_VER == 1600))
|
||||
|
||||
#define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\
|
||||
RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\
|
||||
{ return FWD_FUNCTION(static_cast<const TYPE&>(x)); }\
|
||||
\
|
||||
RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
|
||||
{ return FWD_FUNCTION(::boost::move(x)); }\
|
||||
\
|
||||
template<class BOOST_MOVE_TEMPL_PARAM>\
|
||||
typename ::boost::move_detail::enable_if_c\
|
||||
< !::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value\
|
||||
, RETURN_VALUE >::type\
|
||||
PUB_FUNCTION(const BOOST_MOVE_TEMPL_PARAM &u)\
|
||||
{\
|
||||
TYPE t(u);\
|
||||
return FWD_FUNCTION(::boost::move(t));\
|
||||
}\
|
||||
//
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_MOVE_CONVERSION_AWARE_CATCH(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION)\
|
||||
RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_CONST(TYPE) x)\
|
||||
{ return FWD_FUNCTION(static_cast<const TYPE&>(x)); }\
|
||||
\
|
||||
RETURN_VALUE PUB_FUNCTION(BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
|
||||
{ return FWD_FUNCTION(::boost::move(x)); }\
|
||||
//
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\
|
||||
RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\
|
||||
{ return FWD_FUNCTION(arg1, static_cast<const TYPE&>(x)); }\
|
||||
\
|
||||
RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
|
||||
{ return FWD_FUNCTION(arg1, ::boost::move(x)); }\
|
||||
\
|
||||
RETURN_VALUE PUB_FUNCTION(ARG1 arg1, TYPE &x)\
|
||||
{ return FWD_FUNCTION(arg1, const_cast<const TYPE &>(x)); }\
|
||||
\
|
||||
template<class BOOST_MOVE_TEMPL_PARAM>\
|
||||
typename ::boost::move_detail::enable_if_c<\
|
||||
::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value &&\
|
||||
!::boost::has_move_emulation_enabled<BOOST_MOVE_TEMPL_PARAM>::value\
|
||||
, RETURN_VALUE >::type\
|
||||
PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\
|
||||
{ return FWD_FUNCTION(arg1, u); }\
|
||||
\
|
||||
template<class BOOST_MOVE_TEMPL_PARAM>\
|
||||
typename ::boost::move_detail::enable_if_c<\
|
||||
!::boost::move_detail::is_rv<BOOST_MOVE_TEMPL_PARAM>::value && \
|
||||
!::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value && \
|
||||
!::boost::move_detail::is_convertible<BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO>::value \
|
||||
, RETURN_VALUE >::type\
|
||||
PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\
|
||||
{\
|
||||
TYPE t(u);\
|
||||
return FWD_FUNCTION(arg1, ::boost::move(t));\
|
||||
}\
|
||||
//
|
||||
|
||||
#elif (defined(_MSC_VER) && (_MSC_VER == 1600))
|
||||
|
||||
#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\
|
||||
RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\
|
||||
{ return FWD_FUNCTION(arg1, static_cast<const TYPE&>(x)); }\
|
||||
\
|
||||
RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
|
||||
{ return FWD_FUNCTION(arg1, ::boost::move(x)); }\
|
||||
\
|
||||
template<class BOOST_MOVE_TEMPL_PARAM>\
|
||||
typename ::boost::move_detail::enable_if_c\
|
||||
< !::boost::move_detail::is_same<TYPE, BOOST_MOVE_TEMPL_PARAM>::value && \
|
||||
!::boost::move_detail::is_convertible<BOOST_MOVE_TEMPL_PARAM, UNLESS_CONVERTIBLE_TO>::value \
|
||||
, RETURN_VALUE >::type\
|
||||
PUB_FUNCTION(ARG1 arg1, const BOOST_MOVE_TEMPL_PARAM &u)\
|
||||
{\
|
||||
TYPE t(u);\
|
||||
return FWD_FUNCTION(arg1, ::boost::move(t));\
|
||||
}\
|
||||
//
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(PUB_FUNCTION, TYPE, RETURN_VALUE, FWD_FUNCTION, ARG1, UNLESS_CONVERTIBLE_TO)\
|
||||
RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_CONST(TYPE) x)\
|
||||
{ return FWD_FUNCTION(arg1, static_cast<const TYPE&>(x)); }\
|
||||
\
|
||||
RETURN_VALUE PUB_FUNCTION(ARG1 arg1, BOOST_MOVE_CATCH_RVALUE(TYPE) x) \
|
||||
{ return FWD_FUNCTION(arg1, ::boost::move(x)); }\
|
||||
//
|
||||
|
||||
#endif
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_MOVE_HELPERS_HPP
|
||||
583
boost/move/detail/unique_ptr_meta_utils.hpp
Normal file
583
boost/move/detail/unique_ptr_meta_utils.hpp
Normal file
|
|
@ -0,0 +1,583 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_UNIQUE_PTR_DETAIL_META_UTILS_HPP
|
||||
#define BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
|
||||
|
||||
#include <cstddef> //for std::size_t
|
||||
|
||||
//Small meta-typetraits to support move
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace movelib {
|
||||
|
||||
template <class T>
|
||||
struct default_delete;
|
||||
|
||||
} //namespace movelib {
|
||||
|
||||
#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
//Forward declare boost::rv
|
||||
template <class T> class rv;
|
||||
#endif
|
||||
|
||||
namespace move_upmu {
|
||||
|
||||
//////////////////////////////////////
|
||||
// nat
|
||||
//////////////////////////////////////
|
||||
struct nat{};
|
||||
|
||||
//////////////////////////////////////
|
||||
// natify
|
||||
//////////////////////////////////////
|
||||
template <class T> struct natify{};
|
||||
|
||||
//////////////////////////////////////
|
||||
// if_c
|
||||
//////////////////////////////////////
|
||||
template<bool C, typename T1, typename T2>
|
||||
struct if_c
|
||||
{
|
||||
typedef T1 type;
|
||||
};
|
||||
|
||||
template<typename T1, typename T2>
|
||||
struct if_c<false,T1,T2>
|
||||
{
|
||||
typedef T2 type;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// if_
|
||||
//////////////////////////////////////
|
||||
template<typename T1, typename T2, typename T3>
|
||||
struct if_ : if_c<0 != T1::value, T2, T3>
|
||||
{};
|
||||
|
||||
//enable_if_
|
||||
template <bool B, class T = nat>
|
||||
struct enable_if_c
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// enable_if_c
|
||||
//////////////////////////////////////
|
||||
template <class T>
|
||||
struct enable_if_c<false, T> {};
|
||||
|
||||
//////////////////////////////////////
|
||||
// enable_if
|
||||
//////////////////////////////////////
|
||||
template <class Cond, class T = nat>
|
||||
struct enable_if : public enable_if_c<Cond::value, T> {};
|
||||
|
||||
//////////////////////////////////////
|
||||
// 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_const
|
||||
//////////////////////////////////////
|
||||
template< class T >
|
||||
struct remove_const
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template< class T >
|
||||
struct remove_const<const T>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// remove_volatile
|
||||
//////////////////////////////////////
|
||||
template< class T >
|
||||
struct remove_volatile
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template< class T >
|
||||
struct remove_volatile<volatile T>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// remove_cv
|
||||
//////////////////////////////////////
|
||||
template< class T >
|
||||
struct remove_cv
|
||||
{
|
||||
typedef typename remove_volatile
|
||||
<typename remove_const<T>::type>::type type;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// remove_extent
|
||||
//////////////////////////////////////
|
||||
template<class T>
|
||||
struct remove_extent
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct remove_extent<T[]>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct remove_extent<T[N]>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// extent
|
||||
//////////////////////////////////////
|
||||
|
||||
template<class T, unsigned N = 0>
|
||||
struct extent
|
||||
{
|
||||
static const std::size_t value = 0;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct extent<T[], 0>
|
||||
{
|
||||
static const std::size_t value = 0;
|
||||
};
|
||||
|
||||
template<class T, unsigned N>
|
||||
struct extent<T[], N>
|
||||
{
|
||||
static const std::size_t value = extent<T, N-1>::value;
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct extent<T[N], 0>
|
||||
{
|
||||
static const std::size_t value = N;
|
||||
};
|
||||
|
||||
template<class T, std::size_t I, unsigned N>
|
||||
struct extent<T[I], N>
|
||||
{
|
||||
static const std::size_t value = extent<T, N-1>::value;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// 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 const t_unreferenced t_unreferenced_const;
|
||||
typedef typename add_lvalue_reference
|
||||
<t_unreferenced_const>::type type;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// is_same
|
||||
//////////////////////////////////////
|
||||
template<class T, class U>
|
||||
struct is_same
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_same<T, T>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// is_pointer
|
||||
//////////////////////////////////////
|
||||
template< class T >
|
||||
struct is_pointer
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template< class T >
|
||||
struct is_pointer<T*>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// is_reference
|
||||
//////////////////////////////////////
|
||||
template< class T >
|
||||
struct is_reference
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template< class T >
|
||||
struct is_reference<T&>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
template< class T >
|
||||
struct is_reference<T&&>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////
|
||||
// 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;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// is_array
|
||||
//////////////////////////////////////
|
||||
template<class T>
|
||||
struct is_array
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct is_array<T[]>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct is_array<T[N]>
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// 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;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// pointer_type
|
||||
//////////////////////////////////////
|
||||
template <class T, class D, bool = has_pointer_type<D>::value>
|
||||
struct pointer_type_imp
|
||||
{
|
||||
typedef typename D::pointer type;
|
||||
};
|
||||
|
||||
template <class T, class D>
|
||||
struct pointer_type_imp<T, D, false>
|
||||
{
|
||||
typedef typename remove_extent<T>::type* type;
|
||||
};
|
||||
|
||||
template <class T, class D>
|
||||
struct pointer_type
|
||||
{
|
||||
typedef typename pointer_type_imp
|
||||
<typename remove_extent<T>::type, typename remove_reference<D>::type>::type type;
|
||||
};
|
||||
|
||||
//////////////////////////////////////
|
||||
// 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
|
||||
|
||||
//////////////////////////////////////
|
||||
// is_unary_function
|
||||
//////////////////////////////////////
|
||||
#if defined(BOOST_MSVC) || defined(__BORLANDC_)
|
||||
#define BOOST_MOVE_TT_DECL __cdecl
|
||||
#else
|
||||
#define BOOST_MOVE_TT_DECL
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(UNDER_CE)
|
||||
#define BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
struct is_unary_function_impl
|
||||
{ static const bool value = false; };
|
||||
|
||||
// avoid duplicate definitions of is_unary_function_impl
|
||||
#ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
|
||||
|
||||
template <typename R>
|
||||
struct is_unary_function_impl<R (*)()>
|
||||
{ static const bool value = true; };
|
||||
|
||||
template <typename R>
|
||||
struct is_unary_function_impl<R (*)(...)>
|
||||
{ static const bool value = true; };
|
||||
|
||||
#else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
|
||||
|
||||
template <typename R>
|
||||
struct is_unary_function_impl<R (__stdcall*)()>
|
||||
{ static const bool value = true; };
|
||||
|
||||
#ifndef _MANAGED
|
||||
|
||||
template <typename R>
|
||||
struct is_unary_function_impl<R (__fastcall*)()>
|
||||
{ static const bool value = true; };
|
||||
|
||||
#endif
|
||||
|
||||
template <typename R>
|
||||
struct is_unary_function_impl<R (__cdecl*)()>
|
||||
{ static const bool value = true; };
|
||||
|
||||
template <typename R>
|
||||
struct is_unary_function_impl<R (__cdecl*)(...)>
|
||||
{ static const bool value = true; };
|
||||
|
||||
#endif
|
||||
|
||||
// avoid duplicate definitions of is_unary_function_impl
|
||||
#ifndef BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
|
||||
|
||||
template <typename R, class T0>
|
||||
struct is_unary_function_impl<R (*)(T0)>
|
||||
{ static const bool value = true; };
|
||||
|
||||
template <typename R, class T0>
|
||||
struct is_unary_function_impl<R (*)(T0...)>
|
||||
{ static const bool value = true; };
|
||||
|
||||
#else // BOOST_MOVE_TT_TEST_MSC_FUNC_SIGS
|
||||
|
||||
template <typename R, class T0>
|
||||
struct is_unary_function_impl<R (__stdcall*)(T0)>
|
||||
{ static const bool value = true; };
|
||||
|
||||
#ifndef _MANAGED
|
||||
|
||||
template <typename R, class T0>
|
||||
struct is_unary_function_impl<R (__fastcall*)(T0)>
|
||||
{ static const bool value = true; };
|
||||
|
||||
#endif
|
||||
|
||||
template <typename R, class T0>
|
||||
struct is_unary_function_impl<R (__cdecl*)(T0)>
|
||||
{ static const bool value = true; };
|
||||
|
||||
template <typename R, class T0>
|
||||
struct is_unary_function_impl<R (__cdecl*)(T0...)>
|
||||
{ static const bool value = true; };
|
||||
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
struct is_unary_function_impl<T&>
|
||||
{ static const bool value = false; };
|
||||
|
||||
template<typename T>
|
||||
struct is_unary_function
|
||||
{ static const bool value = is_unary_function_impl<T>::value; };
|
||||
|
||||
//////////////////////////////////////
|
||||
// has_virtual_destructor
|
||||
//////////////////////////////////////
|
||||
#if (defined(BOOST_MSVC) && defined(BOOST_MSVC_FULL_VER) && (BOOST_MSVC_FULL_VER >=140050215))\
|
||||
|| (defined(BOOST_INTEL) && defined(_MSC_VER) && (_MSC_VER >= 1500))
|
||||
# define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
|
||||
#elif defined(BOOST_CLANG) && defined(__has_feature)
|
||||
# if __has_feature(has_virtual_destructor)
|
||||
# define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
|
||||
# endif
|
||||
#elif defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) && !defined(__GCCXML__))) && !defined(BOOST_CLANG)
|
||||
# define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
|
||||
#elif defined(__ghs__) && (__GHS_VERSION_NUMBER >= 600)
|
||||
# define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
|
||||
#elif defined(__CODEGEARC__)
|
||||
# define BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T) __has_virtual_destructor(T)
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR
|
||||
template<class T>
|
||||
struct has_virtual_destructor{ static const bool value = BOOST_MOVEUP_HAS_VIRTUAL_DESTRUCTOR(T); };
|
||||
#else
|
||||
//If no intrinsic is available you trust the programmer knows what is doing
|
||||
template<class T>
|
||||
struct has_virtual_destructor{ static const bool value = true; };
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////
|
||||
// missing_virtual_destructor
|
||||
//////////////////////////////////////
|
||||
|
||||
template< class T, class U
|
||||
, bool enable = is_convertible< U*, T*>::value &&
|
||||
!is_array<T>::value &&
|
||||
!is_same<typename remove_cv<T>::type, void>::value &&
|
||||
!is_same<typename remove_cv<U>::type, typename remove_cv<T>::type>::value
|
||||
>
|
||||
struct missing_virtual_destructor_default_delete
|
||||
{ static const bool value = !has_virtual_destructor<T>::value; };
|
||||
|
||||
template<class T, class U>
|
||||
struct missing_virtual_destructor_default_delete<T, U, false>
|
||||
{ static const bool value = false; };
|
||||
|
||||
template<class Deleter, class U>
|
||||
struct missing_virtual_destructor
|
||||
{ static const bool value = false; };
|
||||
|
||||
template<class T, class U>
|
||||
struct missing_virtual_destructor< ::boost::movelib::default_delete<T>, U >
|
||||
: missing_virtual_destructor_default_delete<T, U>
|
||||
{};
|
||||
|
||||
} //namespace move_upmu {
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_UNIQUE_PTR_DETAIL_META_UTILS_HPP
|
||||
26
boost/move/detail/workaround.hpp
Normal file
26
boost/move/detail/workaround.hpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014. 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/interprocess for documentation.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP
|
||||
#define BOOST_MOVE_DETAIL_WORKAROUND_HPP
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
#define BOOST_MOVE_PERFECT_FORWARDING
|
||||
#endif
|
||||
|
||||
//Macros for documentation purposes. For code, expands to the argument
|
||||
#define BOOST_MOVE_IMPDEF(TYPE) TYPE
|
||||
#define BOOST_MOVE_SEEDOC(TYPE) TYPE
|
||||
#define BOOST_MOVE_DOC0PTR(TYPE) TYPE
|
||||
#define BOOST_MOVE_DOC1ST(TYPE1, TYPE2) TYPE2
|
||||
#define BOOST_MOVE_I ,
|
||||
#define BOOST_MOVE_DOCIGN(T1) T1
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_DETAIL_WORKAROUND_HPP
|
||||
304
boost/move/iterator.hpp
Normal file
304
boost/move/iterator.hpp
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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_ITERATOR_HPP
|
||||
#define BOOST_MOVE_ITERATOR_HPP
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <iterator> //std::iterator
|
||||
|
||||
namespace boost {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move_iterator
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! Class template move_iterator is an iterator adaptor with the same behavior
|
||||
//! as the underlying iterator except that its dereference operator implicitly
|
||||
//! converts the value returned by the underlying iterator's dereference operator
|
||||
//! to an rvalue reference. Some generic algorithms can be called with move
|
||||
//! iterators to replace copying with moving.
|
||||
template <class It>
|
||||
class move_iterator
|
||||
{
|
||||
public:
|
||||
typedef It iterator_type;
|
||||
typedef typename std::iterator_traits<iterator_type>::value_type value_type;
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
typedef value_type && reference;
|
||||
#else
|
||||
typedef typename ::boost::move_detail::if_
|
||||
< ::boost::has_move_emulation_enabled<value_type>
|
||||
, ::boost::rv<value_type>&
|
||||
, value_type & >::type reference;
|
||||
#endif
|
||||
typedef It pointer;
|
||||
typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
|
||||
typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
|
||||
|
||||
move_iterator()
|
||||
{}
|
||||
|
||||
explicit move_iterator(It i)
|
||||
: m_it(i)
|
||||
{}
|
||||
|
||||
template <class U>
|
||||
move_iterator(const move_iterator<U>& u)
|
||||
: m_it(u.base())
|
||||
{}
|
||||
|
||||
iterator_type base() const
|
||||
{ return m_it; }
|
||||
|
||||
reference operator*() const
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
|
||||
return *m_it;
|
||||
#else
|
||||
return ::boost::move(*m_it);
|
||||
#endif
|
||||
}
|
||||
|
||||
pointer operator->() const
|
||||
{ return m_it; }
|
||||
|
||||
move_iterator& operator++()
|
||||
{ ++m_it; return *this; }
|
||||
|
||||
move_iterator<iterator_type> operator++(int)
|
||||
{ move_iterator<iterator_type> tmp(*this); ++(*this); return tmp; }
|
||||
|
||||
move_iterator& operator--()
|
||||
{ --m_it; return *this; }
|
||||
|
||||
move_iterator<iterator_type> operator--(int)
|
||||
{ move_iterator<iterator_type> tmp(*this); --(*this); return tmp; }
|
||||
|
||||
move_iterator<iterator_type> operator+ (difference_type n) const
|
||||
{ return move_iterator<iterator_type>(m_it + n); }
|
||||
|
||||
move_iterator& operator+=(difference_type n)
|
||||
{ m_it += n; return *this; }
|
||||
|
||||
move_iterator<iterator_type> operator- (difference_type n) const
|
||||
{ return move_iterator<iterator_type>(m_it - n); }
|
||||
|
||||
move_iterator& operator-=(difference_type n)
|
||||
{ m_it -= n; return *this; }
|
||||
|
||||
reference operator[](difference_type n) const
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
|
||||
return m_it[n];
|
||||
#else
|
||||
return ::boost::move(m_it[n]);
|
||||
#endif
|
||||
}
|
||||
|
||||
friend bool operator==(const move_iterator& x, const move_iterator& y)
|
||||
{ return x.base() == y.base(); }
|
||||
|
||||
friend bool operator!=(const move_iterator& x, const move_iterator& y)
|
||||
{ return x.base() != y.base(); }
|
||||
|
||||
friend bool operator< (const move_iterator& x, const move_iterator& y)
|
||||
{ return x.base() < y.base(); }
|
||||
|
||||
friend bool operator<=(const move_iterator& x, const move_iterator& y)
|
||||
{ return x.base() <= y.base(); }
|
||||
|
||||
friend bool operator> (const move_iterator& x, const move_iterator& y)
|
||||
{ return x.base() > y.base(); }
|
||||
|
||||
friend bool operator>=(const move_iterator& x, const move_iterator& y)
|
||||
{ return x.base() >= y.base(); }
|
||||
|
||||
friend difference_type operator-(const move_iterator& x, const move_iterator& y)
|
||||
{ return x.base() - y.base(); }
|
||||
|
||||
friend move_iterator operator+(difference_type n, const move_iterator& x)
|
||||
{ return move_iterator(x.base() + n); }
|
||||
|
||||
private:
|
||||
It m_it;
|
||||
};
|
||||
|
||||
//is_move_iterator
|
||||
namespace move_detail {
|
||||
|
||||
template <class I>
|
||||
struct is_move_iterator
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <class I>
|
||||
struct is_move_iterator< ::boost::move_iterator<I> >
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
} //namespace move_detail {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move_iterator
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//!
|
||||
//! <b>Returns</b>: move_iterator<It>(i).
|
||||
template<class It>
|
||||
inline move_iterator<It> make_move_iterator(const It &it)
|
||||
{ return move_iterator<It>(it); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// back_move_insert_iterator
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//! A move insert iterator that move constructs elements at the
|
||||
//! back of a container
|
||||
template <typename C> // C models Container
|
||||
class back_move_insert_iterator
|
||||
{
|
||||
C* container_m;
|
||||
|
||||
public:
|
||||
typedef C container_type;
|
||||
typedef typename C::value_type value_type;
|
||||
typedef typename C::reference reference;
|
||||
typedef typename C::pointer pointer;
|
||||
typedef typename C::difference_type difference_type;
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
|
||||
explicit back_move_insert_iterator(C& x) : container_m(&x) { }
|
||||
|
||||
back_move_insert_iterator& operator=(reference x)
|
||||
{ container_m->push_back(boost::move(x)); return *this; }
|
||||
|
||||
back_move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
|
||||
{ reference rx = x; return this->operator=(rx); }
|
||||
|
||||
back_move_insert_iterator& operator*() { return *this; }
|
||||
back_move_insert_iterator& operator++() { return *this; }
|
||||
back_move_insert_iterator& operator++(int) { return *this; }
|
||||
};
|
||||
|
||||
//!
|
||||
//! <b>Returns</b>: back_move_insert_iterator<C>(x).
|
||||
template <typename C> // C models Container
|
||||
inline back_move_insert_iterator<C> back_move_inserter(C& x)
|
||||
{
|
||||
return back_move_insert_iterator<C>(x);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// front_move_insert_iterator
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//! A move insert iterator that move constructs elements int the
|
||||
//! front of a container
|
||||
template <typename C> // C models Container
|
||||
class front_move_insert_iterator
|
||||
{
|
||||
C* container_m;
|
||||
|
||||
public:
|
||||
typedef C container_type;
|
||||
typedef typename C::value_type value_type;
|
||||
typedef typename C::reference reference;
|
||||
typedef typename C::pointer pointer;
|
||||
typedef typename C::difference_type difference_type;
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
|
||||
explicit front_move_insert_iterator(C& x) : container_m(&x) { }
|
||||
|
||||
front_move_insert_iterator& operator=(reference x)
|
||||
{ container_m->push_front(boost::move(x)); return *this; }
|
||||
|
||||
front_move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
|
||||
{ reference rx = x; return this->operator=(rx); }
|
||||
|
||||
front_move_insert_iterator& operator*() { return *this; }
|
||||
front_move_insert_iterator& operator++() { return *this; }
|
||||
front_move_insert_iterator& operator++(int) { return *this; }
|
||||
};
|
||||
|
||||
//!
|
||||
//! <b>Returns</b>: front_move_insert_iterator<C>(x).
|
||||
template <typename C> // C models Container
|
||||
inline front_move_insert_iterator<C> front_move_inserter(C& x)
|
||||
{
|
||||
return front_move_insert_iterator<C>(x);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// insert_move_iterator
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
template <typename C> // C models Container
|
||||
class move_insert_iterator
|
||||
{
|
||||
C* container_m;
|
||||
typename C::iterator pos_;
|
||||
|
||||
public:
|
||||
typedef C container_type;
|
||||
typedef typename C::value_type value_type;
|
||||
typedef typename C::reference reference;
|
||||
typedef typename C::pointer pointer;
|
||||
typedef typename C::difference_type difference_type;
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
|
||||
explicit move_insert_iterator(C& x, typename C::iterator pos)
|
||||
: container_m(&x), pos_(pos)
|
||||
{}
|
||||
|
||||
move_insert_iterator& operator=(reference x)
|
||||
{
|
||||
pos_ = container_m->insert(pos_, ::boost::move(x));
|
||||
++pos_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
move_insert_iterator& operator=(BOOST_RV_REF(value_type) x)
|
||||
{ reference rx = x; return this->operator=(rx); }
|
||||
|
||||
move_insert_iterator& operator*() { return *this; }
|
||||
move_insert_iterator& operator++() { return *this; }
|
||||
move_insert_iterator& operator++(int) { return *this; }
|
||||
};
|
||||
|
||||
//!
|
||||
//! <b>Returns</b>: move_insert_iterator<C>(x, it).
|
||||
template <typename C> // C models Container
|
||||
inline move_insert_iterator<C> move_inserter(C& x, typename C::iterator it)
|
||||
{
|
||||
return move_insert_iterator<C>(x, it);
|
||||
}
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_ITERATOR_HPP
|
||||
619
boost/move/make_unique.hpp
Normal file
619
boost/move/make_unique.hpp
Normal file
|
|
@ -0,0 +1,619 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2006-2014. 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.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
|
||||
#define BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
#include <boost/move/detail/workaround.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/move/unique_ptr.hpp>
|
||||
#include <cstddef> //for std::size_t
|
||||
#include <boost/move/detail/unique_ptr_meta_utils.hpp>
|
||||
|
||||
//!\file
|
||||
//! Defines "make_unique" functions, which are factories to create instances
|
||||
//! of unique_ptr depending on the passed arguments.
|
||||
//!
|
||||
//! This header can be a bit heavyweight in C++03 compilers due to the use of the
|
||||
//! preprocessor library, that's why it's a a separate header from <tt>unique_ptr.hpp</tt>
|
||||
|
||||
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
namespace std { //no namespace versioning in clang+libc++
|
||||
|
||||
struct nothrow_t;
|
||||
|
||||
} //namespace std {
|
||||
|
||||
namespace boost{
|
||||
namespace move_upmu {
|
||||
|
||||
//Compile time switch between
|
||||
//single element, unknown bound array
|
||||
//and known bound array
|
||||
template<class T>
|
||||
struct unique_ptr_if
|
||||
{
|
||||
typedef ::boost::movelib::unique_ptr<T> t_is_not_array;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct unique_ptr_if<T[]>
|
||||
{
|
||||
typedef ::boost::movelib::unique_ptr<T[]> t_is_array_of_unknown_bound;
|
||||
};
|
||||
|
||||
template<class T, std::size_t N>
|
||||
struct unique_ptr_if<T[N]>
|
||||
{
|
||||
typedef void t_is_array_of_known_bound;
|
||||
};
|
||||
|
||||
static std::nothrow_t *pnothrow;
|
||||
|
||||
} //namespace move_upmu {
|
||||
} //namespace boost{
|
||||
|
||||
#endif //!defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
namespace boost{
|
||||
namespace movelib {
|
||||
|
||||
#if defined(BOOST_MOVE_DOXYGEN_INVOKED) || !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
|
||||
//!
|
||||
//! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::forward<Args>(args)...))</tt>.
|
||||
template<class T, class... Args>
|
||||
inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
|
||||
make_unique(BOOST_FWD_REF(Args)... args)
|
||||
{ return unique_ptr<T>(new T(::boost::forward<Args>(args)...)); }
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
|
||||
//!
|
||||
//! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::nothrow)(std::forward<Args>(args)...))</tt>.
|
||||
template<class T, class... Args>
|
||||
inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
|
||||
make_unique_nothrow(BOOST_FWD_REF(Args)... args)
|
||||
{ return unique_ptr<T>(new (*boost::move_upmu::pnothrow)T(::boost::forward<Args>(args)...)); }
|
||||
|
||||
#else
|
||||
|
||||
//0 arg
|
||||
template<class T>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique()
|
||||
{ return unique_ptr<T>(new T()); }
|
||||
|
||||
template<class T>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique_nothrow()
|
||||
{ return unique_ptr<T>(new (*boost::move_upmu::pnothrow)T()); }
|
||||
|
||||
//1 arg
|
||||
template<class T, class P0>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique( BOOST_FWD_REF(P0) p0
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new T( ::boost::forward<P0>(p0)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<class T, class P0>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique_nothrow( BOOST_FWD_REF(P0) p0
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new (*boost::move_upmu::pnothrow)T ( ::boost::forward<P0>(p0)
|
||||
)
|
||||
);
|
||||
}
|
||||
//2 arg
|
||||
template<class T, class P0, class P1>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new T( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<class T, class P0, class P1>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique_nothrow( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new (*boost::move_upmu::pnothrow)T ( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
)
|
||||
);
|
||||
}
|
||||
//3 arg
|
||||
template<class T, class P0, class P1, class P2>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new T( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<class T, class P0, class P1, class P2>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique_nothrow ( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new (*boost::move_upmu::pnothrow)T ( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
)
|
||||
);
|
||||
}
|
||||
//4 arg
|
||||
template<class T, class P0, class P1, class P2, class P3>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new T( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<class T, class P0, class P1, class P2, class P3>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique_nothrow ( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new (*boost::move_upmu::pnothrow)T ( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
)
|
||||
);
|
||||
}
|
||||
//5 arg
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new T( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique_nothrow ( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new (*boost::move_upmu::pnothrow)T ( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
)
|
||||
);
|
||||
}
|
||||
//6 arg
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4, class P5>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
, BOOST_FWD_REF(P5) p5
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new T( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
, ::boost::forward<P5>(p5)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4, class P5>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique_nothrow ( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
, BOOST_FWD_REF(P5) p5
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new (*boost::move_upmu::pnothrow)T ( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
, ::boost::forward<P5>(p5)
|
||||
)
|
||||
);
|
||||
}
|
||||
//7 arg
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4, class P5, class P6>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
, BOOST_FWD_REF(P5) p5
|
||||
, BOOST_FWD_REF(P6) p6
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new T( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
, ::boost::forward<P5>(p5)
|
||||
, ::boost::forward<P6>(p6)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4, class P5, class P6>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique_nothrow ( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
, BOOST_FWD_REF(P5) p5
|
||||
, BOOST_FWD_REF(P6) p6
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new (*boost::move_upmu::pnothrow)T ( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
, ::boost::forward<P5>(p5)
|
||||
, ::boost::forward<P6>(p6)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//8 arg
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
, BOOST_FWD_REF(P5) p5
|
||||
, BOOST_FWD_REF(P6) p6
|
||||
, BOOST_FWD_REF(P7) p7
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new T( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
, ::boost::forward<P5>(p5)
|
||||
, ::boost::forward<P6>(p6)
|
||||
, ::boost::forward<P7>(p7)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique_nothrow ( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
, BOOST_FWD_REF(P5) p5
|
||||
, BOOST_FWD_REF(P6) p6
|
||||
, BOOST_FWD_REF(P7) p7
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new (*boost::move_upmu::pnothrow)T ( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
, ::boost::forward<P5>(p5)
|
||||
, ::boost::forward<P6>(p6)
|
||||
, ::boost::forward<P7>(p7)
|
||||
)
|
||||
);
|
||||
}
|
||||
//9 arg
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
, BOOST_FWD_REF(P5) p5
|
||||
, BOOST_FWD_REF(P6) p6
|
||||
, BOOST_FWD_REF(P7) p7
|
||||
, BOOST_FWD_REF(P8) p8
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new T( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
, ::boost::forward<P5>(p5)
|
||||
, ::boost::forward<P6>(p6)
|
||||
, ::boost::forward<P7>(p7)
|
||||
, ::boost::forward<P8>(p8)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique_nothrow ( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
, BOOST_FWD_REF(P5) p5
|
||||
, BOOST_FWD_REF(P6) p6
|
||||
, BOOST_FWD_REF(P7) p7
|
||||
, BOOST_FWD_REF(P8) p8
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new (*boost::move_upmu::pnothrow)T ( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
, ::boost::forward<P5>(p5)
|
||||
, ::boost::forward<P6>(p6)
|
||||
, ::boost::forward<P7>(p7)
|
||||
, ::boost::forward<P8>(p8)
|
||||
)
|
||||
);
|
||||
}
|
||||
//10 arg
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
, BOOST_FWD_REF(P5) p5
|
||||
, BOOST_FWD_REF(P6) p6
|
||||
, BOOST_FWD_REF(P7) p7
|
||||
, BOOST_FWD_REF(P8) p8
|
||||
, BOOST_FWD_REF(P9) p9
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new T( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
, ::boost::forward<P5>(p5)
|
||||
, ::boost::forward<P6>(p6)
|
||||
, ::boost::forward<P7>(p7)
|
||||
, ::boost::forward<P8>(p8)
|
||||
, ::boost::forward<P9>(p9)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
template<class T, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array
|
||||
make_unique_nothrow ( BOOST_FWD_REF(P0) p0
|
||||
, BOOST_FWD_REF(P1) p1
|
||||
, BOOST_FWD_REF(P2) p2
|
||||
, BOOST_FWD_REF(P3) p3
|
||||
, BOOST_FWD_REF(P4) p4
|
||||
, BOOST_FWD_REF(P5) p5
|
||||
, BOOST_FWD_REF(P6) p6
|
||||
, BOOST_FWD_REF(P7) p7
|
||||
, BOOST_FWD_REF(P8) p8
|
||||
, BOOST_FWD_REF(P9) p9
|
||||
)
|
||||
{
|
||||
return unique_ptr<T>
|
||||
( new (*boost::move_upmu::pnothrow)T ( ::boost::forward<P0>(p0)
|
||||
, ::boost::forward<P1>(p1)
|
||||
, ::boost::forward<P2>(p2)
|
||||
, ::boost::forward<P3>(p3)
|
||||
, ::boost::forward<P4>(p4)
|
||||
, ::boost::forward<P5>(p5)
|
||||
, ::boost::forward<P6>(p6)
|
||||
, ::boost::forward<P7>(p7)
|
||||
, ::boost::forward<P8>(p8)
|
||||
, ::boost::forward<P9>(p9)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
|
||||
//!
|
||||
//! <b>Returns</b>: <tt>unique_ptr<T>(new T)</tt> (default initialization)
|
||||
template<class T>
|
||||
inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
|
||||
make_unique_definit()
|
||||
{
|
||||
return unique_ptr<T>(new T);
|
||||
}
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is not an array.
|
||||
//!
|
||||
//! <b>Returns</b>: <tt>unique_ptr<T>(new T(std::nothrow)</tt> (default initialization)
|
||||
template<class T>
|
||||
inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_not_array)
|
||||
make_unique_nothrow_definit()
|
||||
{
|
||||
return unique_ptr<T>(new (*boost::move_upmu::pnothrow)T);
|
||||
}
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
|
||||
//! unknown bound.
|
||||
//!
|
||||
//! <b>Returns</b>: <tt>unique_ptr<T>(new remove_extent_t<T>[n]())</tt> (value initialization)
|
||||
template<class T>
|
||||
inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
|
||||
make_unique(std::size_t n)
|
||||
{
|
||||
typedef typename ::boost::move_upmu::remove_extent<T>::type U;
|
||||
return unique_ptr<T>(new U[n]());
|
||||
}
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
|
||||
//! unknown bound.
|
||||
//!
|
||||
//! <b>Returns</b>: <tt>unique_ptr<T>(new (std::nothrow)remove_extent_t<T>[n]())</tt> (value initialization)
|
||||
template<class T>
|
||||
inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
|
||||
make_unique_nothrow(std::size_t n)
|
||||
{
|
||||
typedef typename ::boost::move_upmu::remove_extent<T>::type U;
|
||||
return unique_ptr<T>(new (*boost::move_upmu::pnothrow)U[n]());
|
||||
}
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
|
||||
//! unknown bound.
|
||||
//!
|
||||
//! <b>Returns</b>: <tt>unique_ptr<T>(new remove_extent_t<T>[n])</tt> (default initialization)
|
||||
template<class T>
|
||||
inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
|
||||
make_unique_definit(std::size_t n)
|
||||
{
|
||||
typedef typename ::boost::move_upmu::remove_extent<T>::type U;
|
||||
return unique_ptr<T>(new U[n]);
|
||||
}
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is an array of
|
||||
//! unknown bound.
|
||||
//!
|
||||
//! <b>Returns</b>: <tt>unique_ptr<T>(new (std::nothrow)remove_extent_t<T>[n])</tt> (default initialization)
|
||||
template<class T>
|
||||
inline BOOST_MOVE_DOC1ST(unique_ptr<T>,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_unknown_bound)
|
||||
make_unique_nothrow_definit(std::size_t n)
|
||||
{
|
||||
typedef typename ::boost::move_upmu::remove_extent<T>::type U;
|
||||
return unique_ptr<T>(new (*boost::move_upmu::pnothrow) U[n]);
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
|
||||
//! an array of known bound.
|
||||
template<class T, class... Args>
|
||||
inline BOOST_MOVE_DOC1ST(unspecified,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
|
||||
make_unique(BOOST_FWD_REF(Args) ...) = delete;
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
|
||||
//! an array of known bound.
|
||||
template<class T, class... Args>
|
||||
inline BOOST_MOVE_DOC1ST(unspecified,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
|
||||
make_unique_definit(BOOST_FWD_REF(Args) ...) = delete;
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
|
||||
//! an array of known bound.
|
||||
template<class T, class... Args>
|
||||
inline BOOST_MOVE_DOC1ST(unspecified,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
|
||||
make_unique_nothrow(BOOST_FWD_REF(Args) ...) = delete;
|
||||
|
||||
//! <b>Remarks</b>: This function shall not participate in overload resolution unless T is
|
||||
//! an array of known bound.
|
||||
template<class T, class... Args>
|
||||
inline BOOST_MOVE_DOC1ST(unspecified,
|
||||
typename ::boost::move_upmu::unique_ptr_if<T>::t_is_array_of_known_bound)
|
||||
make_unique_nothrow_definit(BOOST_FWD_REF(Args) ...) = delete;
|
||||
|
||||
#endif
|
||||
|
||||
} //namespace movelib {
|
||||
|
||||
} //namespace boost{
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_MAKE_UNIQUE_HPP_INCLUDED
|
||||
27
boost/move/move.hpp
Normal file
27
boost/move/move.hpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright David Abrahams, Vicente Botet 2009.
|
||||
// (C) Copyright Ion Gaztanaga 2009-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
|
||||
//! A general library header that includes
|
||||
//! the rest of top-level headers.
|
||||
|
||||
#ifndef BOOST_MOVE_MOVE_HPP
|
||||
#define BOOST_MOVE_MOVE_HPP
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/move/iterator.hpp>
|
||||
#include <boost/move/traits.hpp>
|
||||
#include <boost/move/algorithm.hpp>
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_MOVE_HPP
|
||||
72
boost/move/traits.hpp
Normal file
72
boost/move/traits.hpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2009-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_MOVE_TRAITS_HPP
|
||||
#define BOOST_MOVE_MOVE_TRAITS_HPP
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
||||
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
|
||||
#include <boost/type_traits/is_copy_constructible.hpp>
|
||||
#include <boost/move/detail/meta_utils.hpp>
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
#include <boost/move/core.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
//! If this trait yields to true
|
||||
//! (<i>has_trivial_destructor_after_move <T>::value == true</i>)
|
||||
//! means that if T is used as argument of a move construction/assignment,
|
||||
//! there is no need to call T's destructor.
|
||||
//! This optimization tipically is used to improve containers' performance.
|
||||
//!
|
||||
//! By default this trait is true if the type has trivial destructor,
|
||||
//! every class should specialize this trait if it wants to improve performance
|
||||
//! when inserted in containers.
|
||||
template <class T>
|
||||
struct has_trivial_destructor_after_move
|
||||
: ::boost::has_trivial_destructor<T>
|
||||
{};
|
||||
|
||||
//! By default this traits returns
|
||||
//! <pre>boost::is_nothrow_move_constructible<T>::value && boost::is_nothrow_move_assignable<T>::value </pre>.
|
||||
//! Classes with non-throwing move constructor
|
||||
//! and assignment can specialize this trait to obtain some performance improvements.
|
||||
template <class T>
|
||||
struct has_nothrow_move
|
||||
{
|
||||
static const bool value = boost::is_nothrow_move_constructible<T>::value &&
|
||||
boost::is_nothrow_move_assignable<T>::value;
|
||||
};
|
||||
|
||||
namespace move_detail {
|
||||
|
||||
template <class T>
|
||||
struct is_nothrow_move_constructible_or_uncopyable
|
||||
{
|
||||
//The standard requires is_nothrow_move_constructible for move_if_noexcept
|
||||
//but a user (usually in C++03) might specialize has_nothrow_move which includes it
|
||||
static const bool value = boost::is_nothrow_move_constructible<T>::value ||
|
||||
has_nothrow_move<T>::value ||
|
||||
!boost::is_copy_constructible<T>::value;
|
||||
};
|
||||
|
||||
} //move_detail {
|
||||
} //namespace boost {
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_MOVE_TRAITS_HPP
|
||||
855
boost/move/unique_ptr.hpp
Normal file
855
boost/move/unique_ptr.hpp
Normal file
|
|
@ -0,0 +1,855 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (C) Copyright Ion Gaztanaga 2014-2014. 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.
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
|
||||
#define BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
#include <boost/move/detail/workaround.hpp>
|
||||
#include <boost/move/detail/unique_ptr_meta_utils.hpp>
|
||||
#include <boost/move/default_delete.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <cstddef> //For std::nullptr_t and std::size_t
|
||||
|
||||
//!\file
|
||||
//! Describes the smart pointer unique_ptr, a drop-in replacement for std::unique_ptr,
|
||||
//! usable also from C++03 compilers.
|
||||
//!
|
||||
//! Main differences from std::unique_ptr to avoid heavy dependencies,
|
||||
//! specially in C++03 compilers:
|
||||
//! - <tt>operator < </tt> uses pointer <tt>operator < </tt>instead of <tt>std::less<common_type></tt>.
|
||||
//! This avoids dependencies on <tt>std::common_type</tt> and <tt>std::less</tt>
|
||||
//! (<tt><type_traits>/<functional></tt> headers. In C++03 this avoid pulling Boost.Typeof and other
|
||||
//! cascading dependencies. As in all Boost platforms <tt>operator <</tt> on raw pointers and
|
||||
//! other smart pointers provides strict weak ordering in practice this should not be a problem for users.
|
||||
//! - assignable from literal 0 for compilers without nullptr
|
||||
//! - <tt>unique_ptr<T[]></tt> is constructible and assignable from <tt>unique_ptr<U[]></tt> if
|
||||
//! cv-less T and cv-less U are the same type and T is more CV qualified than U.
|
||||
|
||||
namespace boost{
|
||||
namespace move_upd {
|
||||
|
||||
////////////////////////////////////////////
|
||||
// deleter types
|
||||
////////////////////////////////////////////
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
template <class T>
|
||||
class is_noncopyable
|
||||
{
|
||||
typedef char true_t;
|
||||
class false_t { char dummy[2]; };
|
||||
template<class U> static false_t dispatch(...);
|
||||
template<class U> static true_t dispatch(typename U::boost_move_no_copy_constructor_or_assign*);
|
||||
public:
|
||||
static const bool value = sizeof(dispatch<T>(0)) == sizeof(true_t);
|
||||
};
|
||||
#endif //defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
|
||||
template <class D>
|
||||
struct deleter_types
|
||||
{
|
||||
typedef typename bmupmu::add_lvalue_reference<D>::type del_ref;
|
||||
typedef typename bmupmu::add_const_lvalue_reference<D>::type del_cref;
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
typedef typename bmupmu::if_c
|
||||
< bmupmu::is_lvalue_reference<D>::value, D, del_cref >::type deleter_arg_type1;
|
||||
typedef typename bmupmu::remove_reference<D>::type && deleter_arg_type2;
|
||||
#else
|
||||
typedef typename bmupmu::if_c
|
||||
< is_noncopyable<D>::value, bmupmu::nat, del_cref>::type non_ref_deleter_arg1;
|
||||
typedef typename bmupmu::if_c< bmupmu::is_lvalue_reference<D>::value
|
||||
, D, non_ref_deleter_arg1 >::type deleter_arg_type1;
|
||||
typedef ::boost::rv<D> & deleter_arg_type2;
|
||||
#endif
|
||||
};
|
||||
|
||||
////////////////////////////////////////////
|
||||
// unique_ptr_data
|
||||
////////////////////////////////////////////
|
||||
template <class P, class D, bool = bmupmu::is_unary_function<D>::value || bmupmu::is_reference<D>::value >
|
||||
struct unique_ptr_data
|
||||
{
|
||||
typedef typename deleter_types<D>::deleter_arg_type1 deleter_arg_type1;
|
||||
typedef typename deleter_types<D>::del_ref del_ref;
|
||||
typedef typename deleter_types<D>::del_cref del_cref;
|
||||
|
||||
unique_ptr_data() BOOST_NOEXCEPT
|
||||
: m_p(), d()
|
||||
{}
|
||||
|
||||
explicit unique_ptr_data(P p) BOOST_NOEXCEPT
|
||||
: m_p(p), d()
|
||||
{}
|
||||
|
||||
unique_ptr_data(P p, deleter_arg_type1 d1) BOOST_NOEXCEPT
|
||||
: m_p(p), d(d1)
|
||||
{}
|
||||
|
||||
template <class U>
|
||||
unique_ptr_data(P p, BOOST_FWD_REF(U) d) BOOST_NOEXCEPT
|
||||
: m_p(p), d(::boost::forward<U>(d))
|
||||
{}
|
||||
|
||||
del_ref deleter() { return d; }
|
||||
del_cref deleter() const{ return d; }
|
||||
|
||||
P m_p;
|
||||
D d;
|
||||
|
||||
private:
|
||||
unique_ptr_data& operator=(const unique_ptr_data&);
|
||||
unique_ptr_data(const unique_ptr_data&);
|
||||
};
|
||||
|
||||
template <class P, class D>
|
||||
struct unique_ptr_data<P, D, false>
|
||||
: private D
|
||||
{
|
||||
typedef typename deleter_types<D>::deleter_arg_type1 deleter_arg_type1;
|
||||
typedef typename deleter_types<D>::del_ref del_ref;
|
||||
typedef typename deleter_types<D>::del_cref del_cref;
|
||||
|
||||
unique_ptr_data() BOOST_NOEXCEPT
|
||||
: D(), m_p()
|
||||
{}
|
||||
|
||||
explicit unique_ptr_data(P p) BOOST_NOEXCEPT
|
||||
: D(), m_p(p)
|
||||
{}
|
||||
|
||||
unique_ptr_data(P p, deleter_arg_type1 d1) BOOST_NOEXCEPT
|
||||
: D(d1), m_p(p)
|
||||
{}
|
||||
|
||||
template <class U>
|
||||
unique_ptr_data(P p, BOOST_FWD_REF(U) d) BOOST_NOEXCEPT
|
||||
: D(::boost::forward<U>(d)), m_p(p)
|
||||
{}
|
||||
|
||||
del_ref deleter() BOOST_NOEXCEPT { return static_cast<del_ref>(*this); }
|
||||
del_cref deleter() const BOOST_NOEXCEPT { return static_cast<del_cref>(*this); }
|
||||
|
||||
P m_p;
|
||||
|
||||
private:
|
||||
unique_ptr_data& operator=(const unique_ptr_data&);
|
||||
unique_ptr_data(const unique_ptr_data&);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////
|
||||
// is_unique_ptr_convertible
|
||||
////////////////////////////////////////////
|
||||
|
||||
//Although non-standard, we avoid using pointer_traits
|
||||
//to avoid heavy dependencies
|
||||
template <typename T>
|
||||
struct get_element_type
|
||||
{
|
||||
struct DefaultWrap { typedef bmupmu::natify<T> element_type; };
|
||||
template <typename X> static char test(int, typename X::element_type*);
|
||||
template <typename X> static int test(...);
|
||||
static const bool value = (1 == sizeof(test<T>(0, 0)));
|
||||
typedef typename bmupmu::if_c<value, T, DefaultWrap>::type::element_type type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct get_element_type<T*>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
struct get_cvelement
|
||||
: bmupmu::remove_cv<typename get_element_type<T>::type>
|
||||
{};
|
||||
|
||||
template <class P1, class P2>
|
||||
struct is_same_cvelement_and_convertible
|
||||
{
|
||||
typedef typename bmupmu::remove_reference<P1>::type arg1;
|
||||
typedef typename bmupmu::remove_reference<P2>::type arg2;
|
||||
static const bool same_cvless =
|
||||
bmupmu::is_same<typename get_cvelement<arg1>::type,typename get_cvelement<arg2>::type>::value;
|
||||
static const bool value = same_cvless && bmupmu::is_convertible<arg1, arg2>::value;
|
||||
};
|
||||
|
||||
template<bool IsArray, class FromPointer, class ThisPointer>
|
||||
struct is_unique_ptr_convertible
|
||||
: is_same_cvelement_and_convertible<FromPointer, ThisPointer>
|
||||
{};
|
||||
|
||||
template<class FromPointer, class ThisPointer>
|
||||
struct is_unique_ptr_convertible<false, FromPointer, ThisPointer>
|
||||
: bmupmu::is_convertible<FromPointer, ThisPointer>
|
||||
{};
|
||||
|
||||
////////////////////////////////////////
|
||||
//// enable_up_moveconv_assign
|
||||
////////////////////////////////////////
|
||||
|
||||
template<class T, class FromPointer, class ThisPointer, class Type = bmupmu::nat>
|
||||
struct enable_up_ptr
|
||||
: bmupmu::enable_if_c< is_unique_ptr_convertible
|
||||
< bmupmu::is_array<T>::value, FromPointer, ThisPointer>::value, Type>
|
||||
{};
|
||||
|
||||
////////////////////////////////////////
|
||||
//// enable_up_moveconv_assign
|
||||
////////////////////////////////////////
|
||||
|
||||
template<class T, class D, class U, class E>
|
||||
struct unique_moveconvert_assignable
|
||||
{
|
||||
static const bool value = (bmupmu::extent<T>::value == bmupmu::extent<U>::value) && is_unique_ptr_convertible
|
||||
< bmupmu::is_array<T>::value
|
||||
, typename bmupmu::pointer_type<U, E>::type, typename bmupmu::pointer_type<T, D>::type>::value;
|
||||
};
|
||||
|
||||
template<class T, class D, class U, class E, std::size_t N>
|
||||
struct unique_moveconvert_assignable<T[], D, U[N], E>
|
||||
: unique_moveconvert_assignable<T[], D, U[], E>
|
||||
{};
|
||||
|
||||
template<class T, class D, class U, class E, class Type = bmupmu::nat>
|
||||
struct enable_up_moveconv_assign
|
||||
: bmupmu::enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value, Type>
|
||||
{};
|
||||
|
||||
////////////////////////////////////////
|
||||
//// enable_up_moveconv_constr
|
||||
////////////////////////////////////////
|
||||
|
||||
template<class D, class E, bool IsReference = bmupmu::is_reference<D>::value>
|
||||
struct unique_deleter_is_initializable
|
||||
: bmupmu::is_same<D, E>
|
||||
{};
|
||||
|
||||
template <class T, class U>
|
||||
class is_rvalue_convertible
|
||||
{
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
typedef typename bmupmu::remove_reference<T>::type&& t_from;
|
||||
#else
|
||||
typedef typename bmupmu::if_c
|
||||
< ::boost::has_move_emulation_enabled<T>::value && !bmupmu::is_reference<T>::value
|
||||
, ::boost::rv<T>&
|
||||
, typename bmupmu::add_lvalue_reference<T>::type
|
||||
>::type t_from;
|
||||
#endif
|
||||
|
||||
typedef char true_t;
|
||||
class false_t { char dummy[2]; };
|
||||
static false_t dispatch(...);
|
||||
static true_t dispatch(U);
|
||||
static t_from trigger();
|
||||
public:
|
||||
static const bool value = sizeof(dispatch(trigger())) == sizeof(true_t);
|
||||
};
|
||||
|
||||
template<class D, class E>
|
||||
struct unique_deleter_is_initializable<D, E, false>
|
||||
{
|
||||
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
//Clang has some problems with is_rvalue_convertible with non-copyable types
|
||||
//so use intrinsic if available
|
||||
#if defined(BOOST_CLANG)
|
||||
#if __has_feature(is_convertible_to)
|
||||
static const bool value = __is_convertible_to(E, D);
|
||||
#else
|
||||
static const bool value = is_rvalue_convertible<E, D>::value;
|
||||
#endif
|
||||
#else
|
||||
static const bool value = is_rvalue_convertible<E, D>::value;
|
||||
#endif
|
||||
|
||||
#else //!defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
|
||||
//No hope for compilers with move emulation for now. In several compilers is_convertible
|
||||
// leads to errors, so just move the Deleter and see if the conversion works
|
||||
static const bool value = true; /*is_rvalue_convertible<E, D>::value*/
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class T, class D, class U, class E, class Type = bmupmu::nat>
|
||||
struct enable_up_moveconv_constr
|
||||
: bmupmu::enable_if_c<unique_moveconvert_assignable<T, D, U, E>::value &&
|
||||
unique_deleter_is_initializable<D, E>::value, Type>
|
||||
{};
|
||||
|
||||
} //namespace move_upd {
|
||||
|
||||
namespace movelib {
|
||||
|
||||
//! A unique pointer is an object that owns another object and
|
||||
//! manages that other object through a pointer.
|
||||
//!
|
||||
//! More precisely, a unique pointer is an object u that stores a pointer to a second object p and will dispose
|
||||
//! of p when u is itself destroyed (e.g., when leaving block scope). In this context, u is said to own p.
|
||||
//!
|
||||
//! The mechanism by which u disposes of p is known as p's associated deleter, a function object whose correct
|
||||
//! invocation results in p's appropriate disposition (typically its deletion).
|
||||
//!
|
||||
//! Let the notation u.p denote the pointer stored by u, and let u.d denote the associated deleter. Upon request,
|
||||
//! u can reset (replace) u.p and u.d with another pointer and deleter, but must properly dispose of its owned
|
||||
//! object via the associated deleter before such replacement is considered completed.
|
||||
//!
|
||||
//! Additionally, u can, upon request, transfer ownership to another unique pointer u2. Upon completion of
|
||||
//! such a transfer, the following postconditions hold:
|
||||
//! - u2.p is equal to the pre-transfer u.p,
|
||||
//! - u.p is equal to nullptr, and
|
||||
//! - if the pre-transfer u.d maintained state, such state has been transferred to u2.d.
|
||||
//!
|
||||
//! As in the case of a reset, u2 must properly dispose of its pre-transfer owned object via the pre-transfer
|
||||
//! associated deleter before the ownership transfer is considered complete.
|
||||
//!
|
||||
//! Each object of a type U instantiated from the unique_ptr template specified in this subclause has the strict
|
||||
//! ownership semantics, specified above, of a unique pointer. In partial satisfaction of these semantics, each
|
||||
//! such U is MoveConstructible and MoveAssignable, but is not CopyConstructible nor CopyAssignable.
|
||||
//! The template parameter T of unique_ptr may be an incomplete type.
|
||||
//!
|
||||
//! The uses of unique_ptr include providing exception safety for dynamically allocated memory, passing
|
||||
//! ownership of dynamically allocated memory to a function, and returning dynamically allocated memory from
|
||||
//! a function.
|
||||
//!
|
||||
//! If T is an array type (e.g. unique_ptr<MyType[]>) the interface is slightly altered:
|
||||
//! - Pointers to types derived from T are rejected by the constructors, and by reset.
|
||||
//! - The observers <tt>operator*</tt> and <tt>operator-></tt> are not provided.
|
||||
//! - The indexing observer <tt>operator[]</tt> is provided.
|
||||
//!
|
||||
//! \tparam T Provides the type of the stored pointer.
|
||||
//! \tparam D The deleter type:
|
||||
//! - The default type for the template parameter D is default_delete. A client-supplied template argument
|
||||
//! D shall be a function object type, lvalue-reference to function, or lvalue-reference to function object type
|
||||
//! for which, given a value d of type D and a value ptr of type unique_ptr<T, D>::pointer, the expression
|
||||
//! d(ptr) is valid and has the effect of disposing of the pointer as appropriate for that deleter.
|
||||
//! - If the deleter's type D is not a reference type, D shall satisfy the requirements of Destructible.
|
||||
//! - If the type <tt>remove_reference<D>::type::pointer</tt> exists, it shall satisfy the requirements of NullablePointer.
|
||||
template <class T, class D = default_delete<T> >
|
||||
class unique_ptr
|
||||
{
|
||||
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
public:
|
||||
unique_ptr(const unique_ptr&) = delete;
|
||||
unique_ptr& operator=(const unique_ptr&) = delete;
|
||||
private:
|
||||
#else
|
||||
BOOST_MOVABLE_BUT_NOT_COPYABLE(unique_ptr)
|
||||
|
||||
typedef bmupmu::pointer_type<T, D > pointer_type_obtainer;
|
||||
typedef bmupd::unique_ptr_data
|
||||
<typename pointer_type_obtainer::type, D> data_type;
|
||||
typedef typename bmupd::deleter_types<D>::deleter_arg_type1 deleter_arg_type1;
|
||||
typedef typename bmupd::deleter_types<D>::deleter_arg_type2 deleter_arg_type2;
|
||||
data_type m_data;
|
||||
#endif
|
||||
|
||||
public:
|
||||
//! If the type <tt>remove_reference<D>::type::pointer</tt> exists, then it shall be a
|
||||
//! synonym for <tt>remove_reference<D>::type::pointer</tt>. Otherwise it shall be a
|
||||
//! synonym for T*.
|
||||
typedef typename BOOST_MOVE_SEEDOC(pointer_type_obtainer::type) pointer;
|
||||
//! If T is an array type, then element_type is equal to T. Otherwise, if T is a type
|
||||
//! in the form U[], element_type is equal to U.
|
||||
typedef typename BOOST_MOVE_SEEDOC(bmupmu::remove_extent<T>::type) element_type;
|
||||
typedef D deleter_type;
|
||||
|
||||
//! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and
|
||||
//! that construction shall not throw an exception.
|
||||
//!
|
||||
//! <b>Effects</b>: Constructs a unique_ptr object that owns nothing, value-initializing the
|
||||
//! stored pointer and the stored deleter.
|
||||
//!
|
||||
//! <b>Postconditions</b>: <tt>get() == nullptr</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter.
|
||||
//!
|
||||
//! <b>Remarks</b>: If this constructor is instantiated with a pointer type or reference type
|
||||
//! for the template argument D, the program is ill-formed.
|
||||
BOOST_CONSTEXPR unique_ptr() BOOST_NOEXCEPT
|
||||
: m_data()
|
||||
{
|
||||
//If this constructor is instantiated with a pointer type or reference type
|
||||
//for the template argument D, the program is ill-formed.
|
||||
BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
|
||||
BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Same as <tt>unique_ptr()</tt> (default constructor).
|
||||
//!
|
||||
BOOST_CONSTEXPR unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
|
||||
: m_data()
|
||||
{
|
||||
//If this constructor is instantiated with a pointer type or reference type
|
||||
//for the template argument D, the program is ill-formed.
|
||||
BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
|
||||
BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: D shall satisfy the requirements of DefaultConstructible, and
|
||||
//! that construction shall not throw an exception.
|
||||
//!
|
||||
//! <b>Effects</b>: Constructs a unique_ptr which owns p, initializing the stored pointer
|
||||
//! with p and value initializing the stored deleter.
|
||||
//!
|
||||
//! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter.
|
||||
//!
|
||||
//! <b>Remarks</b>: If this constructor is instantiated with a pointer type or reference type
|
||||
//! for the template argument D, the program is ill-formed.
|
||||
//! This constructor shall not participate in overload resolution unless:
|
||||
//! - If T is not an array type and Pointer is implicitly convertible to pointer.
|
||||
//! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
|
||||
template<class Pointer>
|
||||
explicit unique_ptr(Pointer p
|
||||
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
|
||||
) BOOST_NOEXCEPT
|
||||
: m_data(p)
|
||||
{
|
||||
//If T is not an array type, element_type_t<Pointer> derives from T
|
||||
//it uses the default deleter and T has no virtual destructor, then you have a problem
|
||||
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
|
||||
<D, typename bmupd::get_element_type<Pointer>::type>::value ));
|
||||
//If this constructor is instantiated with a pointer type or reference type
|
||||
//for the template argument D, the program is ill-formed.
|
||||
BOOST_STATIC_ASSERT(!bmupmu::is_pointer<D>::value);
|
||||
BOOST_STATIC_ASSERT(!bmupmu::is_reference<D>::value);
|
||||
}
|
||||
|
||||
//!The signature of this constructor depends upon whether D is a reference type.
|
||||
//! - If D is non-reference type A, then the signature is <tt>unique_ptr(pointer p, const A& d)</tt>.
|
||||
//! - If D is an lvalue-reference type A&, then the signature is <tt>unique_ptr(pointer p, A& d)</tt>.
|
||||
//! - If D is an lvalue-reference type const A&, then the signature is <tt>unique_ptr(pointer p, const A& d)</tt>.
|
||||
//!
|
||||
//!
|
||||
//! <b>Requires</b>: Either
|
||||
//! - D is not an lvalue-reference type and d is an lvalue or const rvalue.
|
||||
//! D shall satisfy the requirements of CopyConstructible, and the copy constructor of D
|
||||
//! shall not throw an exception. This unique_ptr will hold a copy of d.
|
||||
//! - D is an lvalue-reference type and d is an lvalue. the type which D references need not be CopyConstructible nor
|
||||
//! MoveConstructible. This unique_ptr will hold a D which refers to the lvalue d.
|
||||
//!
|
||||
//! <b>Effects</b>: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and
|
||||
//! initializing the deleter as described above.
|
||||
//!
|
||||
//! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter. If D is a
|
||||
//! reference type then <tt>get_deleter()</tt> returns a reference to the lvalue d.
|
||||
//!
|
||||
//! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
||||
//! - If T is not an array type and Pointer is implicitly convertible to pointer.
|
||||
//! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
|
||||
template<class Pointer>
|
||||
unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type1) d1
|
||||
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
|
||||
) BOOST_NOEXCEPT
|
||||
: m_data(p, d1)
|
||||
{
|
||||
//If T is not an array type, element_type_t<Pointer> derives from T
|
||||
//it uses the default deleter and T has no virtual destructor, then you have a problem
|
||||
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
|
||||
<D, typename bmupd::get_element_type<Pointer>::type>::value ));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type1 d1)</tt>
|
||||
//! and additionally <tt>get() == nullptr</tt>
|
||||
unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type1) d1) BOOST_NOEXCEPT
|
||||
: m_data(pointer(), d1)
|
||||
{}
|
||||
|
||||
//! The signature of this constructor depends upon whether D is a reference type.
|
||||
//! - If D is non-reference type A, then the signature is <tt>unique_ptr(pointer p, A&& d)</tt>.
|
||||
//! - If D is an lvalue-reference type A&, then the signature is <tt>unique_ptr(pointer p, A&& d)</tt>.
|
||||
//! - If D is an lvalue-reference type const A&, then the signature is <tt>unique_ptr(pointer p, const A&& d)</tt>.
|
||||
//!
|
||||
//! <b>Requires</b>: Either
|
||||
//! - D is not an lvalue-reference type and d is a non-const rvalue. D
|
||||
//! shall satisfy the requirements of MoveConstructible, and the move constructor
|
||||
//! of D shall not throw an exception. This unique_ptr will hold a value move constructed from d.
|
||||
//! - D is an lvalue-reference type and d is an rvalue, the program is ill-formed.
|
||||
//!
|
||||
//! <b>Effects</b>: Constructs a unique_ptr object which owns p, initializing the stored pointer with p and
|
||||
//! initializing the deleter as described above.
|
||||
//!
|
||||
//! <b>Postconditions</b>: <tt>get() == p</tt>. <tt>get_deleter()</tt> returns a reference to the stored deleter. If D is a
|
||||
//! reference type then <tt>get_deleter()</tt> returns a reference to the lvalue d.
|
||||
//!
|
||||
//! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
||||
//! - If T is not an array type and Pointer is implicitly convertible to pointer.
|
||||
//! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
|
||||
template<class Pointer>
|
||||
unique_ptr(Pointer p, BOOST_MOVE_SEEDOC(deleter_arg_type2) d2
|
||||
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer>::type* =0)
|
||||
) BOOST_NOEXCEPT
|
||||
: m_data(p, ::boost::move(d2))
|
||||
{
|
||||
//If T is not an array type, element_type_t<Pointer> derives from T
|
||||
//it uses the default deleter and T has no virtual destructor, then you have a problem
|
||||
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
|
||||
<D, typename bmupd::get_element_type<Pointer>::type>::value ));
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: Same effects as <tt>template<class Pointer> unique_ptr(Pointer p, deleter_arg_type2 d2)</tt>
|
||||
//! and additionally <tt>get() == nullptr</tt>
|
||||
unique_ptr(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), BOOST_MOVE_SEEDOC(deleter_arg_type2) d2) BOOST_NOEXCEPT
|
||||
: m_data(pointer(), ::boost::move(d2))
|
||||
{}
|
||||
|
||||
//! <b>Requires</b>: If D is not a reference type, D shall satisfy the requirements of MoveConstructible.
|
||||
//! Construction of the deleter from an rvalue of type D shall not throw an exception.
|
||||
//!
|
||||
//! <b>Effects</b>: Constructs a unique_ptr by transferring ownership from u to *this. If D is a reference type,
|
||||
//! this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's
|
||||
//! deleter.
|
||||
//!
|
||||
//! <b>Postconditions</b>: <tt>get()</tt> yields the value u.get() yielded before the construction. <tt>get_deleter()</tt>
|
||||
//! returns a reference to the stored deleter that was constructed from u.get_deleter(). If D is a
|
||||
//! reference type then <tt>get_deleter()</tt> and <tt>u.get_deleter()</tt> both reference the same lvalue deleter.
|
||||
unique_ptr(BOOST_RV_REF(unique_ptr) u) BOOST_NOEXCEPT
|
||||
: m_data(u.release(), ::boost::move_if_not_lvalue_reference<D>(u.get_deleter()))
|
||||
{}
|
||||
|
||||
//! <b>Requires</b>: If E is not a reference type, construction of the deleter from an rvalue of type E shall be
|
||||
//! well formed and shall not throw an exception. Otherwise, E is a reference type and construction of the
|
||||
//! deleter from an lvalue of type E shall be well formed and shall not throw an exception.
|
||||
//!
|
||||
//! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
||||
//! - <tt>unique_ptr<U, E>::pointer</tt> is implicitly convertible to pointer,
|
||||
//! - U is not an array type, and
|
||||
//! - either D is a reference type and E is the same type as D, or D is not a reference type and E is
|
||||
//! implicitly convertible to D.
|
||||
//!
|
||||
//! <b>Effects</b>: Constructs a unique_ptr by transferring ownership from u to *this. If E is a reference type,
|
||||
//! this deleter is copy constructed from u's deleter; otherwise, this deleter is move constructed from u's deleter.
|
||||
//!
|
||||
//! <b>Postconditions</b>: <tt>get()</tt> yields the value <tt>u.get()</tt> yielded before the construction. <tt>get_deleter()</tt>
|
||||
//! returns a reference to the stored deleter that was constructed from <tt>u.get_deleter()</tt>.
|
||||
template <class U, class E>
|
||||
unique_ptr( BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u
|
||||
BOOST_MOVE_DOCIGN(BOOST_MOVE_I typename bmupd::enable_up_moveconv_constr<T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E>::type* =0)
|
||||
) BOOST_NOEXCEPT
|
||||
: m_data(u.release(), ::boost::move_if_not_lvalue_reference<E>(u.get_deleter()))
|
||||
{
|
||||
//If T is not an array type, U derives from T
|
||||
//it uses the default deleter and T has no virtual destructor, then you have a problem
|
||||
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
|
||||
<D, typename unique_ptr<U, E>::pointer>::value ));
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
|
||||
//! and shall not throw exceptions.
|
||||
//!
|
||||
//! <b>Effects</b>: If <tt>get() == nullpt1r</tt> there are no effects. Otherwise <tt>get_deleter()(get())</tt>.
|
||||
//!
|
||||
//! <b>Note</b>: The use of default_delete requires T to be a complete type
|
||||
~unique_ptr()
|
||||
{ if(m_data.m_p) m_data.deleter()(m_data.m_p); }
|
||||
|
||||
//! <b>Requires</b>: If D is not a reference type, D shall satisfy the requirements of MoveAssignable
|
||||
//! and assignment of the deleter from an rvalue of type D shall not throw an exception. Otherwise, D
|
||||
//! is a reference type; <tt>remove_reference<D>::type</tt> shall satisfy the CopyAssignable requirements and
|
||||
//! assignment of the deleter from an lvalue of type D shall not throw an exception.
|
||||
//!
|
||||
//! <b>Effects</b>: Transfers ownership from u to *this as if by calling <tt>reset(u.release())</tt> followed
|
||||
//! by <tt>get_deleter() = std::forward<D>(u.get_deleter())</tt>.
|
||||
//!
|
||||
//! <b>Returns</b>: *this.
|
||||
unique_ptr& operator=(BOOST_RV_REF(unique_ptr) u) BOOST_NOEXCEPT
|
||||
{
|
||||
this->reset(u.release());
|
||||
m_data.deleter() = ::boost::move_if_not_lvalue_reference<D>(u.get_deleter());
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: If E is not a reference type, assignment of the deleter from an rvalue of type E shall be
|
||||
//! well-formed and shall not throw an exception. Otherwise, E is a reference type and assignment of the
|
||||
//! deleter from an lvalue of type E shall be well-formed and shall not throw an exception.
|
||||
//!
|
||||
//! <b>Remarks</b>: This operator shall not participate in overload resolution unless:
|
||||
//! - <tt>unique_ptr<U, E>::pointer</tt> is implicitly convertible to pointer and
|
||||
//! - U is not an array type.
|
||||
//!
|
||||
//! <b>Effects</b>: Transfers ownership from u to *this as if by calling <tt>reset(u.release())</tt> followed by
|
||||
//! <tt>get_deleter() = std::forward<E>(u.get_deleter())</tt>.
|
||||
//!
|
||||
//! <b>Returns</b>: *this.
|
||||
template <class U, class E>
|
||||
BOOST_MOVE_DOC1ST(unique_ptr&, typename bmupd::enable_up_moveconv_assign
|
||||
<T BOOST_MOVE_I D BOOST_MOVE_I U BOOST_MOVE_I E BOOST_MOVE_I unique_ptr &>::type)
|
||||
operator=(BOOST_RV_REF_BEG unique_ptr<U, E> BOOST_RV_REF_END u) BOOST_NOEXCEPT
|
||||
{
|
||||
this->reset(u.release());
|
||||
m_data.deleter() = ::boost::move_if_not_lvalue_reference<E>(u.get_deleter());
|
||||
return *this;
|
||||
}
|
||||
|
||||
//! <b>Effects</b>: <tt>reset()</tt>.
|
||||
//!
|
||||
//! <b>Postcondition</b>: <tt>get() == nullptr</tt>
|
||||
//!
|
||||
//! <b>Returns</b>: *this.
|
||||
unique_ptr& operator=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
|
||||
{ this->reset(); return *this; }
|
||||
|
||||
//! <b>Requires</b>: <tt>get() != nullptr</tt>.
|
||||
//!
|
||||
//! <b>Returns</b>: <tt>*get()</tt>.
|
||||
//!
|
||||
//! <b>Remarks</b: If T is an array type, the program is ill-formed.
|
||||
BOOST_MOVE_DOC1ST(element_type&, typename bmupmu::add_lvalue_reference<element_type>::type)
|
||||
operator*() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!bmupmu::is_array<T>::value));
|
||||
return *m_data.m_p;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: i < the number of elements in the array to which the stored pointer points.
|
||||
//!
|
||||
//! <b>Returns</b>: <tt>get()[i]</tt>.
|
||||
//!
|
||||
//! <b>Remarks</b: If T is not an array type, the program is ill-formed.
|
||||
BOOST_MOVE_DOC1ST(element_type&, typename bmupmu::add_lvalue_reference<element_type>::type)
|
||||
operator[](std::size_t i) const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT( bmupmu::extent<T>::value == 0 || i < bmupmu::extent<T>::value );
|
||||
BOOST_ASSERT(m_data.m_p);
|
||||
return m_data.m_p[i];
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: <tt>get() != nullptr</tt>.
|
||||
//!
|
||||
//! <b>Returns</b>: <tt>get()</tt>.
|
||||
//!
|
||||
//! <b>Note</b>: use typically requires that T be a complete type.
|
||||
//!
|
||||
//! <b>Remarks</b: If T is an array type, the program is ill-formed.
|
||||
pointer operator->() const BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!bmupmu::is_array<T>::value));
|
||||
BOOST_ASSERT(m_data.m_p);
|
||||
return m_data.m_p;
|
||||
}
|
||||
|
||||
//! <b>Returns</b>: The stored pointer.
|
||||
//!
|
||||
pointer get() const BOOST_NOEXCEPT
|
||||
{ return m_data.m_p; }
|
||||
|
||||
//! <b>Returns</b>: A reference to the stored deleter.
|
||||
//!
|
||||
BOOST_MOVE_DOC1ST(D&, typename bmupmu::add_lvalue_reference<D>::type)
|
||||
get_deleter() BOOST_NOEXCEPT
|
||||
{ return m_data.deleter(); }
|
||||
|
||||
//! <b>Returns</b>: A reference to the stored deleter.
|
||||
//!
|
||||
BOOST_MOVE_DOC1ST(const D&, typename bmupmu::add_const_lvalue_reference<D>::type)
|
||||
get_deleter() const BOOST_NOEXCEPT
|
||||
{ return m_data.deleter(); }
|
||||
|
||||
#ifdef BOOST_MOVE_DOXYGEN_INVOKED
|
||||
//! <b>Returns</b>: Returns: get() != nullptr.
|
||||
//!
|
||||
explicit operator bool
|
||||
#else
|
||||
operator bmupd::explicit_bool_arg
|
||||
#endif
|
||||
()const BOOST_NOEXCEPT
|
||||
{
|
||||
return m_data.m_p
|
||||
? &bmupd::bool_conversion::for_bool
|
||||
: bmupd::explicit_bool_arg(0);
|
||||
}
|
||||
|
||||
//! <b>Postcondition</b>: <tt>get() == nullptr</tt>.
|
||||
//!
|
||||
//! <b>Returns</b>: The value <tt>get()</tt> had at the start of the call to release.
|
||||
pointer release() BOOST_NOEXCEPT
|
||||
{
|
||||
const pointer tmp = m_data.m_p;
|
||||
m_data.m_p = pointer();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
|
||||
//! and shall not throw exceptions.
|
||||
//!
|
||||
//! <b>Effects</b>: assigns p to the stored pointer, and then if the old value of the stored pointer, old_p, was not
|
||||
//! equal to nullptr, calls <tt>get_deleter()(old_p)</tt>. Note: The order of these operations is significant
|
||||
//! because the call to <tt>get_deleter()</tt> may destroy *this.
|
||||
//!
|
||||
//! <b>Postconditions</b>: <tt>get() == p</tt>. Note: The postcondition does not hold if the call to <tt>get_deleter()</tt>
|
||||
//! destroys *this since <tt>this->get()</tt> is no longer a valid expression.
|
||||
//!
|
||||
//! <b>Remarks</b>: This constructor shall not participate in overload resolution unless:
|
||||
//! - If T is not an array type and Pointer is implicitly convertible to pointer.
|
||||
//! - If T is an array type and Pointer is a more CV qualified pointer to element_type.
|
||||
template<class Pointer>
|
||||
BOOST_MOVE_DOC1ST(void, typename bmupd::enable_up_ptr<T BOOST_MOVE_I Pointer BOOST_MOVE_I pointer BOOST_MOVE_I void>::type)
|
||||
reset(Pointer p) BOOST_NOEXCEPT
|
||||
{
|
||||
//If T is not an array type, element_type_t<Pointer> derives from T
|
||||
//it uses the default deleter and T has no virtual destructor, then you have a problem
|
||||
BOOST_STATIC_ASSERT(( !::boost::move_upmu::missing_virtual_destructor
|
||||
<D, typename bmupd::get_element_type<Pointer>::type>::value ));
|
||||
pointer tmp = m_data.m_p;
|
||||
m_data.m_p = p;
|
||||
if(tmp) m_data.deleter()(tmp);
|
||||
}
|
||||
|
||||
//! <b>Requires</b>: The expression <tt>get_deleter()(get())</tt> shall be well formed, shall have well-defined behavior,
|
||||
//! and shall not throw exceptions.
|
||||
//!
|
||||
//! <b>Effects</b>: assigns nullptr to the stored pointer, and then if the old value of the stored pointer, old_p, was not
|
||||
//! equal to nullptr, calls <tt>get_deleter()(old_p)</tt>. Note: The order of these operations is significant
|
||||
//! because the call to <tt>get_deleter()</tt> may destroy *this.
|
||||
//!
|
||||
//! <b>Postconditions</b>: <tt>get() == p</tt>. Note: The postcondition does not hold if the call to <tt>get_deleter()</tt>
|
||||
//! destroys *this since <tt>this->get()</tt> is no longer a valid expression.
|
||||
void reset() BOOST_NOEXCEPT
|
||||
{ this->reset(pointer()); }
|
||||
|
||||
//! <b>Effects</b>: Same as <tt>reset()</tt>
|
||||
//!
|
||||
void reset(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
|
||||
{ this->reset(); }
|
||||
|
||||
//! <b>Requires</b>: <tt>get_deleter()</tt> shall be swappable and shall not throw an exception under swap.
|
||||
//!
|
||||
//! <b>Effects</b>: Invokes swap on the stored pointers and on the stored deleters of *this and u.
|
||||
void swap(unique_ptr& u) BOOST_NOEXCEPT
|
||||
{
|
||||
using ::boost::move_detail::swap;
|
||||
swap(m_data.m_p, u.m_data.m_p);
|
||||
swap(m_data.deleter(), u.m_data.deleter());
|
||||
}
|
||||
};
|
||||
|
||||
//! <b>Effects</b>: Calls <tt>x.swap(y)</tt>.
|
||||
//!
|
||||
template <class T, class D>
|
||||
inline void swap(unique_ptr<T, D> &x, unique_ptr<T, D> &y) BOOST_NOEXCEPT
|
||||
{ x.swap(y); }
|
||||
|
||||
//! <b>Returns</b>: <tt>x.get() == y.get()</tt>.
|
||||
//!
|
||||
template <class T1, class D1, class T2, class D2>
|
||||
inline bool operator==(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
||||
{ return x.get() == y.get(); }
|
||||
|
||||
//! <b>Returns</b>: <tt>x.get() != y.get()</tt>.
|
||||
//!
|
||||
template <class T1, class D1, class T2, class D2>
|
||||
inline bool operator!=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
||||
{ return x.get() != y.get(); }
|
||||
|
||||
//! <b>Returns</b>: x.get() < y.get().
|
||||
//!
|
||||
//! <b>Remarks</b>: This comparison shall induce a
|
||||
//! strict weak ordering betwen pointers.
|
||||
template <class T1, class D1, class T2, class D2>
|
||||
inline bool operator<(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
||||
{ return x.get() < y.get(); }
|
||||
|
||||
//! <b>Returns</b>: !(y < x).
|
||||
//!
|
||||
template <class T1, class D1, class T2, class D2>
|
||||
inline bool operator<=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
||||
{ return !(y < x); }
|
||||
|
||||
//! <b>Returns</b>: y < x.
|
||||
//!
|
||||
template <class T1, class D1, class T2, class D2>
|
||||
inline bool operator>(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
||||
{ return y < x; }
|
||||
|
||||
//! <b>Returns</b>:!(x < y).
|
||||
//!
|
||||
template <class T1, class D1, class T2, class D2>
|
||||
inline bool operator>=(const unique_ptr<T1, D1> &x, const unique_ptr<T2, D2> &y)
|
||||
{ return !(x < y); }
|
||||
|
||||
//! <b>Returns</b>:!x.
|
||||
//!
|
||||
template <class T, class D>
|
||||
inline bool operator==(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
|
||||
{ return !x; }
|
||||
|
||||
//! <b>Returns</b>:!x.
|
||||
//!
|
||||
template <class T, class D>
|
||||
inline bool operator==(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT
|
||||
{ return !x; }
|
||||
|
||||
//! <b>Returns</b>: (bool)x.
|
||||
//!
|
||||
template <class T, class D>
|
||||
inline bool operator!=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type)) BOOST_NOEXCEPT
|
||||
{ return !!x; }
|
||||
|
||||
//! <b>Returns</b>: (bool)x.
|
||||
//!
|
||||
template <class T, class D>
|
||||
inline bool operator!=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x) BOOST_NOEXCEPT
|
||||
{ return !!x; }
|
||||
|
||||
//! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values.
|
||||
//!
|
||||
//! <b>Returns</b>: Returns <tt>x.get() < pointer()</tt>.
|
||||
template <class T, class D>
|
||||
inline bool operator<(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
|
||||
{ return x.get() < typename unique_ptr<T, D>::pointer(); }
|
||||
|
||||
//! <b>Requires</b>: <tt>operator </tt> shall induce a strict weak ordering on unique_ptr<T, D>::pointer values.
|
||||
//!
|
||||
//! <b>Returns</b>: Returns <tt>pointer() < x.get()</tt>.
|
||||
template <class T, class D>
|
||||
inline bool operator<(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
|
||||
{ return typename unique_ptr<T, D>::pointer() < x.get(); }
|
||||
|
||||
//! <b>Returns</b>: <tt>nullptr < x</tt>.
|
||||
//!
|
||||
template <class T, class D>
|
||||
inline bool operator>(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
|
||||
{ return x.get() > typename unique_ptr<T, D>::pointer(); }
|
||||
|
||||
//! <b>Returns</b>: <tt>x < nullptr</tt>.
|
||||
//!
|
||||
template <class T, class D>
|
||||
inline bool operator>(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
|
||||
{ return typename unique_ptr<T, D>::pointer() > x.get(); }
|
||||
|
||||
//! <b>Returns</b>: <tt>!(nullptr < x)</tt>.
|
||||
//!
|
||||
template <class T, class D>
|
||||
inline bool operator<=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
|
||||
{ return !(bmupd::nullptr_type() < x); }
|
||||
|
||||
//! <b>Returns</b>: <tt>!(x < nullptr)</tt>.
|
||||
//!
|
||||
template <class T, class D>
|
||||
inline bool operator<=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
|
||||
{ return !(x < bmupd::nullptr_type()); }
|
||||
|
||||
//! <b>Returns</b>: <tt>!(x < nullptr)</tt>.
|
||||
//!
|
||||
template <class T, class D>
|
||||
inline bool operator>=(const unique_ptr<T, D> &x, BOOST_MOVE_DOC0PTR(bmupd::nullptr_type))
|
||||
{ return !(x < bmupd::nullptr_type()); }
|
||||
|
||||
//! <b>Returns</b>: <tt>!(nullptr < x)</tt>.
|
||||
//!
|
||||
template <class T, class D>
|
||||
inline bool operator>=(BOOST_MOVE_DOC0PTR(bmupd::nullptr_type), const unique_ptr<T, D> &x)
|
||||
{ return !(bmupd::nullptr_type() < x); }
|
||||
|
||||
} //namespace movelib {
|
||||
} //namespace boost{
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_UNIQUE_PTR_HPP_INCLUDED
|
||||
141
boost/move/utility.hpp
Normal file
141
boost/move/utility.hpp
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
//! This header includes core utilities from <tt><boost/move/utility_core.hpp></tt> and defines
|
||||
//! some more advanced utilities such as:
|
||||
|
||||
#ifndef BOOST_MOVE_MOVE_UTILITY_HPP
|
||||
#define BOOST_MOVE_MOVE_UTILITY_HPP
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
#include <boost/move/utility_core.hpp>
|
||||
#include <boost/move/traits.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
namespace boost {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move_if_noexcept()
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value && !has_move_emulation_enabled<T>::value
|
||||
, typename ::boost::move_detail::add_const<T>::type &
|
||||
>::type
|
||||
move_if_noexcept(T& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
|
||||
&& ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value, rv<T>&>::type
|
||||
move_if_noexcept(T& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return *static_cast<rv<T>* >(::boost::move_detail::addressof(x));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
|
||||
&& ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
|
||||
, rv<T>&
|
||||
>::type
|
||||
move_if_noexcept(rv<T>& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
|
||||
&& !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
|
||||
, typename ::boost::move_detail::add_const<T>::type &
|
||||
>::type
|
||||
move_if_noexcept(T& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value
|
||||
&& !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value
|
||||
, typename ::boost::move_detail::add_const<T>::type &
|
||||
>::type
|
||||
move_if_noexcept(rv<T>& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
} //namespace boost
|
||||
|
||||
#else //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
|
||||
#include <utility>
|
||||
|
||||
namespace boost{
|
||||
|
||||
using ::std::move_if_noexcept;
|
||||
|
||||
} //namespace boost
|
||||
|
||||
#else //!BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
|
||||
|
||||
namespace boost {
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move_if_noexcept()
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
//! This function provides a way to convert a reference into a rvalue reference
|
||||
//! in compilers with rvalue references. For other compilers converts T & into
|
||||
//! <i>::boost::rv<T> &</i> so that move emulation is activated. Reference
|
||||
//! would be converted to rvalue reference only if input type is nothrow move
|
||||
//! constructible or if it has no copy constructor. In all other cases const
|
||||
//! reference would be returned
|
||||
template <class T>
|
||||
rvalue_reference_or_const_lvalue_reference move_if_noexcept(input_reference) noexcept;
|
||||
|
||||
#else //BOOST_MOVE_DOXYGEN_INVOKED
|
||||
|
||||
template <class T>
|
||||
typename ::boost::move_detail::enable_if_c
|
||||
< ::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value, T&&>::type
|
||||
move_if_noexcept(T& x) BOOST_NOEXCEPT
|
||||
{ return ::boost::move(x); }
|
||||
|
||||
template <class T>
|
||||
typename ::boost::move_detail::enable_if_c
|
||||
< !::boost::move_detail::is_nothrow_move_constructible_or_uncopyable<T>::value, const T&>::type
|
||||
move_if_noexcept(T& x) BOOST_NOEXCEPT
|
||||
{ return x; }
|
||||
|
||||
#endif //BOOST_MOVE_DOXYGEN_INVOKED
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
|
||||
|
||||
#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_MOVE_UTILITY_HPP
|
||||
295
boost/move/utility_core.hpp
Normal file
295
boost/move/utility_core.hpp
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// (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
|
||||
//! This header defines core utilities to ease the development
|
||||
//! of move-aware functions. This header minimizes dependencies
|
||||
//! from other libraries.
|
||||
|
||||
#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
|
||||
#define BOOST_MOVE_MOVE_UTILITY_CORE_HPP
|
||||
|
||||
#include <boost/move/detail/config_begin.hpp>
|
||||
#include <boost/move/core.hpp>
|
||||
#include <boost/move/detail/meta_utils.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
namespace boost {
|
||||
|
||||
template<class T>
|
||||
struct enable_move_utility_emulation
|
||||
{
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move()
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value && !has_move_emulation_enabled<T>::value, T&>::type
|
||||
move(T& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value, rv<T>&>::type
|
||||
move(T& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return *static_cast<rv<T>* >(::boost::move_detail::addressof(x));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value && has_move_emulation_enabled<T>::value, rv<T>&>::type
|
||||
move(rv<T>& x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// forward()
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value && ::boost::move_detail::is_rv<T>::value, T &>::type
|
||||
forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
|
||||
{
|
||||
return const_cast<T&>(x);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value && !::boost::move_detail::is_rv<T>::value, const T &>::type
|
||||
forward(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move_if_not_lvalue_reference()
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value &&
|
||||
::boost::move_detail::is_rv<T>::value
|
||||
, T &>::type
|
||||
move_if_not_lvalue_reference(const typename ::boost::move_detail::identity<T>::type &x) BOOST_NOEXCEPT
|
||||
{
|
||||
return const_cast<T&>(x);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value &&
|
||||
!::boost::move_detail::is_rv<T>::value &&
|
||||
(::boost::move_detail::is_lvalue_reference<T>::value ||
|
||||
!has_move_emulation_enabled<T>::value)
|
||||
, typename ::boost::move_detail::add_lvalue_reference<T>::type
|
||||
>::type
|
||||
move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::enable_if_c
|
||||
< enable_move_utility_emulation<T>::value &&
|
||||
!::boost::move_detail::is_rv<T>::value &&
|
||||
(!::boost::move_detail::is_lvalue_reference<T>::value &&
|
||||
has_move_emulation_enabled<T>::value)
|
||||
, rv<T>&
|
||||
>::type
|
||||
move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type &x) BOOST_NOEXCEPT
|
||||
{
|
||||
return move(x);
|
||||
}
|
||||
|
||||
} //namespace boost
|
||||
|
||||
#else //#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
|
||||
#include <utility>
|
||||
|
||||
namespace boost{
|
||||
|
||||
using ::std::move;
|
||||
using ::std::forward;
|
||||
|
||||
} //namespace boost
|
||||
|
||||
#else //!BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE
|
||||
|
||||
namespace boost {
|
||||
|
||||
//! This trait's internal boolean `value` is false in compilers with rvalue references
|
||||
//! and true in compilers without rvalue references.
|
||||
//!
|
||||
//! A user can specialize this trait for a type T to false to SFINAE out `move` and `forward`
|
||||
//! so that the user can define a different move emulation for that type in namespace boost
|
||||
//! (e.g. another Boost library for its types) and avoid any overload ambiguity.
|
||||
template<class T>
|
||||
struct enable_move_utility_emulation
|
||||
{
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
//! This function provides a way to convert a reference into a rvalue reference
|
||||
//! in compilers with rvalue references. For other compilers if `T` is Boost.Move
|
||||
//! enabled type then it converts `T&` into <tt>::boost::rv<T> &</tt> so that
|
||||
//! move emulation is activated, else it returns `T &`.
|
||||
template <class T>
|
||||
rvalue_reference move(input_reference) noexcept;
|
||||
|
||||
#elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
|
||||
|
||||
//Old move approach, lvalues could bind to rvalue references
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
|
||||
{ return t; }
|
||||
|
||||
#else //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
|
||||
template <class T>
|
||||
inline typename ::boost::move_detail::remove_reference<T>::type && move(T&& t) BOOST_NOEXCEPT
|
||||
{ return static_cast<typename ::boost::move_detail::remove_reference<T>::type &&>(t); }
|
||||
|
||||
#endif //BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// forward
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
//! This function provides limited form of forwarding that is usually enough for
|
||||
//! in-place construction and avoids the exponential overloading for
|
||||
//! achieve the limited forwarding in C++03.
|
||||
//!
|
||||
//! For compilers with rvalue references this function provides perfect forwarding.
|
||||
//!
|
||||
//! Otherwise:
|
||||
//! * If input_reference binds to const ::boost::rv<T> & then it output_reference is
|
||||
//! ::boost::rv<T> &
|
||||
//!
|
||||
//! * Else, output_reference is equal to input_reference.
|
||||
template <class T> output_reference forward(input_reference) noexcept;
|
||||
#elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
|
||||
|
||||
//Old move approach, lvalues could bind to rvalue references
|
||||
|
||||
template <class T>
|
||||
inline T&& forward(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
|
||||
{ return t; }
|
||||
|
||||
#else //Old move
|
||||
|
||||
template <class T>
|
||||
inline T&& forward(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
|
||||
{ return static_cast<T&&>(t); }
|
||||
|
||||
template <class T>
|
||||
inline T&& forward(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT
|
||||
{
|
||||
//"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue.";
|
||||
BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
|
||||
return static_cast<T&&>(t);
|
||||
}
|
||||
|
||||
#endif //BOOST_MOVE_DOXYGEN_INVOKED
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// move_if_not_lvalue_reference
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#if defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
template <class T> output_reference move_if_not_lvalue_reference(input_reference) noexcept;
|
||||
#elif defined(BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES)
|
||||
|
||||
//Old move approach, lvalues could bind to rvalue references
|
||||
|
||||
template <class T>
|
||||
inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::identity<T>::type&& t) BOOST_NOEXCEPT
|
||||
{ return t; }
|
||||
|
||||
#else //Old move
|
||||
|
||||
template <class T>
|
||||
inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type& t) BOOST_NOEXCEPT
|
||||
{ return static_cast<T&&>(t); }
|
||||
|
||||
template <class T>
|
||||
inline T&& move_if_not_lvalue_reference(typename ::boost::move_detail::remove_reference<T>::type&& t) BOOST_NOEXCEPT
|
||||
{
|
||||
//"boost::forward<T> error: 'T' is a lvalue reference, can't forward as rvalue.";
|
||||
BOOST_STATIC_ASSERT(!boost::move_detail::is_lvalue_reference<T>::value);
|
||||
return static_cast<T&&>(t);
|
||||
}
|
||||
|
||||
#endif //BOOST_MOVE_DOXYGEN_INVOKED
|
||||
|
||||
} //namespace boost {
|
||||
|
||||
#endif //#if defined(BOOST_MOVE_USE_STANDARD_LIBRARY_MOVE)
|
||||
|
||||
#endif //BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
|
||||
#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
namespace boost{
|
||||
namespace move_detail{
|
||||
|
||||
template<class T>
|
||||
void swap(T &a, T &b)
|
||||
{
|
||||
T c((::boost::move(a)));
|
||||
a = ::boost::move(b);
|
||||
b = ::boost::move(c);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename boost::move_detail::add_rvalue_reference<T>::type declval();
|
||||
|
||||
} //namespace move_detail{
|
||||
} //namespace boost{
|
||||
|
||||
#endif //#if !defined(BOOST_MOVE_DOXYGEN_INVOKED)
|
||||
|
||||
|
||||
#include <boost/move/detail/config_end.hpp>
|
||||
|
||||
#endif //#ifndef BOOST_MOVE_MOVE_UTILITY_CORE_HPP
|
||||
Loading…
Add table
Add a link
Reference in a new issue