forked from boostorg/optional
trivially-copyable optional<T> for trivial T
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
|
||||
// Copyright (C) 2014 - 2016 Andrzej Krzemienski.
|
||||
// Copyright (C) 2014 - 2017 Andrzej Krzemienski.
|
||||
//
|
||||
// Use, modification, and distribution is subject to the Boost Software
|
||||
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
@ -36,13 +36,22 @@
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/decay.hpp>
|
||||
#include <boost/type_traits/has_trivial_copy.hpp>
|
||||
#include <boost/type_traits/has_trivial_move_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_constructor.hpp>
|
||||
#include <boost/type_traits/has_trivial_assign.hpp>
|
||||
#include <boost/type_traits/has_trivial_move_assign.hpp>
|
||||
#include <boost/type_traits/has_trivial_destructor.hpp>
|
||||
#include <boost/type_traits/is_base_of.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_constructible.hpp>
|
||||
#include <boost/type_traits/is_lvalue_reference.hpp>
|
||||
#include <boost/type_traits/is_nothrow_move_assignable.hpp>
|
||||
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
|
||||
#include <boost/type_traits/is_rvalue_reference.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/is_volatile.hpp>
|
||||
#include <boost/type_traits/is_scalar.hpp>
|
||||
#include <boost/move/utility.hpp>
|
||||
#include <boost/none.hpp>
|
||||
#include <boost/utility/compare_pointees.hpp>
|
||||
@ -178,6 +187,7 @@ class optional_base : public optional_tag
|
||||
// Creates a deep move of another optional<T>
|
||||
// Can throw if T::T(T&&) does
|
||||
optional_base ( optional_base&& rhs )
|
||||
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
|
||||
:
|
||||
m_initialized(false)
|
||||
{
|
||||
@ -210,6 +220,20 @@ class optional_base : public optional_tag
|
||||
|
||||
#endif
|
||||
|
||||
optional_base& operator= ( optional_base const& rhs )
|
||||
{
|
||||
this->assign(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
optional_base& operator= ( optional_base && rhs )
|
||||
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
|
||||
{
|
||||
this->assign(static_cast<optional_base&&>(rhs));
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
// No-throw (assuming T::~T() doesn't)
|
||||
~optional_base() { destroy() ; }
|
||||
@ -735,6 +759,10 @@ class optional_base : public optional_tag
|
||||
storage_type m_storage ;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
#include <boost/optional/detail/optional_trivially_copyable_base.hpp>
|
||||
|
||||
// definition of metafunciton is_optional_val_init_candidate
|
||||
template <typename U>
|
||||
struct is_optional_related
|
||||
@ -776,13 +804,46 @@ struct is_optional_val_init_candidate
|
||||
: boost::conditional< !is_optional_related<U>::value && is_convertible_to_T_or_factory<T, U>::value
|
||||
, boost::true_type, boost::false_type>::type
|
||||
{};
|
||||
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct is_type_trivially_copyable
|
||||
: boost::conditional<(boost::has_trivial_copy_constructor<T>::value &&
|
||||
boost::has_trivial_move_constructor<T>::value &&
|
||||
boost::has_trivial_destructor<T>::value &&
|
||||
boost::has_trivial_move_assign<T>::value &&
|
||||
boost::has_trivial_assign<T>::value),
|
||||
boost::true_type, boost::false_type>::type
|
||||
{};
|
||||
|
||||
} // namespace optional_detail
|
||||
|
||||
namespace optional_config {
|
||||
|
||||
template <typename T>
|
||||
struct is_type_trivial
|
||||
: boost::conditional< (optional_detail::is_type_trivially_copyable<T>::value && boost::has_trivial_default_constructor<T>::value) ||
|
||||
(boost::is_scalar<T>::value && !boost::is_const<T>::value && !boost::is_volatile<T>::value)
|
||||
, boost::true_type, boost::false_type>::type
|
||||
{};
|
||||
|
||||
} // namespace optional_config
|
||||
|
||||
|
||||
#ifndef BOOST_OPTIONAL_CONFIG_NO_SPEC_FOR_TRIVIAL_TYPES
|
||||
# define BOOST_OPTIONAL_BASE_TYPE(T) boost::conditional< optional_config::is_type_trivial<T>::value, \
|
||||
optional_detail::tc_optional_base<T>, \
|
||||
optional_detail::optional_base<T> \
|
||||
>::type
|
||||
#else
|
||||
# define BOOST_OPTIONAL_BASE_TYPE(T) optional_detail::optional_base<T>
|
||||
#endif
|
||||
|
||||
template<class T>
|
||||
class optional : public optional_detail::optional_base<T>
|
||||
class optional
|
||||
: public BOOST_OPTIONAL_BASE_TYPE(T)
|
||||
{
|
||||
typedef optional_detail::optional_base<T> base ;
|
||||
typedef typename BOOST_OPTIONAL_BASE_TYPE(T) base ;
|
||||
|
||||
public :
|
||||
|
||||
@ -842,7 +903,7 @@ class optional : public optional_detail::optional_base<T>
|
||||
)
|
||||
:
|
||||
base()
|
||||
{
|
||||
{
|
||||
if ( rhs.is_initialized() )
|
||||
this->construct(rhs.get());
|
||||
}
|
||||
@ -893,15 +954,24 @@ class optional : public optional_detail::optional_base<T>
|
||||
|
||||
// Creates a deep copy of another optional<T>
|
||||
// Can throw if T::T(T const&) does
|
||||
#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
|
||||
optional ( optional const& ) = default;
|
||||
#else
|
||||
optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Creates a deep move of another optional<T>
|
||||
// Can throw if T::T(T&&) does
|
||||
|
||||
#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
|
||||
optional ( optional && rhs ) = default;
|
||||
#else
|
||||
optional ( optional && rhs )
|
||||
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value)
|
||||
: base( boost::move(rhs) )
|
||||
{}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -959,21 +1029,30 @@ class optional : public optional_detail::optional_base<T>
|
||||
// Assigns from another optional<T> (deep-copies the rhs value)
|
||||
// Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
|
||||
// (NOTE: On BCB, this operator is not actually called and left is left UNMODIFIED in case of a throw)
|
||||
#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
|
||||
optional& operator= ( optional const& rhs ) = default;
|
||||
#else
|
||||
optional& operator= ( optional const& rhs )
|
||||
{
|
||||
this->assign( static_cast<base const&>(rhs) ) ;
|
||||
return *this ;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
// Assigns from another optional<T> (deep-moves the rhs value)
|
||||
#ifndef BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
|
||||
optional& operator= ( optional && ) = default;
|
||||
#else
|
||||
optional& operator= ( optional && rhs )
|
||||
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
|
||||
{
|
||||
this->assign( static_cast<base &&>(rhs) ) ;
|
||||
return *this ;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||
|
||||
#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
|
||||
|
||||
|
Reference in New Issue
Block a user