mirror of
https://github.com/boostorg/optional.git
synced 2026-07-21 13:43:39 +00:00
add conversion from optional T to optional ref T
This commit is contained in:
@@ -197,6 +197,9 @@ They are empty, trivially copyable classes with disabled default constructor.
|
||||
template<class F> constexpr auto flat_map( F f ) & -> ``['see below]``; ``[link reference_optional_flat_map __GO_TO__]``
|
||||
template<class F> constexpr auto flat_map( F f ) && -> ``['see below]``; ``[link reference_optional_flat_map_move __GO_TO__]``
|
||||
|
||||
constexpr operator optional<T&>() & noexcept; ``[link reference_optional_conversion_to_ref __GO_TO__]``
|
||||
constexpr operator optional<T const&&>() const& noexcept; ``[link reference_optional_conversion_to_ref __GO_TO__]``
|
||||
|
||||
T const* get_ptr() const ; ``[link reference_optional_get_ptr __GO_TO__]``
|
||||
T* get_ptr() ; ``[link reference_optional_get_ptr __GO_TO__]``
|
||||
|
||||
|
||||
@@ -751,6 +751,26 @@ __SPACE__
|
||||
|
||||
__SPACE__
|
||||
|
||||
|
||||
[#reference_optional_conversion_to_ref]
|
||||
|
||||
[: `constexpr optional<T>::operator optional<T&>() & noexcept ;`]
|
||||
|
||||
* [*Returns:] If `*this` contains a value `optional<T&>(**this)`, otherwise `optional<T&>()`.
|
||||
|
||||
[: `constexpr optional<T>::operator optional<T const&>() const& noexcept ;`]
|
||||
|
||||
* [*Returns:] If `*this` contains a value `optional<T const&>(**this)`, otherwise `optional<T&>()`.
|
||||
|
||||
* [*Example:]
|
||||
``
|
||||
const optional<int> oi = 1;
|
||||
optional<const int&> ri = oi;
|
||||
``
|
||||
|
||||
__SPACE__
|
||||
|
||||
|
||||
[#reference_optional_get_value_or_value]
|
||||
|
||||
[: `T const& optional<T>::get_value_or( T const& default) const ;`]
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
* Construct `o = u`, where `o` is of type `optional<T>` and `u` is of type `U` convertible to `T`,
|
||||
does not create a temporary `T`.
|
||||
|
||||
* In the said implementation, added a conversion from `optional<T>&` to `optional<T&>`.
|
||||
|
||||
* `none_t` is now `std::equality_comparable`, which means that `none_t` and `optional<T>`
|
||||
model concept `std::equality_comparable_with` (for `std::equality_comparable` `T`s),
|
||||
which means that you can `std::ranges::find(rng, boost::none)` for a range of optional objects.
|
||||
|
||||
@@ -379,6 +379,20 @@ namespace boost {
|
||||
: storage(in_place_init, optional_detail::forward_<Args>(args)...)
|
||||
{}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR operator optional<T&>() & noexcept
|
||||
{
|
||||
return this->has_value() ? optional<T&>(**this) : optional<T&>();
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR operator optional<const T&>() const& noexcept
|
||||
{
|
||||
return this->has_value() ? optional<const T&>(**this) : optional<const T&>();
|
||||
}
|
||||
|
||||
BOOST_CXX14_CONSTEXPR operator optional<T&>() && noexcept = delete;
|
||||
BOOST_CONSTEXPR operator optional<const T&>() const&& noexcept = delete;
|
||||
|
||||
|
||||
BOOST_CXX14_CONSTEXPR void reset() noexcept
|
||||
{
|
||||
storage.reset();
|
||||
|
||||
@@ -80,6 +80,7 @@ compile-fail optional_test_fail3b.cpp ;
|
||||
compile-fail optional_test_ref_fail1.cpp ;
|
||||
compile-fail optional_test_ref_fail3.cpp ;
|
||||
compile-fail optional_test_ref_fail4.cpp ;
|
||||
compile-fail optional_test_ref_fail_convert_from_temporary_optional_T.cpp ;
|
||||
compile-fail optional_test_inplace_fail.cpp ;
|
||||
compile-fail optional_test_inplace_fail2.cpp ;
|
||||
compile-fail optional_test_fail_implicit_bool_convert.cpp ;
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
|
||||
//
|
||||
// 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)
|
||||
//
|
||||
// See http://www.boost.org/lib/optional for documentation.
|
||||
//
|
||||
// You are welcome to contact the author at:
|
||||
// fernando_cacciola@hotmail.com
|
||||
//
|
||||
#include "boost/optional.hpp"
|
||||
|
||||
//
|
||||
// THIS TEST SHOULD FAIL TO COMPILE
|
||||
//
|
||||
void optional_reference__test_no_converting_initialization()
|
||||
{
|
||||
boost::optional<const int&> o (boost::optional<int>(1));
|
||||
(void)o;
|
||||
}
|
||||
@@ -24,7 +24,13 @@ using boost::none;
|
||||
struct Value
|
||||
{
|
||||
int val;
|
||||
explicit Value(int v) : val(v) {}
|
||||
BOOST_CONSTEXPR explicit Value(int v) : val(v) {}
|
||||
};
|
||||
|
||||
struct Guard
|
||||
{
|
||||
int val;
|
||||
BOOST_CONSTEXPR explicit Guard(int v) : val(v) {}
|
||||
};
|
||||
|
||||
int val(int const& i)
|
||||
@@ -37,6 +43,11 @@ int val(Value const& v)
|
||||
return v.val;
|
||||
}
|
||||
|
||||
int val(Guard const& v)
|
||||
{
|
||||
return v.val;
|
||||
}
|
||||
|
||||
template <typename Tref>
|
||||
optional<Tref&> make_opt_ref(Tref& v)
|
||||
{
|
||||
@@ -47,21 +58,21 @@ template <typename Tval, typename Tref>
|
||||
void test_construct_from_optional_ref()
|
||||
{
|
||||
Tref v1 (1), v2 (2);
|
||||
|
||||
|
||||
optional<Tref&> opt_ref0;
|
||||
optional<Tref&> opt_ref1 (v1);
|
||||
|
||||
|
||||
optional<Tval> opt_val0 (opt_ref0);
|
||||
optional<Tval> opt_val1 (opt_ref1);
|
||||
optional<Tval> opt_val2 (make_opt_ref(v2));
|
||||
|
||||
|
||||
BOOST_TEST (!opt_val0);
|
||||
BOOST_TEST (opt_val1);
|
||||
BOOST_TEST (opt_val2);
|
||||
|
||||
|
||||
BOOST_TEST_EQ (1, val(*opt_val1));
|
||||
BOOST_TEST_EQ (2, val(*opt_val2));
|
||||
|
||||
|
||||
BOOST_TEST (boost::addressof(*opt_val1) != boost::addressof(v1));
|
||||
BOOST_TEST (boost::addressof(*opt_val2) != boost::addressof(v2));
|
||||
}
|
||||
@@ -70,29 +81,121 @@ template <typename Tval, typename Tref>
|
||||
void test_assign_from_optional_ref()
|
||||
{
|
||||
Tref v1 (1), v2 (2);
|
||||
|
||||
|
||||
optional<Tref&> opt_ref0;
|
||||
optional<Tref&> opt_ref1 (v1);
|
||||
|
||||
|
||||
optional<Tval> opt_val0;
|
||||
optional<Tval> opt_val1;
|
||||
optional<Tval> opt_val2;
|
||||
|
||||
|
||||
opt_val0 = opt_ref0;
|
||||
opt_val1 = opt_ref1;
|
||||
opt_val2 = make_opt_ref(v2);
|
||||
|
||||
|
||||
BOOST_TEST (!opt_val0);
|
||||
BOOST_TEST (opt_val1);
|
||||
BOOST_TEST (opt_val2);
|
||||
|
||||
|
||||
BOOST_TEST_EQ (1, val(*opt_val1));
|
||||
BOOST_TEST_EQ (2, val(*opt_val2));
|
||||
|
||||
|
||||
BOOST_TEST (boost::addressof(*opt_val1) != boost::addressof(v1));
|
||||
BOOST_TEST (boost::addressof(*opt_val2) != boost::addressof(v2));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_convert_optional_T_to_optional_T_ref()
|
||||
{
|
||||
#ifdef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
using boost::optional;
|
||||
using boost::in_place_init;
|
||||
|
||||
{ // optional<T>& -> optional<T&>
|
||||
optional<T> ovN, ov1(in_place_init, 1), ov2(in_place_init, 2);
|
||||
|
||||
optional<T&> orN = ovN;
|
||||
optional<T&> or1 = ov1;
|
||||
optional<T&> or2 = ov2;
|
||||
|
||||
BOOST_TEST_EQ (!!orN, !!ovN);
|
||||
BOOST_TEST_EQ (!!or1, !!ov1);
|
||||
BOOST_TEST_EQ (!!or2, !!ov2);
|
||||
|
||||
BOOST_TEST (or1);
|
||||
BOOST_TEST (or2);
|
||||
BOOST_TEST_EQ (val(*or1), 1);
|
||||
BOOST_TEST_EQ (val(*or2), 2);
|
||||
BOOST_TEST (boost::addressof(*or1) == boost::addressof(*ov1));
|
||||
BOOST_TEST (boost::addressof(*or2) == boost::addressof(*ov2));
|
||||
}
|
||||
|
||||
{ // const optional<T>& -> optional<const T&>
|
||||
constexpr optional<T> ovN;
|
||||
constexpr optional<T> ov1(in_place_init, 1);
|
||||
constexpr optional<T> ov2(in_place_init, 2);
|
||||
|
||||
optional<const T&> orN = ovN;
|
||||
optional<const T&> or1 = ov1;
|
||||
optional<const T&> or2 = ov2;
|
||||
|
||||
BOOST_TEST_EQ (!!orN, !!ovN);
|
||||
BOOST_TEST_EQ (!!or1, !!ov1);
|
||||
BOOST_TEST_EQ (!!or2, !!ov2);
|
||||
|
||||
BOOST_TEST (or1);
|
||||
BOOST_TEST (or2);
|
||||
BOOST_TEST_EQ (val(*or1), 1);
|
||||
BOOST_TEST_EQ (val(*or2), 2);
|
||||
BOOST_TEST (boost::addressof(*or1) == boost::addressof(*ov1));
|
||||
BOOST_TEST (boost::addressof(*or2) == boost::addressof(*ov2));
|
||||
}
|
||||
|
||||
{ // optional<const T>& -> optional<const T&>
|
||||
optional<const T> ovN;
|
||||
optional<const T> ov1(in_place_init, 1);
|
||||
optional<const T> ov2(in_place_init, 2);
|
||||
|
||||
optional<const T&> orN = ovN;
|
||||
optional<const T&> or1 = ov1;
|
||||
optional<const T&> or2 = ov2;
|
||||
|
||||
BOOST_TEST_EQ (!!orN, !!ovN);
|
||||
BOOST_TEST_EQ (!!or1, !!ov1);
|
||||
BOOST_TEST_EQ (!!or2, !!ov2);
|
||||
|
||||
BOOST_TEST (or1);
|
||||
BOOST_TEST (or2);
|
||||
BOOST_TEST_EQ (val(*or1), 1);
|
||||
BOOST_TEST_EQ (val(*or2), 2);
|
||||
BOOST_TEST (boost::addressof(*or1) == boost::addressof(*ov1));
|
||||
BOOST_TEST (boost::addressof(*or2) == boost::addressof(*ov2));
|
||||
}
|
||||
|
||||
{ // optional<T>& -> optional<const T&>
|
||||
optional<T> ovN;
|
||||
optional<T> ov1(in_place_init, 1);
|
||||
optional<T> ov2(in_place_init, 2);
|
||||
|
||||
optional<const T&> orN = ovN;
|
||||
optional<const T&> or1 = ov1;
|
||||
optional<const T&> or2 = ov2;
|
||||
|
||||
BOOST_TEST_EQ (!!orN, !!ovN);
|
||||
BOOST_TEST_EQ (!!or1, !!ov1);
|
||||
BOOST_TEST_EQ (!!or2, !!ov2);
|
||||
|
||||
BOOST_TEST (or1);
|
||||
BOOST_TEST (or2);
|
||||
BOOST_TEST_EQ (val(*or1), 1);
|
||||
BOOST_TEST_EQ (val(*or2), 2);
|
||||
BOOST_TEST (boost::addressof(*or1) == boost::addressof(*ov1));
|
||||
BOOST_TEST (boost::addressof(*or2) == boost::addressof(*ov2));
|
||||
}
|
||||
|
||||
#endif // BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
@@ -100,17 +203,21 @@ int main()
|
||||
test_construct_from_optional_ref<int, int const>();
|
||||
test_construct_from_optional_ref<int const, int const>();
|
||||
test_construct_from_optional_ref<int const, int>();
|
||||
|
||||
|
||||
test_construct_from_optional_ref<Value, Value>();
|
||||
test_construct_from_optional_ref<Value, Value const>();
|
||||
test_construct_from_optional_ref<Value const, Value const>();
|
||||
test_construct_from_optional_ref<Value const, Value>();
|
||||
|
||||
|
||||
test_assign_from_optional_ref<int, int>();
|
||||
test_assign_from_optional_ref<int, int const>();
|
||||
|
||||
test_assign_from_optional_ref<Value, Value>();
|
||||
test_assign_from_optional_ref<Value, Value const>();
|
||||
|
||||
test_convert_optional_T_to_optional_T_ref<int>();
|
||||
test_convert_optional_T_to_optional_T_ref<Value>();
|
||||
test_convert_optional_T_to_optional_T_ref<Guard>();
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user