From 92c24da9a1d48d75d48e535375055e194653cc12 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 29 Oct 2023 03:10:27 +0200 Subject: [PATCH] Document operator| --- doc/system/changes.adoc | 1 + doc/system/reference.adoc | 117 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/doc/system/changes.adoc b/doc/system/changes.adoc index 2efa68d..427cefd 100644 --- a/doc/system/changes.adoc +++ b/doc/system/changes.adoc @@ -11,6 +11,7 @@ https://www.boost.org/LICENSE_1_0.txt ## Changes in Boost 1.84 * Added support for `result`. +* Added `operator|` for `result`. ## Changes in Boost 1.81 diff --git a/doc/system/reference.adoc b/doc/system/reference.adoc index 01b2d7d..f37b6a1 100644 --- a/doc/system/reference.adoc +++ b/doc/system/reference.adoc @@ -1517,6 +1517,19 @@ constexpr in_place_error_t in_place_error{}; template class result; template class result; +template class result; + +// operator| + +template T operator|( result const& r, U&& u ); +template T operator|( result&& r, U&& u ); + +template T operator|( result const& r, F&& f ); +template T operator|( result&& r, F&& f ); + +template R operator|( result const& r, F&& f ); +template R operator|( result&& r, F&& f ); +template R operator|( result&& r, F&& f ); } // namespace system } // namespace boost @@ -2488,6 +2501,110 @@ friend constexpr bool operator!=( result const & r1, result const & r2 ); Returns: :: `!( r1 == r2 )`. +### Chaining + +#### operator| + +``` +template T operator|( result const& r, U&& u ); +template T operator|( result&& r, U&& u ); +``` +[none] +* {blank} ++ +Returns the value in `r`, or if `r` contains an error, a default value `u`. ++ +Effects: :: + - If `r.has_value()` is `true`, returns `*r`. + - Otherwise, returns `u`. +Remarks: :: + Only enabled when `U` is convertible to `T`. +Example: :: ++ +``` +result get_server_port(); // can fail + +int get_port() +{ + return get_server_port() | 443; +} +``` + +``` +template T operator|( result const& r, F&& f ); +template T operator|( result&& r, F&& f ); +``` +[none] +* {blank} ++ +Returns the value in `r`, or if `r` contains an error, a default value obtained +by invoking the function `f`. ++ +Effects: :: + - If `r.has_value()` is `true`, returns `*r`. + - Otherwise, returns `f()`. +Remarks: :: + Only enabled when `f()` is convertible to `T`. +Example: :: ++ +``` +result get_server_port(); // can fail +int get_default_port(); + +int get_port() +{ + return get_server_port() | get_default_port; +} +``` ++ +Note that the right hand side is `get_default_port` and not `get_default_port()`. +This is important; spelled this way, the function `get_default_port` is called +only when `get_server_port_impl()` fails. If it were ++ +``` + return get_server_port() | get_default_port(); +``` ++ +the function would have been called unconditionally. ++ +Another, equivalent, way is to use a lambda ++ +``` + return get_server_port() | []{ return get_default_port(); }; +``` ++ +which isn't necessary here, but would be needed for more complex expressions. + +``` +template R operator|( result const& r, F&& f ); +template R operator|( result&& r, F&& f ); +template R operator|( result&& r, F&& f ); +``` +[none] +* {blank} ++ +Returns the value in `r`, or if `r` contains an error, another `result` obtained +by invoking the function `f`. ++ +Let `R` be the type of `f()`. ++ +Effects: :: + - If `r.has_value()` is `true`, returns `*r`. + - Otherwise, returns `f()`. +Remarks: :: + Only enabled when `R` is an instance of `result` and `T` is convertible to `R::value_type`. +Example: :: ++ +``` +result get_server_port(); // can fail +result get_default_port(); // can fail + +int get_port() +{ + return get_server_port() | get_default_port | 443; +} +``` + ## This convenience header includes all the headers previously described.