forked from boostorg/optional
Fix #12563
This commit is contained in:
@ -745,6 +745,10 @@ struct is_convertible_to_T_or_factory
|
|||||||
, boost::true_type, boost::false_type>::type
|
, boost::true_type, boost::false_type>::type
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_optional_constructible : boost::is_constructible<T, U>
|
||||||
|
{};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT
|
#define BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT
|
||||||
@ -753,6 +757,10 @@ template <typename, typename>
|
|||||||
struct is_convertible_to_T_or_factory : boost::true_type
|
struct is_convertible_to_T_or_factory : boost::true_type
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
struct is_optional_constructible : boost::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
#endif // is_convertible condition
|
#endif // is_convertible condition
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
@ -812,7 +820,8 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
// Requires a valid conversion from U to T.
|
// Requires a valid conversion from U to T.
|
||||||
// Can throw if T::T(U const&) does
|
// Can throw if T::T(U const&) does
|
||||||
template<class U>
|
template<class U>
|
||||||
explicit optional ( optional<U> const& rhs )
|
explicit optional ( optional<U> const& rhs,
|
||||||
|
typename boost::enable_if< optional_detail::is_optional_constructible<T, U const&> >::type* = 0)
|
||||||
:
|
:
|
||||||
base()
|
base()
|
||||||
{
|
{
|
||||||
@ -825,7 +834,8 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
// Requires a valid conversion from U to T.
|
// Requires a valid conversion from U to T.
|
||||||
// Can throw if T::T(U&&) does
|
// Can throw if T::T(U&&) does
|
||||||
template<class U>
|
template<class U>
|
||||||
explicit optional ( optional<U> && rhs )
|
explicit optional ( optional<U> && rhs,
|
||||||
|
typename boost::enable_if< optional_detail::is_optional_constructible<T, U> >::type* = 0 )
|
||||||
:
|
:
|
||||||
base()
|
base()
|
||||||
{
|
{
|
||||||
|
@ -23,6 +23,29 @@
|
|||||||
using boost::optional;
|
using boost::optional;
|
||||||
using boost::none;
|
using boost::none;
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
struct superconv
|
||||||
|
{
|
||||||
|
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
|
template <typename T>
|
||||||
|
superconv(T&&) { BOOST_STATIC_ASSERT(sizeof(T) == 0); }
|
||||||
|
#else
|
||||||
|
template <typename T>
|
||||||
|
superconv(const T&) { BOOST_STATIC_ASSERT(sizeof(T) == 0); }
|
||||||
|
template <typename T>
|
||||||
|
superconv( T&) { BOOST_STATIC_ASSERT(sizeof(T) == 0); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
superconv() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void test_optional_of_superconverting_T() // compile-time test
|
||||||
|
{
|
||||||
|
superconv<optional<int> > s;
|
||||||
|
superconv<optional<int> > & rs = s;
|
||||||
|
optional<superconv<optional<int> > > os = rs;
|
||||||
|
}
|
||||||
|
|
||||||
void test_optional_optional_T()
|
void test_optional_optional_T()
|
||||||
{
|
{
|
||||||
optional<int> oi1 (1), oiN;
|
optional<int> oi1 (1), oiN;
|
||||||
@ -39,6 +62,7 @@ void test_optional_optional_T()
|
|||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test_optional_optional_T();
|
test_optional_optional_T();
|
||||||
|
test_optional_of_superconverting_T();
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,20 @@ struct Resource
|
|||||||
explicit Resource(const X&) {}
|
explicit Resource(const X&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(( boost::is_constructible<Resource, const X&>::value));
|
BOOST_STATIC_ASSERT(( boost::is_constructible<Resource, const X&>::value ));
|
||||||
BOOST_STATIC_ASSERT((!boost::is_constructible<Resource, const Y&>::value));
|
BOOST_STATIC_ASSERT(( !boost::is_constructible<Resource, const Y&>::value ));
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(( boost::is_constructible<optional<Resource>, const X&>::value));
|
BOOST_STATIC_ASSERT(( boost::is_constructible<optional<Resource>, const X&>::value ));
|
||||||
BOOST_STATIC_ASSERT((!boost::is_constructible<optional<Resource>, const Y&>::value));
|
BOOST_STATIC_ASSERT(( !boost::is_constructible<optional<Resource>, const Y&>::value ));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_constructible< optional< optional<int> >, optional<int> >::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( !boost::is_constructible< optional<int>, optional< optional<int> > >::value ));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_constructible< optional< optional<int> >, const optional<int>& >::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( !boost::is_constructible< optional<int>, const optional< optional<int> >& >::value ));
|
||||||
|
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_constructible<optional<Resource>, const optional<X>&>::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( !boost::is_constructible<optional<Resource>, const optional<Y>&>::value ));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user