mirror of
https://github.com/boostorg/optional.git
synced 2025-07-30 04:27:19 +02:00
Merge branch 'Lastique-fix_constructible_from_any' into develop
This commit is contained in:
@ -30,7 +30,7 @@ class tc_optional_base : public optional_tag
|
|||||||
:
|
:
|
||||||
m_initialized(false) {}
|
m_initialized(false) {}
|
||||||
|
|
||||||
tc_optional_base ( argument_type val )
|
tc_optional_base ( init_value_tag, argument_type val )
|
||||||
:
|
:
|
||||||
m_initialized(true), m_storage(val) {}
|
m_initialized(true), m_storage(val) {}
|
||||||
|
|
||||||
|
@ -107,7 +107,9 @@ using optional_ns::in_place_init_if;
|
|||||||
|
|
||||||
namespace optional_detail {
|
namespace optional_detail {
|
||||||
|
|
||||||
struct optional_tag {} ;
|
struct init_value_tag {};
|
||||||
|
|
||||||
|
struct optional_tag {};
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@ -147,7 +149,7 @@ class optional_base : public optional_tag
|
|||||||
|
|
||||||
// Creates an optional<T> initialized with 'val'.
|
// Creates an optional<T> initialized with 'val'.
|
||||||
// Can throw if T::T(T const&) does
|
// Can throw if T::T(T const&) does
|
||||||
optional_base ( argument_type val )
|
optional_base ( init_value_tag, argument_type val )
|
||||||
:
|
:
|
||||||
m_initialized(false)
|
m_initialized(false)
|
||||||
{
|
{
|
||||||
@ -157,7 +159,7 @@ class optional_base : public optional_tag
|
|||||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
// move-construct an optional<T> initialized from an rvalue-ref to 'val'.
|
// move-construct an optional<T> initialized from an rvalue-ref to 'val'.
|
||||||
// Can throw if T::T(T&&) does
|
// Can throw if T::T(T&&) does
|
||||||
optional_base ( rval_reference_type val )
|
optional_base ( init_value_tag, rval_reference_type val )
|
||||||
:
|
:
|
||||||
m_initialized(false)
|
m_initialized(false)
|
||||||
{
|
{
|
||||||
@ -870,12 +872,12 @@ class optional
|
|||||||
|
|
||||||
// Creates an optional<T> initialized with 'val'.
|
// Creates an optional<T> initialized with 'val'.
|
||||||
// Can throw if T::T(T const&) does
|
// Can throw if T::T(T const&) does
|
||||||
optional ( argument_type val ) : base(val) {}
|
optional ( argument_type val ) : base(optional_detail::init_value_tag(), val) {}
|
||||||
|
|
||||||
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
// Creates an optional<T> initialized with 'move(val)'.
|
// Creates an optional<T> initialized with 'move(val)'.
|
||||||
// Can throw if T::T(T &&) does
|
// Can throw if T::T(T &&) does
|
||||||
optional ( rval_reference_type val ) : base( boost::forward<T>(val) )
|
optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), boost::forward<T>(val))
|
||||||
{}
|
{}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -76,6 +76,7 @@ import testing ;
|
|||||||
[ run optional_test_static_properties.cpp ]
|
[ run optional_test_static_properties.cpp ]
|
||||||
[ compile optional_test_maybe_uninitialized_warning.cpp ]
|
[ compile optional_test_maybe_uninitialized_warning.cpp ]
|
||||||
[ compile optional_test_deleted_default_ctor.cpp ]
|
[ compile optional_test_deleted_default_ctor.cpp ]
|
||||||
|
[ compile optional_test_constructible_from_other.cpp ]
|
||||||
#[ run optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp ]
|
#[ run optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp ]
|
||||||
[ run optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_pass.cpp ]
|
[ run optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_pass.cpp ]
|
||||||
[ run-fail optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_fail.cpp ]
|
[ run-fail optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_fail.cpp ]
|
||||||
|
57
test/optional_test_constructible_from_other.cpp
Normal file
57
test/optional_test_constructible_from_other.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright (c) 2018 Andrey Semashev
|
||||||
|
//
|
||||||
|
// Use, modification, and distribution is subject to 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)
|
||||||
|
|
||||||
|
// The test verifies that Boost.Optional copy constructors do not attempt to invoke
|
||||||
|
// the element type initializing constructors from templated arguments
|
||||||
|
|
||||||
|
#include <boost/optional/optional.hpp>
|
||||||
|
#include <boost/core/enable_if.hpp>
|
||||||
|
|
||||||
|
struct no_type
|
||||||
|
{
|
||||||
|
char data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct yes_type
|
||||||
|
{
|
||||||
|
char data[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
template< unsigned int Size >
|
||||||
|
struct size_tag {};
|
||||||
|
|
||||||
|
template< typename T, typename U >
|
||||||
|
struct is_constructible
|
||||||
|
{
|
||||||
|
template< typename T1, typename U1 >
|
||||||
|
static yes_type check_helper(size_tag< sizeof(static_cast< T1 >(U1())) >*);
|
||||||
|
template< typename T1, typename U1 >
|
||||||
|
static no_type check_helper(...);
|
||||||
|
|
||||||
|
static const bool value = sizeof(check_helper< T, U >(0)) == sizeof(yes_type);
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
class wrapper
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wrapper() {}
|
||||||
|
wrapper(wrapper const&) {}
|
||||||
|
template< typename U >
|
||||||
|
wrapper(U const&, typename boost::enable_if_c< is_constructible< T, U >::value, int >::type = 0) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline boost::optional< wrapper< int > > foo()
|
||||||
|
{
|
||||||
|
return boost::optional< wrapper< int > >();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
// Invokes boost::optional copy constructor. Should not invoke wrapper constructor from U.
|
||||||
|
boost::optional< wrapper< int > > res = foo();
|
||||||
|
return 0;
|
||||||
|
}
|
Reference in New Issue
Block a user