Skip to content

Commit 046357c

Browse files
committed
Add more robust constexpr support
1 parent b6a57cd commit 046357c

27 files changed

+621
-247
lines changed

doc/00_optional.qbk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
[library Boost.Optional
2-
[quickbook 1.4]
2+
[quickbook 1.7]
33
[authors [Cacciola Carballal, Fernando Luis]]
44
[copyright 2003-2007 Fernando Luis Cacciola Carballal]
5-
[copyright 2014-2026 Andrzej Krzemieński]
5+
[copyright 2014-2026 Andrzej Krzemieński]
66
[category miscellaneous]
77
[id optional]
88
[dirname optional]

doc/16_optional_references.qbk

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ rather than the reference itself.
2727
On compilers that do not conform to Standard C++ rules of reference binding,
2828
some operations on optional references are disabled in order to prevent subtle
2929
bugs. For more details see
30-
[link boost_optional.dependencies_and_portability.optional_reference_binding Dependencies and Portability section].
30+
[link optional_reference_binding Dependencies and Portability section].
3131
]
3232

3333
[heading Rvalue references]
@@ -39,6 +39,8 @@ Rvalue references and lvalue references to const have the ability in C++ to exte
3939

4040
[endsect]
4141

42+
43+
[#optional_ref_rebinding_semantics]
4244
[section Rebinding semantics for assignment of optional references]
4345

4446
If you assign to an ['uninitialized ] `optional<T&>` the effect is to bind (for

doc/17_in_place_factories.qbk

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
[section In-Place Factories]
2+
[section:in_place_factories In-Place Factories][#boost_optional_factories]
33

44
One of the typical problems with wrappers and containers is that their
55
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
138138

139139
[caution The support for in-place factories is deprecated. Use constructor taking `in_place_init` tag and function `.emplace()` instead.]
140140

141-
[endsect]
141+
[endsect:in_place_factories]

doc/1A_type_requirements.qbk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ The very minimum requirement of `optional<T>` is that `T` is a complete type and
88
assert(!o); //
99
o.value(); // always throws
1010

11-
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]:
11+
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]:
1212

1313
optional<T> o;
1414
o.emplace("T", "ctor", "params");

doc/21_ref_none.qbk

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Boost.Optional
33

44
Copyright (c) 2003-2007 Fernando Luis Cacciola Carballal
5-
Copyright (c) 2015 Andrzej Krzemienski
5+
Copyright (c) 2015 Andrzej Krzemieński
66

77
Distributed under the Boost Software License, Version 1.0.
88
(See accompanying file LICENSE_1_0.txt or copy at
@@ -15,14 +15,25 @@
1515
```
1616
namespace boost {
1717

18-
class none_t {/* see below */};
18+
class none_t
19+
{
20+
friend constexpr bool operator==(none_t, none_t) = default;
21+
/* see below */
22+
};
1923

2024
inline constexpr none_t none (/* see below */);
2125

2226
} // namespace boost
2327
```
2428

25-
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.
29+
Class `none_t` is meant to serve as a tag for selecting appropriate overloads of from `optional`'s interface.
30+
It is an empty class.
31+
32+
It is [@https://en.cppreference.com/w/cpp/named_req/TriviallyCopyable.html trivially copyable].
33+
34+
It is ['not] [@https://en.cppreference.com/w/cpp/named_req/DefaultConstructible default-constructible].
35+
36+
It models concept [@https://en.cppreference.com/w/cpp/concepts/equality_comparable `std::equality_comparable`].
2637

2738
Constant `none` is used to indicate an optional object that does not contain a value in initialization, assignment and relational operations of `optional`.
2839

doc/28_ref_optional_semantics.qbk

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ factory.
281281
* [*Postconditions: ] `*this` is [_initialized] and its value is ['directly given]
282282
from the factory `f` (i.e., the value [_is not copied]).
283283
* [*Throws:] Whatever the `T` constructor called by the factory throws.
284-
* [*Notes:] See [link boost_optional.design.in_place_factories In-Place Factories]
284+
* [*Notes:] See [link boost_optional_factories In-Place Factories]
285285
* [*Exception Safety:] Exceptions can only be thrown during the call to
286286
the `T` constructor used by the factory; in that case, this constructor has
287287
no effect.
@@ -524,7 +524,7 @@ factory.
524524
* [*Postconditions: ] `*this` is [_initialized] and its value is ['directly given]
525525
from the factory `f` (i.e., the value [_is not copied]).
526526
* [*Throws:] Whatever the `T` constructor called by the factory throws.
527-
* [*Notes:] See [link boost_optional.design.in_place_factories In-Place Factories]
527+
* [*Notes:] See [link boost_optional_factories In-Place Factories]
528528
* [*Exception Safety:] Exceptions can only be thrown during the call to
529529
the `T` constructor used by the factory; in that case, the `optional` object
530530
will be reset to be ['uninitialized].
@@ -956,7 +956,7 @@ __SPACE__
956956

957957
* [*Postconditions:] `bool(*this) == bool(rhs)`.
958958

959-
* [*Notes:] This behaviour is called ['rebinding semantics]. See [link boost_optional.design.optional_references.rebinding_semantics_for_assignment_of_optional_references here] for details.
959+
* [*Notes:] This behaviour is called ['rebinding semantics]. See [link optional_ref_rebinding_semantics here] for details.
960960

961961
* [*Example:]
962962
``

doc/29_ref_optional_convenience.qbk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
[section Header <boost/optional.hpp>]
1313

14-
This is an alias for header [link boost_optional.reference.header__boost_optional_optional_hpp_.header_optional_optional `<boost/optional/optional.hpp>`].
14+
This is an alias for header [link ref_header_optional_optional_hpp `<boost/optional/optional.hpp>`].
1515

1616

1717
[endsect]

doc/90_dependencies.qbk

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,55 @@
1313

1414

1515
[section Minimum System Requirements]
16-
This library requires C++11 as minimum. However some features are disabled.
16+
This library requires C++11 as minimum. However, in C++11 some features are disabled.
1717

18-
For C++14 and higher this library provides a `constexpr` interface for non-mutable
19-
member functions and some mutable member functions.
18+
[section:constexpr Support for `constexpr`]
19+
20+
[section C++11]
21+
For compilers fully supporting C++11 (including unconstrained unions and ref-qualifiers),
22+
for trivially-destructible `T`s, `optional<T>` is a ['literal type] and its constructors
23+
with `this->has_value() == false` as postcondition:
24+
25+
* `optional()`,
26+
* `optional(none_t)`,
27+
28+
are ['core constant expressions]. Even for other `T`s, these constructors are guaranteed to
29+
perform ['constant initialization]: they are never subject to "initialization order fiasco".
30+
31+
Other constructors with `this->has_value() == true`
32+
as postcondition are core constant expressions if the expression required to initialize
33+
the contained value is a core constant expression. This includes constructors:
34+
35+
* `template <typename... Args> optional(in_place_init, Args&&...)`,
36+
* `template <typename U> optional(U&&)`,
37+
* `optional(const T&)`,
38+
* `optional(T&&)`.
39+
40+
Other constructors, including the copy and move constructos, are ['not] core constant expressions.
41+
42+
Member functions `.has_value`, `operator bool` and (non)equality comparisons with `none` are core-constant expressions for trivially-destructible `T`s.
43+
44+
Also all `const`-qualified non-static member functions and comparison operators are core constant expressions, if the corresponding operations on `T`
45+
are core constant expressions.
46+
[endsect]
47+
48+
[section C++14]
49+
For C++14 and higher this library, for trivially-destructible `T`s provides the `constexpr` interface for all mutable and non-mutable
50+
member functions, as long as:
51+
52+
* the corresponding operations on `T` are core constant expressions and
53+
* the member never attempts to change the `optional`'s state from not containing a value to containing a value.
2054

2155
[note For types that overload unary `operator&` (address) some member functions in `optional`, like `operator->`,
2256
cannot be implemented as `constexpr` on some compilers.]
57+
[endsect]
58+
59+
[section C++17]
60+
In C++17 all non-deprecated constructors are core constant expressions as long as
61+
`T` is a literal type and its constructor used is a core constant expression.
62+
[endsect]
63+
64+
[endsect:constexpr]
2365

2466
[endsect]
2567

doc/91_comparison_with_std.qbk

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111

1212
[section:std_comp Comparison with `std::optional`]
1313

14-
[table
15-
[]
14+
[table Comparison with `std::optional`
1615
[ [[*`boost::optional`]] [[*`std::optional`]] [] ]
1716
[ [`optional<int> o = none;`] [`optional<int> o = nullopt;`] [Different name for no-value tag.] ]
1817
[ [`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 @@
4241
[ [`make_optional(cond, v);`] [] [No `make_optional` with condition in `std`.] ]
4342
[ [] [`make_optional<T>(a, b);`] [No `make_optional` with specified `T` in `boost`.] ]
4443
[ [`std::cout << optional<int>{};`] [] [No printing to IOStreams in `std`.]]
44+
45+
[ [`std::vector<optional<int>> rng;`
46+
47+
`std::ranges::find(rng, boost::none)`] [`std::vector<optional<int>> rng;`
48+
49+
`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`. ] ]
4550
]
4651

4752

doc/92_relnotes.qbk

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,35 @@
1111

1212
[section:relnotes Release Notes]
1313

14-
15-
16-
14+
[heading Boost Release 1.91]
15+
16+
* For compilers with full C++11 support (including "unrestricted unions" and ref-qualifiers)
17+
changed the implementation from aligned storage to union storage. This enables the gradual
18+
`constexpr` support:
19+
20+
* In C++11, some constructors and `const`-qualified accessors become usable
21+
in compile-time contexts (are ['core constant expressions] for types
22+
satisfying certain constraints.
23+
* In C++14 even some mutating operations become core constant expressions (those
24+
that do not require changing the state of `optional` from not having a value to
25+
having a value), for co-operating types.
26+
* In C++17 all constructors (including copy and move) become core constant expressions
27+
for co-operating types.
28+
29+
This addresses [@https://github.com/boostorg/optional/issues/143 issue #143].
30+
31+
* *Breaking change.* In the said implementation, abandoned the mechanism for customizing
32+
`swap`. Hardly anyone knows about this mechanism and it was never documented.
33+
34+
* In the said implementation, applied a couple of small changes to get closer to the interface of `std::optional`:
35+
* Enabled syntax `o = {}` for putting optional objects to no-value state.
36+
* Enabled syntax `o.value_or({})`, which uses a default-constructed `T`.
37+
* Construct `o = u`, where `o` is of type `optional<T>` and `u` is of type `U` convertible to `T`,
38+
does not create a temporary `T`.
39+
40+
* `none_t` is now `std::equality_comparable`, which means that `none_t` and `optional<T>`
41+
model concept `std::equality_comparable_with` (for `std::equality_comparable` `T`s),
42+
which means that you can `std::ranges::find(rng, boost::none)` for a range of optional objects.
1743

1844
[heading Boost Release 1.87]
1945

0 commit comments

Comments
 (0)