mirror of
https://github.com/boostorg/optional.git
synced 2026-06-11 20:01:10 +02:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0fca17a0a8 | |||
| 3ce5e44ae2 | |||
| 64aa3f918c | |||
| 003b1e5415 | |||
| d3f6501728 | |||
| 802715d295 | |||
| 437c1eb626 | |||
| 6a2e169f23 | |||
| f0059887bc | |||
| b8e5c07f2f |
@@ -142,8 +142,9 @@ jobs:
|
||||
- toolset: clang
|
||||
compiler: clang++-16
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-24.04
|
||||
os: ubuntu-latest
|
||||
install: clang-16
|
||||
container: ubuntu:24.04
|
||||
- toolset: clang
|
||||
compiler: clang++-17
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
@@ -224,6 +225,10 @@ jobs:
|
||||
cxxstd: 14,latest
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.1
|
||||
cxxstd: "11,14,17,20,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2019
|
||||
- toolset: msvc-14.2
|
||||
cxxstd: "14,17,20,latest"
|
||||
addrmd: 32,64
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
[library Boost.Optional
|
||||
[quickbook 1.4]
|
||||
[quickbook 1.7]
|
||||
[authors [Cacciola Carballal, Fernando Luis]]
|
||||
[copyright 2003-2007 Fernando Luis Cacciola Carballal]
|
||||
[copyright 2014-2026 Andrzej Krzemieński]
|
||||
[copyright 2014-2026 Andrzej Krzemieński]
|
||||
[category miscellaneous]
|
||||
[id optional]
|
||||
[dirname optional]
|
||||
|
||||
@@ -27,7 +27,7 @@ rather than the reference itself.
|
||||
On compilers that do not conform to Standard C++ rules of reference binding,
|
||||
some operations on optional references are disabled in order to prevent subtle
|
||||
bugs. For more details see
|
||||
[link boost_optional.dependencies_and_portability.optional_reference_binding Dependencies and Portability section].
|
||||
[link optional_reference_binding Dependencies and Portability section].
|
||||
]
|
||||
|
||||
[heading Rvalue references]
|
||||
@@ -39,6 +39,8 @@ Rvalue references and lvalue references to const have the ability in C++ to exte
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
[#optional_ref_rebinding_semantics]
|
||||
[section Rebinding semantics for assignment of optional references]
|
||||
|
||||
If you assign to an ['uninitialized ] `optional<T&>` the effect is to bind (for
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
[section In-Place Factories]
|
||||
[section:in_place_factories In-Place Factories][#boost_optional_factories]
|
||||
|
||||
One of the typical problems with wrappers and containers is that their
|
||||
interfaces usually provide an operation to initialize or assign the
|
||||
@@ -138,4 +138,4 @@ The factories are implemented in the headers: __IN_PLACE_FACTORY_HPP__ and __TYP
|
||||
|
||||
[caution The support for in-place factories is deprecated. Use constructor taking `in_place_init` tag and function `.emplace()` instead.]
|
||||
|
||||
[endsect]
|
||||
[endsect:in_place_factories]
|
||||
|
||||
@@ -8,7 +8,7 @@ The very minimum requirement of `optional<T>` is that `T` is a complete type and
|
||||
assert(!o); //
|
||||
o.value(); // always throws
|
||||
|
||||
But this is practically useless. In order for `optional<T>` to be able to do anything useful and offer all the spectrum of ways of accessing the contained value, `T` needs to have at least one accessible constructor. In that case you need to initialize the optional object with function `emplace()`, or if your compiler does not support it, resort to [link boost_optional.design.in_place_factories In-Place Factories]:
|
||||
But this is practically useless. In order for `optional<T>` to be able to do anything useful and offer all the spectrum of ways of accessing the contained value, `T` needs to have at least one accessible constructor. In that case you need to initialize the optional object with function `emplace()`, or if your compiler does not support it, resort to [link boost_optional_factories In-Place Factories]:
|
||||
|
||||
optional<T> o;
|
||||
o.emplace("T", "ctor", "params");
|
||||
|
||||
+14
-3
@@ -2,7 +2,7 @@
|
||||
Boost.Optional
|
||||
|
||||
Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal
|
||||
Copyright (c) 2015 Andrzej Krzemienski
|
||||
Copyright (c) 2015 Andrzej Krzemieński
|
||||
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -15,14 +15,25 @@
|
||||
```
|
||||
namespace boost {
|
||||
|
||||
class none_t {/* see below */};
|
||||
class none_t
|
||||
{
|
||||
friend constexpr bool operator==(none_t, none_t) = default;
|
||||
/* see below */
|
||||
};
|
||||
|
||||
inline constexpr none_t none (/* see below */);
|
||||
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
Class `none_t` is meant to serve as a tag for selecting appropriate overloads of from `optional`'s interface. It is an empty, trivially copyable class with disabled default constructor.
|
||||
Class `none_t` is meant to serve as a tag for selecting appropriate overloads of from `optional`'s interface.
|
||||
It is an empty class.
|
||||
|
||||
It is [@https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable.html trivially copyable].
|
||||
|
||||
It is ['not] [@https://en.cppreference.com/w/cpp/named_req/DefaultConstructible default-constructible].
|
||||
|
||||
It models concept [@https://en.cppreference.com/w/cpp/concepts/equality_comparable `std::equality_comparable`].
|
||||
|
||||
Constant `none` is used to indicate an optional object that does not contain a value in initialization, assignment and relational operations of `optional`.
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@ factory.
|
||||
* [*Postconditions: ] `*this` is [_initialized] and its value is ['directly given]
|
||||
from the factory `f` (i.e., the value [_is not copied]).
|
||||
* [*Throws:] Whatever the `T` constructor called by the factory throws.
|
||||
* [*Notes:] See [link boost_optional.design.in_place_factories In-Place Factories]
|
||||
* [*Notes:] See [link boost_optional_factories In-Place Factories]
|
||||
* [*Exception Safety:] Exceptions can only be thrown during the call to
|
||||
the `T` constructor used by the factory; in that case, this constructor has
|
||||
no effect.
|
||||
@@ -524,7 +524,7 @@ factory.
|
||||
* [*Postconditions: ] `*this` is [_initialized] and its value is ['directly given]
|
||||
from the factory `f` (i.e., the value [_is not copied]).
|
||||
* [*Throws:] Whatever the `T` constructor called by the factory throws.
|
||||
* [*Notes:] See [link boost_optional.design.in_place_factories In-Place Factories]
|
||||
* [*Notes:] See [link boost_optional_factories In-Place Factories]
|
||||
* [*Exception Safety:] Exceptions can only be thrown during the call to
|
||||
the `T` constructor used by the factory; in that case, the `optional` object
|
||||
will be reset to be ['uninitialized].
|
||||
@@ -956,7 +956,7 @@ __SPACE__
|
||||
|
||||
* [*Postconditions:] `bool(*this) == bool(rhs)`.
|
||||
|
||||
* [*Notes:] This behaviour is called ['rebinding semantics]. See [link boost_optional.design.optional_references.rebinding_semantics_for_assignment_of_optional_references here] for details.
|
||||
* [*Notes:] This behaviour is called ['rebinding semantics]. See [link optional_ref_rebinding_semantics here] for details.
|
||||
|
||||
* [*Example:]
|
||||
``
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
[section Header <boost/optional.hpp>]
|
||||
|
||||
This is an alias for header [link boost_optional.reference.header__boost_optional_optional_hpp_.header_optional_optional `<boost/optional/optional.hpp>`].
|
||||
This is an alias for header [link ref_header_optional_optional_hpp `<boost/optional/optional.hpp>`].
|
||||
|
||||
|
||||
[endsect]
|
||||
|
||||
+45
-3
@@ -13,13 +13,55 @@
|
||||
|
||||
|
||||
[section Minimum System Requirements]
|
||||
This library requires C++11 as minimum. However some features are disabled.
|
||||
This library requires C++11 as minimum. However, in C++11 some features are disabled.
|
||||
|
||||
For C++14 and higher this library provides a `constexpr` interface for non-mutable
|
||||
member functions and some mutable member functions.
|
||||
[section:constexpr Support for `constexpr`]
|
||||
|
||||
[section C++11]
|
||||
For compilers fully supporting C++11 (including unconstrained unions and ref-qualifiers),
|
||||
for trivially-destructible `T`s, `optional<T>` is a ['literal type] and its constructors
|
||||
with `this->has_value() == false` as postcondition:
|
||||
|
||||
* `optional()`,
|
||||
* `optional(none_t)`,
|
||||
|
||||
are ['core constant expressions]. Even for other `T`s, these constructors are guaranteed to
|
||||
perform ['constant initialization]: they are never subject to "initialization order fiasco".
|
||||
|
||||
Other constructors with `this->has_value() == true`
|
||||
as postcondition are core constant expressions if the expression required to initialize
|
||||
the contained value is a core constant expression. This includes constructors:
|
||||
|
||||
* `template <typename... Args> optional(in_place_init, Args&&...)`,
|
||||
* `template <typename U> optional(U&&)`,
|
||||
* `optional(const T&)`,
|
||||
* `optional(T&&)`.
|
||||
|
||||
Other constructors, including the copy and move constructos, are ['not] core constant expressions.
|
||||
|
||||
Member functions `.has_value`, `operator bool` and (non)equality comparisons with `none` are core-constant expressions for trivially-destructible `T`s.
|
||||
|
||||
Also all `const`-qualified non-static member functions and comparison operators are core constant expressions, if the corresponding operations on `T`
|
||||
are core constant expressions.
|
||||
[endsect]
|
||||
|
||||
[section C++14]
|
||||
For C++14 and higher this library, for trivially-destructible `T`s provides the `constexpr` interface for all mutable and non-mutable
|
||||
member functions, as long as:
|
||||
|
||||
* the corresponding operations on `T` are core constant expressions and
|
||||
* the member never attempts to change the `optional`'s state from not containing a value to containing a value.
|
||||
|
||||
[note For types that overload unary `operator&` (address) some member functions in `optional`, like `operator->`,
|
||||
cannot be implemented as `constexpr` on some compilers.]
|
||||
[endsect]
|
||||
|
||||
[section C++17]
|
||||
In C++17 all non-deprecated constructors are core constant expressions as long as
|
||||
`T` is a literal type and its constructor used is a core constant expression.
|
||||
[endsect]
|
||||
|
||||
[endsect:constexpr]
|
||||
|
||||
[endsect]
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
|
||||
[section:std_comp Comparison with `std::optional`]
|
||||
|
||||
[table
|
||||
[]
|
||||
[table Comparison with `std::optional`
|
||||
[ [[*`boost::optional`]] [[*`std::optional`]] [] ]
|
||||
[ [`optional<int> o = none;`] [`optional<int> o = nullopt;`] [Different name for no-value tag.] ]
|
||||
[ [`optional<X> o {in_place_init, a, b};`] [`optional<int> o {in_place, a, b};`] [Different name for in-place initialization tag.] ]
|
||||
@@ -42,6 +41,12 @@
|
||||
[ [`make_optional(cond, v);`] [] [No `make_optional` with condition in `std`.] ]
|
||||
[ [] [`make_optional<T>(a, b);`] [No `make_optional` with specified `T` in `boost`.] ]
|
||||
[ [`std::cout << optional<int>{};`] [] [No printing to IOStreams in `std`.]]
|
||||
|
||||
[ [`std::vector<optional<int>> rng;`
|
||||
|
||||
`std::ranges::find(rng, boost::none)`] [`std::vector<optional<int>> rng;`
|
||||
|
||||
`std::ranges::find(rng, boost::optional<int>{})`] [optional<T> is never [@https://en.cppreference.com/w/cpp/concepts/equality_comparable `std::equality_comparable_with`] `nullopt_t` in `std`. ] ]
|
||||
]
|
||||
|
||||
|
||||
|
||||
@@ -11,9 +11,35 @@
|
||||
|
||||
[section:relnotes Release Notes]
|
||||
|
||||
[heading Boost Release 1.91]
|
||||
|
||||
* For compilers with full C++11 support (including "unrestricted unions" and ref-qualifiers)
|
||||
changed the implementation from aligned storage to union storage. This enables the gradual
|
||||
`constexpr` support:
|
||||
|
||||
* In C++11, some constructors and `const`-qualified accessors become usable
|
||||
in compile-time contexts (are ['core constant expressions] for types
|
||||
satisfying certain constraints.
|
||||
* In C++14 even some mutating operations become core constant expressions (those
|
||||
that do not require changing the state of `optional` from not having a value to
|
||||
having a value), for co-operating types.
|
||||
* In C++17 all constructors (including copy and move) become core constant expressions
|
||||
for co-operating types.
|
||||
|
||||
This addresses [@https://github.com/boostorg/optional/issues/143 issue #143].
|
||||
|
||||
* *Breaking change.* In the said implementation, abandoned the mechanism for customizing
|
||||
`swap`. Hardly anyone knows about this mechanism and it was never documented.
|
||||
|
||||
* In the said implementation, applied a couple of small changes to get closer to the interface of `std::optional`:
|
||||
* Enabled syntax `o = {}` for putting optional objects to no-value state.
|
||||
* Enabled syntax `o.value_or({})`, which uses a default-constructed `T`.
|
||||
* 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`.
|
||||
|
||||
* `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.
|
||||
|
||||
[heading Boost Release 1.87]
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
#elif defined(BOOST_NO_CXX11_REF_QUALIFIERS) || defined(BOOST_NO_CXX11_NOEXCEPT) || defined(BOOST_NO_CXX11_DEFAULTED_MOVES)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("C++03 support is deprecated in Boost.Optional 1.83 and will be removed in Boost.Optional 1.88.")
|
||||
BOOST_PRAGMA_MESSAGE("C++03 support is deprecated in Boost.Optional 1.83 and will be removed in Boost.Optional 1.92.")
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,6 +46,11 @@ struct none_t
|
||||
{
|
||||
struct init_tag{};
|
||||
explicit BOOST_CONSTEXPR none_t(init_tag){} // to disable default constructor
|
||||
|
||||
#ifndef BOOST_OPTIONAL_DISABLE_EQUALITY_FOR_NONE
|
||||
friend BOOST_CONSTEXPR bool operator==(none_t, none_t) { return true; }
|
||||
friend BOOST_CONSTEXPR bool operator!=(none_t, none_t) { return false; }
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // old implementation workarounds
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/addressof.hpp>
|
||||
#include <type_traits>
|
||||
#include <boost/optional/detail/optional_factory_support.hpp>
|
||||
|
||||
#ifndef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
#include <boost/type_traits/decay.hpp>
|
||||
|
||||
@@ -195,6 +195,31 @@ namespace boost {
|
||||
storage.init_ = true;
|
||||
}
|
||||
|
||||
#ifdef BOOST_OPTIONAL_CONSTEXPR_COPY
|
||||
// The conditional initialization of storage needs to employ a factory
|
||||
// function, so that we can utilize the guaranteed copy elision on the
|
||||
// return type.
|
||||
// an alternative -- using a conditional operator in the initializer --
|
||||
// does not work in MSVC 14.2 and 14.3.
|
||||
template <typename... U>
|
||||
static constexpr storage_t conditional_storage_from_values(bool cond, U&&... v)
|
||||
{
|
||||
if (cond)
|
||||
return storage_t(in_place_init, optional_detail::forward_<U>(v)...);
|
||||
else
|
||||
return storage_t();
|
||||
}
|
||||
|
||||
template <typename OU>
|
||||
static constexpr storage_t conditional_storage_from_optional(OU&& ou)
|
||||
{
|
||||
if (ou.has_value())
|
||||
return storage_t(in_place_init, *optional_detail::forward_<OU>(ou));
|
||||
else
|
||||
return storage_t();
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
using unqualified_value_type = typename ::std::remove_const<T>::type;
|
||||
@@ -218,35 +243,35 @@ namespace boost {
|
||||
|
||||
#ifdef BOOST_OPTIONAL_CONSTEXPR_COPY
|
||||
constexpr optional(bool cond, const T& v)
|
||||
: storage(cond ? storage_t(v) : storage_t())
|
||||
: storage(conditional_storage_from_values(cond, v))
|
||||
{}
|
||||
|
||||
constexpr optional(bool cond, T&& v)
|
||||
: storage(cond ? storage_t(optional_detail::move_(v)) : storage_t())
|
||||
: storage(conditional_storage_from_values(cond, optional_detail::move_(v)))
|
||||
{}
|
||||
|
||||
constexpr optional(const optional& rhs)
|
||||
: storage(rhs.is_initialized() ? storage_t(*rhs) : storage_t())
|
||||
: storage(conditional_storage_from_optional(rhs))
|
||||
{}
|
||||
|
||||
constexpr optional(optional&& rhs)
|
||||
noexcept(::std::is_nothrow_move_constructible<T>::value)
|
||||
: storage(rhs.is_initialized() ? storage_t(*optional_detail::move_(rhs)) : storage_t())
|
||||
: storage(conditional_storage_from_optional(optional_detail::move_(rhs)))
|
||||
{}
|
||||
|
||||
template <typename U, BOOST_OPTIONAL_REQUIRES(::std::is_constructible<T, U const&>)>
|
||||
constexpr explicit optional(optional<U> const& rhs)
|
||||
: storage(rhs.is_initialized() ? storage_t(in_place_init, *rhs) : storage_t())
|
||||
: storage(conditional_storage_from_optional(rhs))
|
||||
{}
|
||||
|
||||
template <typename U, BOOST_OPTIONAL_REQUIRES(::std::is_constructible<T, U&&>)>
|
||||
constexpr explicit optional(optional<U> && rhs)
|
||||
: storage(rhs.is_initialized() ? storage_t(in_place_init, *optional_detail::move_(rhs)) : storage_t())
|
||||
: storage(conditional_storage_from_optional(optional_detail::move_(rhs)))
|
||||
{}
|
||||
|
||||
template <typename... Args>
|
||||
constexpr explicit optional( in_place_init_if_t, bool cond, Args&&... args )
|
||||
: storage( cond ? storage_t(in_place_init, optional_detail::forward_<Args>(args)...) : storage_t() )
|
||||
: storage(conditional_storage_from_values(cond, optional_detail::forward_<Args>(args)...))
|
||||
{}
|
||||
#else
|
||||
optional(bool cond, const T& v)
|
||||
@@ -319,7 +344,7 @@ namespace boost {
|
||||
explicit optional (FT&& factory)
|
||||
: storage()
|
||||
{
|
||||
factory.template apply<T>(this->dataptr());
|
||||
boost_optional_detail::construct<value_type>(factory, this->dataptr());
|
||||
storage.init_ = true;
|
||||
}
|
||||
|
||||
@@ -454,7 +479,7 @@ namespace boost {
|
||||
optional& operator=(F&& factory)
|
||||
{
|
||||
reset();
|
||||
factory.template apply<T>(this->dataptr());
|
||||
boost_optional_detail::construct<value_type>(factory, this->dataptr());
|
||||
storage.init_ = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -84,10 +84,8 @@ operator<<(std::basic_ostream<CharType, CharTrait>& os, optional_detail::optiona
|
||||
#include <boost/type_traits/is_volatile.hpp>
|
||||
#include <boost/type_traits/is_scalar.hpp>
|
||||
|
||||
|
||||
#include <boost/optional/optional_fwd.hpp>
|
||||
#include <boost/optional/detail/optional_config.hpp>
|
||||
#include <boost/optional/detail/optional_factory_support.hpp>
|
||||
#include <boost/optional/detail/optional_aligned_storage.hpp>
|
||||
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ run optional_test_flat_map.cpp ;
|
||||
run optional_test_hash.cpp ;
|
||||
run optional_test_map.cpp ;
|
||||
run optional_test_tie.cpp : : : <library>/boost/tuple//boost_tuple ;
|
||||
run optional_test_ranges_find.cpp ;
|
||||
run optional_test_ref_assign_portable_minimum.cpp ;
|
||||
run optional_test_ref_assign_mutable_int.cpp ;
|
||||
run optional_test_ref_assign_const_int.cpp ;
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
// akrzemi1@gmail.com
|
||||
|
||||
#include "boost/optional.hpp"
|
||||
#include <string>
|
||||
|
||||
#ifdef BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
|
||||
@@ -20,6 +21,16 @@ struct Record
|
||||
constexpr int operator()() const { return i; }
|
||||
};
|
||||
|
||||
struct Guard
|
||||
{
|
||||
int i;
|
||||
constexpr explicit Guard(int i) : i(i) {}
|
||||
Guard(Guard&&) = delete;
|
||||
};
|
||||
|
||||
static_assert(boost::none == boost::none, "");
|
||||
static_assert(!(boost::none != boost::none), "");
|
||||
|
||||
namespace test_int
|
||||
{
|
||||
constexpr boost::optional<int> oN;
|
||||
@@ -52,7 +63,7 @@ namespace test_int
|
||||
static_assert(o2 != o1, "");
|
||||
static_assert(o2 > o1, "");
|
||||
|
||||
#ifndef BOOST_NO_CXX14_CONSTEXPR
|
||||
#ifdef BOOST_OPTIONAL_CONSTEXPR_COPY
|
||||
constexpr boost::optional<int> oNc = oN;
|
||||
constexpr boost::optional<int> oNd = boost::none;
|
||||
constexpr boost::optional<int> oNe = {};
|
||||
@@ -88,6 +99,29 @@ namespace test_record
|
||||
static_assert(r2.value().i == 2, "");
|
||||
}
|
||||
|
||||
namespace test_guard
|
||||
{
|
||||
constexpr boost::optional<Guard> g1 {boost::in_place_init, 1};
|
||||
constexpr boost::optional<Guard> gNa {boost::none};
|
||||
constexpr boost::optional<Guard> gNb;
|
||||
|
||||
static_assert(g1, "");
|
||||
static_assert(!!g1, "");
|
||||
static_assert(g1 != boost::none, "");
|
||||
static_assert(!(g1 == boost::none), "");
|
||||
static_assert(g1.has_value(), "");
|
||||
|
||||
static_assert(!gNa, "");
|
||||
static_assert(!gNa.has_value(), "");
|
||||
static_assert(gNa == boost::none, "");
|
||||
static_assert(!(gNa != boost::none), "");
|
||||
|
||||
static_assert(!gNb, "");
|
||||
static_assert(!gNb.has_value(), "");
|
||||
static_assert(gNb == boost::none, "");
|
||||
static_assert(!(gNb != boost::none), "");
|
||||
}
|
||||
|
||||
namespace test_optional_ref
|
||||
{
|
||||
constexpr int gi = 9;
|
||||
@@ -96,4 +130,24 @@ namespace test_optional_ref
|
||||
static_assert(*iref == 9, "");
|
||||
}
|
||||
|
||||
namespace test_msvc_14_1
|
||||
{
|
||||
struct Aggr
|
||||
{
|
||||
boost::optional<std::string> os;
|
||||
};
|
||||
|
||||
void test()
|
||||
{
|
||||
Aggr a;
|
||||
Aggr b = a;
|
||||
b = a;
|
||||
Aggr c = Aggr();
|
||||
b = Aggr();
|
||||
(void)a;
|
||||
(void)b;
|
||||
(void)c;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_OPTIONAL_USES_UNION_IMPLEMENTATION
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright (C) 2026 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
|
||||
// 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:
|
||||
// akrzemi1@gmail.com
|
||||
|
||||
|
||||
#include "boost/optional/optional.hpp"
|
||||
#include "boost/core/lightweight_test.hpp"
|
||||
#include <type_traits>
|
||||
|
||||
#ifndef BOOST_NO_CXX20_HDR_RANGES
|
||||
#include <ranges>
|
||||
#include <concepts>
|
||||
#include <iterator>
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
static_assert(std::equality_comparable<boost::none_t>, "boost::none shall be equality comparable");
|
||||
|
||||
|
||||
template <typename T>
|
||||
void test_that_you_can_find_none_in_a_range_of_optional(T x, T y)
|
||||
{
|
||||
static_assert(std::equality_comparable_with<boost::optional<T>, boost::none_t>, "boost::none shall satisfy the concept");
|
||||
static_assert(std::equality_comparable_with<boost::none_t, boost::optional<T> >, "boost::none shall satisfy the concept");
|
||||
static_assert(std::indirect_binary_predicate<std::ranges::equal_to, const boost::optional<T>*, const boost::none_t*>, "boost::none shall satisfy the concept");
|
||||
|
||||
// [0] [1] [2]
|
||||
std::array<boost::optional<T>, 3> arr = {{ x, boost::none, y }};
|
||||
auto it = std::ranges::find(arr, boost::none);
|
||||
BOOST_TEST_EQ(std::distance(arr.begin(), it), 1);
|
||||
}
|
||||
#endif // BOOST_NO_CXX20_HDR_RANGES
|
||||
|
||||
|
||||
# if (defined __GNUC__) && (!defined BOOST_INTEL_CXX_VERSION) && (!defined __clang__)
|
||||
# if (__GNUC__ <= 4)
|
||||
# define BOOST_OPTIONAL_TEST_INSUFFICIENT_TYPE_TRAIT_SUPPORT
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#ifndef BOOST_OPTIONAL_TEST_INSUFFICIENT_TYPE_TRAIT_SUPPORT
|
||||
static_assert(std::is_trivially_copyable<boost::none_t>::value, "boost::none shall be trivially copyable");
|
||||
#endif
|
||||
|
||||
|
||||
void test_that_none_is_equal_to_none()
|
||||
{
|
||||
BOOST_TEST(boost::none == boost::none);
|
||||
BOOST_TEST(!(boost::none != boost::none));
|
||||
auto None = boost::none;
|
||||
BOOST_TEST(None == boost::none);
|
||||
BOOST_TEST(!(None != boost::none));
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef BOOST_NO_CXX20_HDR_RANGES
|
||||
test_that_you_can_find_none_in_a_range_of_optional(1, 2);
|
||||
test_that_you_can_find_none_in_a_range_of_optional<std::string>("one", "two");
|
||||
#endif
|
||||
test_that_none_is_equal_to_none();
|
||||
return boost::report_errors();
|
||||
}
|
||||
Reference in New Issue
Block a user