mirror of
https://github.com/boostorg/system.git
synced 2025-12-25 16:28:05 +01:00
Compare commits
27 Commits
feature/re
...
feature/is
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2aa5d4d97f | ||
|
|
18edbf75d0 | ||
|
|
52220a0351 | ||
|
|
ffa67ab005 | ||
|
|
d8399efcac | ||
|
|
8bc32b7267 | ||
|
|
d11dd4b396 | ||
|
|
ca5bca39ce | ||
|
|
a58115cb50 | ||
|
|
1bc08296de | ||
|
|
25479216b3 | ||
|
|
54d3b253b1 | ||
|
|
194b84e663 | ||
|
|
47a08cb35b | ||
|
|
7ffd63d54c | ||
|
|
92c24da9a1 | ||
|
|
dc73ca428b | ||
|
|
c1fa3619b6 | ||
|
|
0cd351014b | ||
|
|
d38e54d4c3 | ||
|
|
fa3331412d | ||
|
|
b899c49ae8 | ||
|
|
61a0e244da | ||
|
|
eb788615de | ||
|
|
84fd43e14a | ||
|
|
b0ef682e3d | ||
|
|
c360ff1b1c |
@@ -226,6 +226,20 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
"g++-12-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 23.04 GCC 13 32",
|
||||
"cppalliance/droneubuntu2304:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '32' },
|
||||
"g++-13-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 23.04 GCC 13 64",
|
||||
"cppalliance/droneubuntu2304:1",
|
||||
{ TOOLSET: 'gcc', COMPILER: 'g++-13', CXXSTD: '03,11,14,17,20,2b', ADDRMD: '64' },
|
||||
"g++-13-multilib",
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 16.04 Clang 3.5",
|
||||
"cppalliance/droneubuntu1604:1",
|
||||
@@ -283,6 +297,13 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
["deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-15 main"],
|
||||
),
|
||||
|
||||
linux_pipeline(
|
||||
"Linux 23.04 Clang 16",
|
||||
"cppalliance/droneubuntu2304:1",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++-16', CXXSTD: '11,14,17,20,2b' },
|
||||
"clang-16",
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 10.15 Xcode 12.2 UBSAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + ubsan,
|
||||
@@ -293,6 +314,18 @@ local windows_pipeline(name, image, environment, arch = "amd64") =
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '03,11,14,1z' } + asan,
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 12.4 Xcode 13.4.1 UBSAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + ubsan,
|
||||
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
|
||||
),
|
||||
|
||||
macos_pipeline(
|
||||
"MacOS 12.4 Xcode 13.4.1 ASAN",
|
||||
{ TOOLSET: 'clang', COMPILER: 'clang++', CXXSTD: '11,14,17,20,2b' } + asan,
|
||||
xcode_version = "13.4.1", osx_version = "monterey", arch = "arm64",
|
||||
),
|
||||
|
||||
windows_pipeline(
|
||||
"Windows VS2015 msvc-14.0",
|
||||
"cppalliance/dronevs2015",
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
# https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
set -ex
|
||||
export PATH=~/.local/bin:/usr/local/bin:$PATH
|
||||
|
||||
DRONE_BUILD_DIR=$(pwd)
|
||||
|
||||
|
||||
19
.github/workflows/ci.yml
vendored
19
.github/workflows/ci.yml
vendored
@@ -113,24 +113,33 @@ jobs:
|
||||
- toolset: clang
|
||||
compiler: clang++-13
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
container: ubuntu:22.04
|
||||
os: ubuntu-latest
|
||||
install: clang-13
|
||||
- toolset: clang
|
||||
compiler: clang++-14
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
container: ubuntu:22.04
|
||||
os: ubuntu-latest
|
||||
install: clang-14
|
||||
- toolset: clang
|
||||
compiler: clang++-15
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-22.04
|
||||
container: ubuntu:22.04
|
||||
os: ubuntu-latest
|
||||
install: clang-15
|
||||
- toolset: clang
|
||||
compiler: clang++-16
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
os: ubuntu-latest
|
||||
container: ubuntu:23.04
|
||||
os: ubuntu-latest
|
||||
install: clang-16
|
||||
- toolset: clang
|
||||
compiler: clang++-17
|
||||
cxxstd: "03,11,14,17,20,2b"
|
||||
container: ubuntu:23.10
|
||||
os: ubuntu-latest
|
||||
install: clang-17
|
||||
- toolset: clang
|
||||
cxxstd: "03,11,14,17,2a"
|
||||
os: macos-11
|
||||
@@ -213,7 +222,7 @@ jobs:
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: clang-win
|
||||
cxxstd: "14,17,latest"
|
||||
cxxstd: "14,17,20,latest"
|
||||
addrmd: 32,64
|
||||
os: windows-2022
|
||||
- toolset: gcc
|
||||
|
||||
@@ -8,6 +8,13 @@ https://www.boost.org/LICENSE_1_0.txt
|
||||
# Revision History
|
||||
:idprefix:
|
||||
|
||||
## Changes in Boost 1.84
|
||||
|
||||
* Added support for `result<U&, E>`.
|
||||
* Added `operator|` for `result`.
|
||||
* Added `operator&` for `result`.
|
||||
* Added `operator&=` for `result`.
|
||||
|
||||
## Changes in Boost 1.81
|
||||
|
||||
* The macro `BOOST_SYSTEM_DISABLE_THREADS` can now be defined to disable
|
||||
|
||||
@@ -1517,6 +1517,38 @@ constexpr in_place_error_t in_place_error{};
|
||||
|
||||
template<class T, class E = error_code> class result;
|
||||
template<class E> class result<void, E>;
|
||||
template<class U, class E> class result<U&, E>;
|
||||
|
||||
// operator|
|
||||
|
||||
template<class T, class E, class U> T operator|( result<T, E> const& r, U&& u );
|
||||
template<class T, class E, class U> T operator|( result<T, E>&& r, U&& u );
|
||||
|
||||
template<class T, class E, class F> T operator|( result<T, E> const& r, F&& f );
|
||||
template<class T, class E, class F> T operator|( result<T, E>&& r, F&& f );
|
||||
|
||||
template<class T, class E, class F, class R = ...> R operator|( result<T, E> const& r, F&& f );
|
||||
template<class T, class E, class F, class R = ...> R operator|( result<T, E>&& r, F&& f );
|
||||
template<class E, class F, class R = ...> R operator|( result<void, E> const& r, F&& f );
|
||||
template<class E, class F, class R = ...> R operator|( result<void, E>&& r, F&& f );
|
||||
|
||||
// operator&
|
||||
|
||||
template<class T, class E, class F, class U = ...>
|
||||
result<U, E> operator&( result<T, E> const& r, F&& f );
|
||||
template<class T, class E, class F, class U = ...>
|
||||
result<U, E> operator&( result<T, E>&& r, F&& f );
|
||||
|
||||
template<class T, class E, class F, class R = ...> R operator&( result<T, E> const& r, F&& f );
|
||||
template<class T, class E, class F, class R = ...> R operator&( result<T, E>&& r, F&& f );
|
||||
|
||||
// operator&=
|
||||
|
||||
template<class T, class E, class F, class U = ...>
|
||||
result<T, E>& operator&=( result<T, E>& r, F&& f );
|
||||
|
||||
template<class T, class E, class F, class R = ...>
|
||||
result<T, E>& operator&=( result<T, E>& r, F&& f );
|
||||
|
||||
} // namespace system
|
||||
} // namespace boost
|
||||
@@ -1713,7 +1745,7 @@ Effects: ::
|
||||
ensures that `*this` holds the error `E( std::forward<A>(a)... )`.
|
||||
- Otherwise, this constructor does not participate in overload resolution.
|
||||
Remarks: ::
|
||||
This constructor is only enabled when `sizeof...(T) > 0`.
|
||||
This constructor is only enabled when `sizeof...(A) > 0`.
|
||||
|
||||
```
|
||||
template<class... A>
|
||||
@@ -1747,7 +1779,7 @@ template<class T2, class E2>
|
||||
* {blank}
|
||||
+
|
||||
Ensures: ::
|
||||
If `r2.has_value()` is `true`, `*this` holds the value `T( *r2 )`, otherwise `*this` holds the value `E( r2.error() )`.
|
||||
If `r2.has_value()` is `true`, `*this` holds the value `T( *r2 )`, otherwise `*this` holds the error `E( r2.error() )`.
|
||||
Remarks: ::
|
||||
This constructor is only enabled when `std::is_convertible<T2, T>::value && std::is_convertible<E2, E>::value` is `true`.
|
||||
|
||||
@@ -1759,7 +1791,7 @@ template<class T2, class E2>
|
||||
* {blank}
|
||||
+
|
||||
Ensures: ::
|
||||
If `r2.has_value()` is `true`, `*this` holds the value `T( std::move( *r2 ) )`, otherwise `*this` holds the value `E( r2.error() )`.
|
||||
If `r2.has_value()` is `true`, `*this` holds the value `T( std::move( *r2 ) )`, otherwise `*this` holds the error `E( r2.error() )`.
|
||||
Remarks: ::
|
||||
This constructor is only enabled when `std::is_convertible<T2, T>::value && std::is_convertible<E2, E>::value` is `true`.
|
||||
|
||||
@@ -1961,6 +1993,9 @@ public:
|
||||
template<class... A>
|
||||
constexpr result( in_place_error_t, A&&... a );
|
||||
|
||||
template<class E2>
|
||||
constexpr result( result<void, E2> const& r2 );
|
||||
|
||||
// queries
|
||||
|
||||
constexpr bool has_value() const noexcept;
|
||||
@@ -2032,7 +2067,7 @@ Effects: ::
|
||||
ensures that `*this` holds the error `E( std::forward<A>(a)... )`.
|
||||
- Otherwise, this constructor does not participate in overload resolution.
|
||||
Remarks: ::
|
||||
This constructor is only enabled when `sizeof...(T) > 0`.
|
||||
This constructor is only enabled when `sizeof...(A) > 0`.
|
||||
|
||||
```
|
||||
template<class... A>
|
||||
@@ -2056,6 +2091,18 @@ Ensures: ::
|
||||
Remarks: ::
|
||||
This constructor is only enabled when `std::is_constructible<E, A...>::value` is `true`.
|
||||
|
||||
```
|
||||
template<class E2>
|
||||
constexpr result( result<void, E2> const& r2 );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Ensures: ::
|
||||
If `r2.has_value()` is `true`, `*this` holds an unspecified value, otherwise `*this` holds the error `E( r2.error() )`.
|
||||
Remarks: ::
|
||||
This constructor is only enabled when `std::is_convertible<E2, E>::value` is `true`.
|
||||
|
||||
#### Queries
|
||||
|
||||
```
|
||||
@@ -2201,6 +2248,533 @@ Effects: ::
|
||||
Returns: ::
|
||||
`os`.
|
||||
|
||||
### result<U&, E>
|
||||
|
||||
```
|
||||
namespace boost {
|
||||
namespace system {
|
||||
|
||||
template<class U, class E> class result<U&, E>
|
||||
{
|
||||
public:
|
||||
|
||||
using value_type = U&;
|
||||
using error_type = E;
|
||||
|
||||
static constexpr in_place_value_t in_place_value{};
|
||||
static constexpr in_place_error_t in_place_error{};
|
||||
|
||||
// constructors
|
||||
|
||||
template<class A>
|
||||
constexpr result( A&& a ) noexcept;
|
||||
|
||||
template<class... A>
|
||||
constexpr result( A&&... a );
|
||||
|
||||
template<class A>
|
||||
constexpr result( in_place_value_t, A&& a ) noexcept;
|
||||
|
||||
template<class... A>
|
||||
constexpr result( in_place_error_t, A&&... a );
|
||||
|
||||
template<class U2, class E2>
|
||||
constexpr result( result<U2&, E2> const& r2 );
|
||||
|
||||
// queries
|
||||
|
||||
constexpr bool has_value() const noexcept;
|
||||
constexpr bool has_error() const noexcept;
|
||||
constexpr explicit operator bool() const noexcept;
|
||||
|
||||
// checked value access
|
||||
|
||||
constexpr U& value( boost::source_location const & loc =
|
||||
BOOST_CURRENT_LOCATION ) const;
|
||||
|
||||
// unchecked value access
|
||||
|
||||
constexpr U* operator->() const noexcept;
|
||||
constexpr U& operator*() const noexcept;
|
||||
|
||||
// error access
|
||||
|
||||
constexpr E error() const &;
|
||||
constexpr E error() &&;
|
||||
|
||||
// emplace
|
||||
|
||||
template<class A>
|
||||
constexpr U& emplace( A&& a ) noexcept;
|
||||
|
||||
// swap
|
||||
|
||||
constexpr void swap( result& r );
|
||||
friend constexpr void swap( result & r1, result & r2 );
|
||||
|
||||
// equality
|
||||
|
||||
friend constexpr bool operator==( result const & r1, result const & r2 );
|
||||
friend constexpr bool operator!=( result const & r1, result const & r2 );
|
||||
};
|
||||
|
||||
} // namespace system
|
||||
} // namespace boost
|
||||
```
|
||||
|
||||
#### Constructors
|
||||
|
||||
```
|
||||
template<class A>
|
||||
constexpr result( A&& a ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Ensures: ::
|
||||
`*this` holds the reference `static_cast<U&>( std::forward<A>(a) )`.
|
||||
Remarks: ::
|
||||
This constructor is only enabled when `A` is `B&` and `std::is_convertible<B*, U*>::value` is `true`.
|
||||
|
||||
```
|
||||
template<class... A>
|
||||
constexpr result( A&&... a );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects: ::
|
||||
- If `std::is_constructible<E, A...>::value && !std::is_constructible<U&, A...>::value`,
|
||||
ensures that `*this` holds the error `E( std::forward<A>(a)... )`.
|
||||
- Otherwise, this constructor does not participate in overload resolution.
|
||||
Remarks: ::
|
||||
This constructor is only enabled when `sizeof...(A) > 0`.
|
||||
|
||||
```
|
||||
template<class A>
|
||||
constexpr result( in_place_value_t, A&& a ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Ensures: ::
|
||||
`*this` holds the reference `static_cast<U&>( std::forward<A>(a) )`.
|
||||
Remarks: ::
|
||||
This constructor is only enabled when `A` is `B&` and `std::is_convertible<B*, U*>::value` is `true`.
|
||||
|
||||
```
|
||||
template<class... A>
|
||||
constexpr result( in_place_error_t, A&&... a );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Ensures: ::
|
||||
`*this` holds the error `E( std::forward<A>(a)... )`.
|
||||
Remarks: ::
|
||||
This constructor is only enabled when `std::is_constructible<E, A...>::value` is `true`.
|
||||
|
||||
```
|
||||
template<class U2, class E2>
|
||||
constexpr result( result<U2&, E2> const& r2 );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Ensures: ::
|
||||
If `r2.has_value()` is `true`, `*this` holds the reference `static_cast<U&>( *r2 )`, otherwise `*this` holds the error `E( r2.error() )`.
|
||||
Remarks: ::
|
||||
This constructor is only enabled when `std::is_convertible<U2*, U*>::value && std::is_convertible<E2, E>::value` is `true`.
|
||||
|
||||
#### Queries
|
||||
|
||||
```
|
||||
constexpr bool has_value() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns: ::
|
||||
`true` when `*this` holds a value, `false` otherwise.
|
||||
|
||||
```
|
||||
constexpr bool has_error() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns: ::
|
||||
`!has_value()`.
|
||||
|
||||
```
|
||||
constexpr explicit operator bool() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns: ::
|
||||
`has_value()`.
|
||||
|
||||
#### Checked Value Access
|
||||
|
||||
```
|
||||
constexpr U& value(
|
||||
boost::source_location const & loc = BOOST_CURRENT_LOCATION ) const;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects: ::
|
||||
If `*this` holds a reference, returns it. Otherwise,
|
||||
calls `throw_exception_from_error`, passing it a reference to
|
||||
the held error, and `loc`.
|
||||
|
||||
#### Unchecked Value Access
|
||||
|
||||
```
|
||||
constexpr U* operator->() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns: ::
|
||||
If `*this` holds a reference, a pointer to its referent. Otherwise, `nullptr`.
|
||||
|
||||
```
|
||||
constexpr U& operator*() const noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Requires: :: `*this` holds a reference.
|
||||
Returns: ::
|
||||
`*operator\->()`.
|
||||
|
||||
#### Error Access
|
||||
|
||||
```
|
||||
constexpr E error() const &;
|
||||
constexpr E error() &&;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects: ::
|
||||
If `*this` holds an error, returns it. Otherwise, returns `E()`.
|
||||
|
||||
#### emplace
|
||||
|
||||
```
|
||||
template<class A>
|
||||
constexpr U& emplace( A&& a ) noexcept;
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Ensures: ::
|
||||
`*this` holds the reference `static_cast<U&>( std::forward<A>(a)... )`.
|
||||
Returns: ::
|
||||
The contained reference.
|
||||
Remarks: ::
|
||||
This function is only enabled when `A` is `B&` and `std::is_convertible<B*, U*>::value` is `true`.
|
||||
|
||||
#### swap
|
||||
|
||||
```
|
||||
constexpr void swap( result& r );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects: ::
|
||||
Exchanges the contents of `*this` and `r`.
|
||||
|
||||
```
|
||||
friend constexpr void swap( result & r1, result & r2 );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects: ::
|
||||
Exchanges the contents of `r1` and `r2`.
|
||||
|
||||
#### Equality
|
||||
|
||||
```
|
||||
friend constexpr bool operator==( result const & r1, result const & r2 );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Effects: ::
|
||||
- If `r1` holds a reference `t1` and `r2` holds a reference `t2`, returns `t1 == t2`.
|
||||
- If `r1` holds an error `e1` and `r2` holds an error `e2`, returns `e1 == e2`.
|
||||
- Otherwise, returns `false`.
|
||||
|
||||
```
|
||||
friend constexpr bool operator!=( result const & r1, result const & r2 );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns: ::
|
||||
`!( r1 == r2 )`.
|
||||
|
||||
### Chaining
|
||||
|
||||
#### operator|
|
||||
|
||||
```
|
||||
template<class T, class E, class U> T operator|( result<T, E> const& r, U&& u );
|
||||
template<class T, class E, class U> T operator|( result<T, E>&& 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<int> get_server_port(); // can fail
|
||||
|
||||
int get_port()
|
||||
{
|
||||
return get_server_port() | 443;
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
template<class T, class E, class F> T operator|( result<T, E> const& r, F&& f );
|
||||
template<class T, class E, class F> T operator|( result<T, E>&& 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<int> 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<class T, class E, class F, class R = ...> R operator|( result<T, E> const& r, F&& f );
|
||||
template<class T, class E, class F, class R = ...> R operator|( result<T, E>&& r, F&& f );
|
||||
template<class E, class F, class R = ...> R operator|( result<void, E> const& r, F&& f );
|
||||
template<class E, class F, class R = ...> R operator|( result<void, E>&& 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<int> get_server_port(); // can fail
|
||||
result<int> get_default_port(); // can fail
|
||||
|
||||
int get_port()
|
||||
{
|
||||
return get_server_port() | get_default_port | 443;
|
||||
}
|
||||
```
|
||||
|
||||
#### operator&
|
||||
|
||||
```
|
||||
template<class T, class E, class F, class U = ...>
|
||||
result<U, E> operator&( result<T, E> const& r, F&& f );
|
||||
|
||||
template<class T, class E, class F, class U = ...>
|
||||
result<U, E> operator&( result<T, E>&& r, F&& f );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns the error in `r`, or if `r` contains a value, transforms the value by calling `f` on it.
|
||||
+
|
||||
Let `U` be the type of `f(*r)`.
|
||||
+
|
||||
Effects: ::
|
||||
- If `r.has_value()` is `true`, returns `f(*r)`.
|
||||
- Otherwise, returns `r.error()`.
|
||||
Remarks: ::
|
||||
Only enabled when `U` is not an instance of `result`.
|
||||
Example: ::
|
||||
+
|
||||
```
|
||||
struct currency_type
|
||||
{
|
||||
char code_[ 4 ] = {};
|
||||
};
|
||||
|
||||
result<double> get_exchange_rate( currency_type from, currency_type to );
|
||||
|
||||
result<double> convert( double amount, currency_type from, currency_type to )
|
||||
{
|
||||
return get_exchange_rate( from, to ) & [&](double rate){ return rate * amount; };
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
template<class T, class E, class F, class R = ...> R operator&( result<T, E> const& r, F&& f );
|
||||
template<class T, class E, class F, class R = ...> R operator&( result<T, E>&& r, F&& f );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
Returns the error in `r`, or if `r` contains a value, another `result` obtained
|
||||
by invoking the function `f` on the value in `r`.
|
||||
+
|
||||
Let `R` be the type of `f(*r)`.
|
||||
+
|
||||
Effects: ::
|
||||
- If `r.has_value()` is `true`, returns `f(*r)`.
|
||||
- Otherwise, returns `r.error()`.
|
||||
Remarks: ::
|
||||
Only enabled when `R` is an instance of `result` and `E` is convertible to `R::error_type`.
|
||||
Example: ::
|
||||
+
|
||||
```
|
||||
struct JsonValue
|
||||
{
|
||||
result<JsonValue const&> at( std::size_t i ) const noexcept;
|
||||
result<JsonValue const&> at( std::string_view key ) const noexcept;
|
||||
template<class T> result<T> to_number() const noexcept;
|
||||
};
|
||||
|
||||
namespace helpers
|
||||
{
|
||||
|
||||
inline auto at( std::size_t i ) {
|
||||
return [=](JsonValue const& jv){ return jv.at( i ); }; }
|
||||
|
||||
inline auto at( std::string_view key ) {
|
||||
return [=](JsonValue const& jv){ return jv.at( key ); }; }
|
||||
|
||||
template<class T> inline auto to_number() {
|
||||
return [](JsonValue const& jv){ return jv.to_number<T>(); }; }
|
||||
|
||||
} // namespace helpers
|
||||
|
||||
int get_port( JsonValue const& config, int def )
|
||||
{
|
||||
using namespace helpers;
|
||||
return config.at( "servers" ) & at( 0 ) & at( "port" ) & to_number<int>() | def;
|
||||
}
|
||||
```
|
||||
|
||||
#### operator&=
|
||||
|
||||
```
|
||||
template<class T, class E, class F, class U = ...>
|
||||
result<T, E>& operator&=( result<T, E>& r, F&& f );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
If `r` contains a value, replaces it with the result of invoking the function `f` on the value in `r`.
|
||||
+
|
||||
Let `U` be the type of `f(*r)`.
|
||||
+
|
||||
Effects: :: If `r.has_value()` is `true`, assigns `f(*std::move(r))` to `r`.
|
||||
Returns: :: `r`.
|
||||
Remarks: ::
|
||||
Only enabled when `U` is not an instance of `result` and is convertible to `T`.
|
||||
|
||||
```
|
||||
template<class T, class E, class F, class R = ...>
|
||||
result<T, E>& operator&=( result<T, E>& r, F&& f );
|
||||
```
|
||||
[none]
|
||||
* {blank}
|
||||
+
|
||||
If `r` contains a value, replaces `r` with the result of invoking the function `f` on the value in `r`.
|
||||
+
|
||||
Let `R` be the type of `f(*r)`.
|
||||
+
|
||||
Effects: :: If `r.has_value()` is `true`, assigns `f(*std::move(r))` to `r`.
|
||||
Returns: :: `r`.
|
||||
Remarks: ::
|
||||
Only enabled when `R` is an instance of `result` and is convertible to `result<T, E>`.
|
||||
Example: ::
|
||||
+
|
||||
```
|
||||
struct JsonValue
|
||||
{
|
||||
result<JsonValue const&> at( std::string_view key ) const noexcept;
|
||||
};
|
||||
|
||||
namespace helpers
|
||||
{
|
||||
|
||||
inline auto at( std::string_view key ) {
|
||||
return [=](JsonValue const& jv){ return jv.at( key ); }; }
|
||||
|
||||
} // namespace helpers
|
||||
|
||||
result<JsonValue const&> at_path( JsonValue const& jv,
|
||||
std::initializer_list<std::string_view> path )
|
||||
{
|
||||
result<JsonValue const&> r( jv );
|
||||
|
||||
using namespace helpers;
|
||||
|
||||
for( auto key: path )
|
||||
{
|
||||
r &= at( key );
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
```
|
||||
|
||||
## <boost/system.hpp>
|
||||
|
||||
This convenience header includes all the headers previously described.
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || \
|
||||
defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR)
|
||||
|
||||
BOOST_PRAGMA_MESSAGE("C++03 support was deprecated in Boost.System 1.82 and will be removed in Boost.System 1.84. Please open an issue in https://github.com/boostorg/system if you want it retained.")
|
||||
BOOST_PRAGMA_MESSAGE("C++03 support was deprecated in Boost.System 1.82 and will be removed in Boost.System 1.85.")
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -450,6 +450,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
|
||||
|
||||
template<class T, class E> constexpr in_place_value_t result<T, E>::in_place_value;
|
||||
template<class T, class E> constexpr in_place_error_t result<T, E>::in_place_error;
|
||||
|
||||
#endif
|
||||
|
||||
template<class Ch, class Tr, class T, class E> std::basic_ostream<Ch, Tr>& operator<<( std::basic_ostream<Ch, Tr>& os, result<T, E> const & r )
|
||||
{
|
||||
if( r.has_value() )
|
||||
@@ -538,6 +545,23 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
// converting
|
||||
template<class E2, class En = typename std::enable_if<
|
||||
std::is_convertible<E2, E>::value
|
||||
>::type>
|
||||
BOOST_CXX14_CONSTEXPR result( result<void, E2> const& r2 )
|
||||
noexcept(
|
||||
std::is_nothrow_constructible<E, E2>::value &&
|
||||
std::is_nothrow_default_constructible<E2>::value &&
|
||||
std::is_nothrow_copy_constructible<E2>::value )
|
||||
: v_( in_place_error, r2.error() )
|
||||
{
|
||||
if( r2 )
|
||||
{
|
||||
this->emplace();
|
||||
}
|
||||
}
|
||||
|
||||
// queries
|
||||
|
||||
constexpr bool has_value() const noexcept
|
||||
@@ -635,6 +659,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
|
||||
|
||||
template<class E> constexpr in_place_value_t result<void, E>::in_place_value;
|
||||
template<class E> constexpr in_place_error_t result<void, E>::in_place_error;
|
||||
|
||||
#endif
|
||||
|
||||
template<class Ch, class Tr, class E> std::basic_ostream<Ch, Tr>& operator<<( std::basic_ostream<Ch, Tr>& os, result<void, E> const & r )
|
||||
{
|
||||
if( r.has_value() )
|
||||
@@ -727,7 +758,8 @@ public:
|
||||
|
||||
// tagged, value
|
||||
template<class A, class En = typename std::enable_if<
|
||||
std::is_constructible<U&, A>::value
|
||||
std::is_constructible<U&, A>::value &&
|
||||
!detail::reference_to_temporary<U, A>::value
|
||||
>::type>
|
||||
constexpr result( in_place_value_t, A&& a )
|
||||
noexcept( std::is_nothrow_constructible<U&, A>::value )
|
||||
@@ -867,6 +899,283 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
|
||||
|
||||
template<class U, class E> constexpr in_place_value_t result<U&, E>::in_place_value;
|
||||
template<class U, class E> constexpr in_place_error_t result<U&, E>::in_place_error;
|
||||
|
||||
#endif
|
||||
|
||||
// operator|
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// is_value_convertible_to
|
||||
|
||||
template<class T, class U> struct is_value_convertible_to: std::is_convertible<T, U>
|
||||
{
|
||||
};
|
||||
|
||||
template<class T, class U> struct is_value_convertible_to<T, U&>:
|
||||
std::integral_constant<bool,
|
||||
std::is_lvalue_reference<T>::value &&
|
||||
std::is_convertible<typename std::remove_reference<T>::type*, U*>::value>
|
||||
{
|
||||
};
|
||||
|
||||
// is_result
|
||||
|
||||
template<class T> struct is_result: std::false_type {};
|
||||
template<class T, class E> struct is_result< result<T, E> >: std::true_type {};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// result | value
|
||||
|
||||
template<class T, class E, class U,
|
||||
class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
|
||||
>
|
||||
T operator|( result<T, E> const& r, U&& u )
|
||||
{
|
||||
if( r )
|
||||
{
|
||||
return *r;
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<U>( u );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class E, class U,
|
||||
class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
|
||||
>
|
||||
T operator|( result<T, E>&& r, U&& u )
|
||||
{
|
||||
if( r )
|
||||
{
|
||||
return *std::move( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<U>( u );
|
||||
}
|
||||
}
|
||||
|
||||
// result | nullary-returning-value
|
||||
|
||||
template<class T, class E, class F,
|
||||
class U = decltype( std::declval<F>()() ),
|
||||
class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
|
||||
>
|
||||
T operator|( result<T, E> const& r, F&& f )
|
||||
{
|
||||
if( r )
|
||||
{
|
||||
return *r;
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<F>( f )();
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class E, class F,
|
||||
class U = decltype( std::declval<F>()() ),
|
||||
class En = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
|
||||
>
|
||||
T operator|( result<T, E>&& r, F&& f )
|
||||
{
|
||||
if( r )
|
||||
{
|
||||
return *std::move( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<F>( f )();
|
||||
}
|
||||
}
|
||||
|
||||
// result | nullary-returning-result
|
||||
|
||||
template<class T, class E, class F,
|
||||
class U = decltype( std::declval<F>()() ),
|
||||
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
|
||||
class En2 = typename std::enable_if<detail::is_value_convertible_to<T, typename U::value_type>::value>::type
|
||||
>
|
||||
U operator|( result<T, E> const& r, F&& f )
|
||||
{
|
||||
if( r )
|
||||
{
|
||||
return *r;
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<F>( f )();
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class E, class F,
|
||||
class U = decltype( std::declval<F>()() ),
|
||||
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
|
||||
class En2 = typename std::enable_if<detail::is_value_convertible_to<T, typename U::value_type>::value>::type
|
||||
>
|
||||
U operator|( result<T, E>&& r, F&& f )
|
||||
{
|
||||
if( r )
|
||||
{
|
||||
return *std::move( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<F>( f )();
|
||||
}
|
||||
}
|
||||
|
||||
template<class E, class F,
|
||||
class U = decltype( std::declval<F>()() ),
|
||||
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
|
||||
class En2 = typename std::enable_if<std::is_void<typename U::value_type>::value>::type
|
||||
>
|
||||
U operator|( result<void, E> const& r, F&& f )
|
||||
{
|
||||
if( r )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<F>( f )();
|
||||
}
|
||||
}
|
||||
|
||||
template<class E, class F,
|
||||
class U = decltype( std::declval<F>()() ),
|
||||
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
|
||||
class En2 = typename std::enable_if<std::is_void<typename U::value_type>::value>::type
|
||||
>
|
||||
U operator|( result<void, E>&& r, F&& f )
|
||||
{
|
||||
if( r )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<F>( f )();
|
||||
}
|
||||
}
|
||||
|
||||
// operator&
|
||||
|
||||
// result & unary-returning-value
|
||||
|
||||
template<class T, class E, class F,
|
||||
class U = decltype( std::declval<F>()( std::declval<T const&>() ) ),
|
||||
class En = typename std::enable_if<!detail::is_result<U>::value>::type
|
||||
>
|
||||
result<U, E> operator&( result<T, E> const& r, F&& f )
|
||||
{
|
||||
if( r.has_error() )
|
||||
{
|
||||
return r.error();
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<F>( f )( *r );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class E, class F,
|
||||
class U = decltype( std::declval<F>()( std::declval<T>() ) ),
|
||||
class En = typename std::enable_if<!detail::is_result<U>::value>::type
|
||||
>
|
||||
result<U, E> operator&( result<T, E>&& r, F&& f )
|
||||
{
|
||||
if( r.has_error() )
|
||||
{
|
||||
return r.error();
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<F>( f )( *std::move( r ) );
|
||||
}
|
||||
}
|
||||
|
||||
// result & unary-returning-result
|
||||
|
||||
template<class T, class E, class F,
|
||||
class U = decltype( std::declval<F>()( std::declval<T const&>() ) ),
|
||||
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
|
||||
class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type
|
||||
>
|
||||
U operator&( result<T, E> const& r, F&& f )
|
||||
{
|
||||
if( r.has_error() )
|
||||
{
|
||||
return r.error();
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<F>( f )( *r );
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class E, class F,
|
||||
class U = decltype( std::declval<F>()( std::declval<T>() ) ),
|
||||
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
|
||||
class En2 = typename std::enable_if<std::is_convertible<E, typename U::error_type>::value>::type
|
||||
>
|
||||
U operator&( result<T, E>&& r, F&& f )
|
||||
{
|
||||
if( r.has_error() )
|
||||
{
|
||||
return r.error();
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::forward<F>( f )( *std::move( r ) );
|
||||
}
|
||||
}
|
||||
|
||||
// operator&=
|
||||
|
||||
// result &= unary-returning-value
|
||||
|
||||
template<class T, class E, class F,
|
||||
class U = decltype( std::declval<F>()( std::declval<T>() ) ),
|
||||
class En1 = typename std::enable_if<!detail::is_result<U>::value>::type,
|
||||
class En2 = typename std::enable_if<detail::is_value_convertible_to<U, T>::value>::type
|
||||
>
|
||||
result<T, E>& operator&=( result<T, E>& r, F&& f )
|
||||
{
|
||||
if( r )
|
||||
{
|
||||
r = std::forward<F>( f )( *std::move( r ) );
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
// result &= unary-returning-result
|
||||
|
||||
template<class T, class E, class F,
|
||||
class U = decltype( std::declval<F>()( std::declval<T>() ) ),
|
||||
class En1 = typename std::enable_if<detail::is_result<U>::value>::type,
|
||||
class En2 = typename std::enable_if<detail::is_value_convertible_to<typename U::value_type, T>::value>::type,
|
||||
class En3 = typename std::enable_if<std::is_convertible<typename U::error_type, E>::value>::type
|
||||
>
|
||||
result<T, E>& operator&=( result<T, E>& r, F&& f )
|
||||
{
|
||||
if( r )
|
||||
{
|
||||
r = std::forward<F>( f )( *std::move( r ) );
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
} // namespace system
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -167,3 +167,13 @@ boost_test(TYPE run SOURCES result_error_move.cpp)
|
||||
boost_test(TYPE run SOURCES result_value_construct6.cpp)
|
||||
boost_test(TYPE run SOURCES result_value_construct7.cpp)
|
||||
boost_test(TYPE run SOURCES result_error_construct5.cpp)
|
||||
boost_test(TYPE run SOURCES result_or_value.cpp)
|
||||
boost_test(TYPE compile-fail SOURCES result_or_value_fail.cpp)
|
||||
boost_test(TYPE compile-fail SOURCES result_or_value_fail2.cpp)
|
||||
boost_test(TYPE run SOURCES result_or_fn0v.cpp)
|
||||
boost_test(TYPE run SOURCES result_or_fn0r.cpp)
|
||||
boost_test(TYPE run SOURCES result_and_fn1v.cpp)
|
||||
boost_test(TYPE run SOURCES result_and_fn1r.cpp)
|
||||
boost_test(TYPE run SOURCES result_and_eq_fn1v.cpp)
|
||||
boost_test(TYPE run SOURCES result_and_eq_fn1r.cpp)
|
||||
boost_test(TYPE run SOURCES result_in_place_use.cpp)
|
||||
|
||||
@@ -197,3 +197,13 @@ run result_error_move.cpp : : : $(CPP11) ;
|
||||
run result_value_construct6.cpp : : : $(CPP11) ;
|
||||
run result_value_construct7.cpp : : : $(CPP11) ;
|
||||
run result_error_construct5.cpp : : : $(CPP11) ;
|
||||
run result_or_value.cpp : : : $(CPP11) ;
|
||||
compile-fail result_or_value_fail.cpp : $(CPP11) ;
|
||||
compile-fail result_or_value_fail2.cpp : $(CPP11) ;
|
||||
run result_or_fn0v.cpp : : : $(CPP11) ;
|
||||
run result_or_fn0r.cpp : : : $(CPP11) ;
|
||||
run result_and_fn1v.cpp : : : $(CPP11) ;
|
||||
run result_and_fn1r.cpp : : : $(CPP11) ;
|
||||
run result_and_eq_fn1v.cpp : : : $(CPP11) ;
|
||||
run result_and_eq_fn1r.cpp : : : $(CPP11) ;
|
||||
run result_in_place_use.cpp : : : $(CPP11) ;
|
||||
|
||||
126
test/result_and_eq_fn1r.cpp
Normal file
126
test/result_and_eq_fn1r.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright 2017, 2021, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
struct X
|
||||
{
|
||||
int v_;
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int v_;
|
||||
|
||||
explicit Y( int v ): v_( v ) {}
|
||||
Y( X x ): v_( x.v_) {}
|
||||
|
||||
Y( Y const& ) = delete;
|
||||
Y& operator=( Y const& ) = delete;
|
||||
|
||||
Y( Y&& r ): v_( r.v_ )
|
||||
{
|
||||
r.v_ = 0;
|
||||
}
|
||||
|
||||
Y& operator=( Y&& r )
|
||||
{
|
||||
if( &r != this )
|
||||
{
|
||||
v_ = r.v_;
|
||||
r.v_ = 0;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct E
|
||||
{
|
||||
};
|
||||
|
||||
struct E2
|
||||
{
|
||||
E2() {}
|
||||
E2( E ) {}
|
||||
};
|
||||
|
||||
result<int, E> fi( int x )
|
||||
{
|
||||
return 2 * x + 1;
|
||||
}
|
||||
|
||||
result<int, E2> fi2( int )
|
||||
{
|
||||
return E2();
|
||||
}
|
||||
|
||||
result<X, E> fy( Y y )
|
||||
{
|
||||
return X{ 2 * y.v_ + 1 };
|
||||
}
|
||||
|
||||
result<Y, E2> fy2( Y )
|
||||
{
|
||||
return E2();
|
||||
}
|
||||
|
||||
result<int&, E> fri( int& )
|
||||
{
|
||||
static int x = 2;
|
||||
return x;
|
||||
}
|
||||
|
||||
result<int&, E2> fri2( int& )
|
||||
{
|
||||
return E2();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
result<int, E2> r( 1 );
|
||||
|
||||
r &= fi;
|
||||
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 3 );
|
||||
|
||||
r &= fi2;
|
||||
BOOST_TEST( r.has_error() );
|
||||
|
||||
r &= fi;
|
||||
BOOST_TEST( r.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<Y, E2> r( in_place_value, 1 );
|
||||
|
||||
r &= fy;
|
||||
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 3 );
|
||||
|
||||
r &= fy2;
|
||||
BOOST_TEST( r.has_error() );
|
||||
|
||||
r &= fy;
|
||||
BOOST_TEST( r.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
result<int&, E2> r( x1 );
|
||||
|
||||
r &= fri;
|
||||
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &*fri( x1 ) );
|
||||
|
||||
r &= fri2;
|
||||
BOOST_TEST( r.has_error() );
|
||||
|
||||
r &= fri;
|
||||
BOOST_TEST( r.has_error() );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
114
test/result_and_eq_fn1v.cpp
Normal file
114
test/result_and_eq_fn1v.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
// Copyright 2017, 2021, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
struct X
|
||||
{
|
||||
int v_;
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int v_;
|
||||
|
||||
explicit Y( int v ): v_( v ) {}
|
||||
Y( X x ): v_( x.v_) {}
|
||||
|
||||
Y( Y const& ) = delete;
|
||||
Y& operator=( Y const& ) = delete;
|
||||
|
||||
Y( Y&& r ): v_( r.v_ )
|
||||
{
|
||||
r.v_ = 0;
|
||||
}
|
||||
|
||||
Y& operator=( Y&& r )
|
||||
{
|
||||
if( &r != this )
|
||||
{
|
||||
v_ = r.v_;
|
||||
r.v_ = 0;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct E
|
||||
{
|
||||
};
|
||||
|
||||
int f( int x )
|
||||
{
|
||||
return x * 2 + 1;
|
||||
}
|
||||
|
||||
X g( Y y )
|
||||
{
|
||||
return X{ y.v_ * 2 + 1 };
|
||||
}
|
||||
|
||||
int& h( int& )
|
||||
{
|
||||
static int x = 2;
|
||||
return x;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
result<int> r( 1 );
|
||||
|
||||
r &= f;
|
||||
|
||||
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( *r, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E> r( in_place_error );
|
||||
|
||||
r &= f;
|
||||
|
||||
BOOST_TEST( r.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<Y> r( in_place_value, 1 );
|
||||
|
||||
r &= g;
|
||||
|
||||
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( r->v_, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<Y, E> r( in_place_error );
|
||||
|
||||
r &= g;
|
||||
|
||||
BOOST_TEST( r.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
result<int&> r( x1 );
|
||||
|
||||
r &= h;
|
||||
|
||||
BOOST_TEST( r.has_value() ) && BOOST_TEST_EQ( &*r, &h( x1 ) );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E> r( in_place_error );
|
||||
|
||||
r &= h;
|
||||
|
||||
BOOST_TEST( r.has_error() );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
347
test/result_and_fn1r.cpp
Normal file
347
test/result_and_fn1r.cpp
Normal file
@@ -0,0 +1,347 @@
|
||||
// Copyright 2017, 2021, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
struct X
|
||||
{
|
||||
int v_;
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int v_;
|
||||
|
||||
explicit Y( int v ): v_( v ) {}
|
||||
Y( X x ): v_( x.v_) {}
|
||||
|
||||
Y( Y const& ) = delete;
|
||||
Y& operator=( Y const& ) = delete;
|
||||
|
||||
Y( Y&& r ): v_( r.v_ )
|
||||
{
|
||||
r.v_ = 0;
|
||||
}
|
||||
|
||||
Y& operator=( Y&& ) = delete;
|
||||
};
|
||||
|
||||
struct E
|
||||
{
|
||||
};
|
||||
|
||||
struct E2
|
||||
{
|
||||
E2() {}
|
||||
E2( E ) {}
|
||||
};
|
||||
|
||||
result<int, E2> fi( int x )
|
||||
{
|
||||
return 2 * x + 1;
|
||||
}
|
||||
|
||||
result<int, E2> fi2( int )
|
||||
{
|
||||
return E2();
|
||||
}
|
||||
|
||||
result<void, E2> fi3( int )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
result<X, E2> fy( Y y )
|
||||
{
|
||||
return X{ 2 * y.v_ + 1 };
|
||||
}
|
||||
|
||||
result<X, E2> fy2( Y )
|
||||
{
|
||||
return E2();
|
||||
}
|
||||
|
||||
result<void, E2> fy3( Y )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
result<int, E2> fri( int& x )
|
||||
{
|
||||
return x * 2 + 1;
|
||||
}
|
||||
|
||||
result<int&, E2> fri2( int& )
|
||||
{
|
||||
return E2();
|
||||
}
|
||||
|
||||
result<void, E2> fri3( int& )
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
result<int, E> r( 1 );
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fi;
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fi2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = r & fi3;
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E> const r( 1 );
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fi;
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fi2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = r & fi3;
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E2> r2 = result<int, E>( 1 ) & fi;
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E2> r2 = result<int, E>( 1 ) & fi2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = result<int, E>( 1 ) & fi3;
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E> r( in_place_error );
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fi;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fi2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = r & fi3;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E> const r( in_place_error );
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fi;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fi2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = r & fi3;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E2> r2 = result<int, E>( in_place_error ) & fi;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E2> r2 = result<int, E>( in_place_error ) & fi2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = result<int, E>( in_place_error ) & fi3;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<X, E2> r2 = result<Y, E>( in_place_value, 1 ) & fy;
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2->v_, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<X, E2> r2 = result<Y, E>( in_place_value, 1 ) & fy2;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = result<Y, E>( in_place_value, 1 ) & fy3;
|
||||
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
|
||||
{
|
||||
result<X, E2> r2 = result<Y, E>( in_place_error ) & fy;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<X, E2> r2 = result<Y, E>( in_place_error ) & fy2;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = result<Y, E>( in_place_error ) & fy3;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
result<int&, E> r( x1 );
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fri;
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E2> r2 = r & fri2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = r & fri3;
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
result<int&, E> const r( x1 );
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fri;
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E2> r2 = r & fri2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = r & fri3;
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
|
||||
result<int, E2> r2 = result<int&, E>( x1 ) & fri;
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
|
||||
result<int&, E2> r2 = result<int&, E>( x1 ) & fri2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
|
||||
result<void, E2> r2 = result<int&, E>( x1 ) & fri3;
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E> r( in_place_error );
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fri;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E2> r2 = r & fri2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = r & fri3;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E> const r( in_place_error );
|
||||
|
||||
{
|
||||
result<int, E2> r2 = r & fri;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E2> r2 = r & fri2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = r & fri3;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E2> r2 = result<int&, E>( in_place_error ) & fri;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E2> r2 = result<int&, E>( in_place_error ) & fri2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E2> r2 = result<int&, E>( in_place_error ) & fri3;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
158
test/result_and_fn1v.cpp
Normal file
158
test/result_and_fn1v.cpp
Normal file
@@ -0,0 +1,158 @@
|
||||
// Copyright 2017, 2021, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
struct X
|
||||
{
|
||||
int v_;
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int v_;
|
||||
|
||||
explicit Y( int v ): v_( v ) {}
|
||||
Y( X x ): v_( x.v_) {}
|
||||
|
||||
Y( Y const& ) = delete;
|
||||
Y& operator=( Y const& ) = delete;
|
||||
|
||||
Y( Y&& r ): v_( r.v_ )
|
||||
{
|
||||
r.v_ = 0;
|
||||
}
|
||||
|
||||
Y& operator=( Y&& ) = delete;
|
||||
};
|
||||
|
||||
struct E
|
||||
{
|
||||
};
|
||||
|
||||
int f( int x )
|
||||
{
|
||||
return x * 2 + 1;
|
||||
}
|
||||
|
||||
X g( Y y )
|
||||
{
|
||||
return X{ y.v_ * 2 + 1 };
|
||||
}
|
||||
|
||||
int& h( int& )
|
||||
{
|
||||
static int x = 2;
|
||||
return x;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
result<int> r( 1 );
|
||||
result<int> r2 = r & f;
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> const r( 1 );
|
||||
result<int> r2 = r & f;
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> r2 = result<int>( 1 ) & f;
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( *r2, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E> r( in_place_error );
|
||||
result<int, E> r2 = r & f;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E> const r( in_place_error );
|
||||
result<int, E> r2 = r & f;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E> r2 = result<int, E>( in_place_error ) & f;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<X> r2 = result<Y>( in_place_value, 1 ) & g;
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( r2->v_, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<X, E> r2 = result<Y, E>( in_place_error ) & g;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
|
||||
result<int&> r( x1 );
|
||||
|
||||
result<int&> r2 = r & h;
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( &*r2, &h( x1 ) );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
|
||||
result<int&> const r( x1 );
|
||||
|
||||
result<int&> r2 = r & h;
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( &*r2, &h( x1 ) );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
|
||||
result<int&> r2 = result<int&>( x1 ) & h;
|
||||
|
||||
BOOST_TEST( r2.has_value() ) && BOOST_TEST_EQ( &*r2, &h( x1 ) );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E> r( in_place_error );
|
||||
|
||||
result<int&, E> r2 = r & h;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E> const r( in_place_error );
|
||||
|
||||
result<int&, E> r2 = r & h;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E> r2 = result<int&, E>( in_place_error ) & h;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
@@ -183,6 +183,67 @@ int main()
|
||||
|
||||
//
|
||||
|
||||
{
|
||||
result<void, int> r;
|
||||
result<void, X> r2 = r;
|
||||
|
||||
BOOST_TEST( r2 );
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
result<void, int> const r;
|
||||
result<void, X> r2 = r;
|
||||
|
||||
BOOST_TEST( r2 );
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
result<void, X> r2 = result<void, int>();
|
||||
|
||||
BOOST_TEST( r2 );
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
result<void, int> r( 5 );
|
||||
result<void, X> r2 = r;
|
||||
|
||||
BOOST_TEST( !r2 );
|
||||
BOOST_TEST_EQ( r2.error(), X(5) );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
{
|
||||
result<void, int> const r( 6 );
|
||||
result<void, X> r2 = r;
|
||||
|
||||
BOOST_TEST( !r2 );
|
||||
BOOST_TEST_EQ( r2.error(), X(6) );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, X> r2 = result<void, int>( 7 );
|
||||
|
||||
BOOST_TEST( !r2 );
|
||||
BOOST_TEST_EQ( r2.error(), X(7) );
|
||||
BOOST_TEST_EQ( X::instances, 1 );
|
||||
}
|
||||
|
||||
BOOST_TEST_EQ( X::instances, 0 );
|
||||
|
||||
//
|
||||
|
||||
{
|
||||
int x = 5;
|
||||
|
||||
@@ -225,6 +286,9 @@ int main()
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<int, void*>, result<int, int>>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<int, int>, result<int, void*>>));
|
||||
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_constructible<result<void, void*>, result<void, int>>));
|
||||
BOOST_TEST_TRAIT_FALSE((std::is_convertible<result<void, int>, result<void, void*>>));
|
||||
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_constructible<result<int const&>, result<int&>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_convertible<result<int&>, result<int const&>>));
|
||||
|
||||
|
||||
@@ -28,6 +28,24 @@ int main()
|
||||
BOOST_TEST_EQ( r.value(), 0 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> r{};
|
||||
|
||||
BOOST_TEST( r.has_value() );
|
||||
BOOST_TEST( !r.has_error() );
|
||||
|
||||
BOOST_TEST_EQ( r.value(), 0 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> r = {};
|
||||
|
||||
BOOST_TEST( r.has_value() );
|
||||
BOOST_TEST( !r.has_error() );
|
||||
|
||||
BOOST_TEST_EQ( r.value(), 0 );
|
||||
}
|
||||
|
||||
{
|
||||
result<X> r;
|
||||
|
||||
@@ -35,6 +53,20 @@ int main()
|
||||
BOOST_TEST( !r.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<X> r{};
|
||||
|
||||
BOOST_TEST( r.has_value() );
|
||||
BOOST_TEST( !r.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<X> r = {};
|
||||
|
||||
BOOST_TEST( r.has_value() );
|
||||
BOOST_TEST( !r.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void> r;
|
||||
|
||||
@@ -42,6 +74,20 @@ int main()
|
||||
BOOST_TEST( !r.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void> r{};
|
||||
|
||||
BOOST_TEST( r.has_value() );
|
||||
BOOST_TEST( !r.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void> r = {};
|
||||
|
||||
BOOST_TEST( r.has_value() );
|
||||
BOOST_TEST( !r.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<result<int>>));
|
||||
BOOST_TEST_TRAIT_TRUE((std::is_default_constructible<result<int, int>>));
|
||||
|
||||
22
test/result_in_place_use.cpp
Normal file
22
test/result_in_place_use.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
// Copyright 2023 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
template<class T, class U> void test( T const& t, U const& u )
|
||||
{
|
||||
BOOST_TEST_NE( static_cast<void const*>( &t ), static_cast<void const*>( &u ) );
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost::system;
|
||||
|
||||
test( result<int>::in_place_value, result<int>::in_place_error );
|
||||
test( result<void>::in_place_value, result<void>::in_place_error );
|
||||
test( result<int&>::in_place_value, result<int&>::in_place_error );
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
359
test/result_or_fn0r.cpp
Normal file
359
test/result_or_fn0r.cpp
Normal file
@@ -0,0 +1,359 @@
|
||||
// Copyright 2017, 2021, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
struct X
|
||||
{
|
||||
int v_;
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int v_;
|
||||
|
||||
explicit Y( int v ): v_( v ) {}
|
||||
Y( X x ): v_( x.v_) {}
|
||||
|
||||
Y( Y const& ) = delete;
|
||||
Y& operator=( Y const& ) = delete;
|
||||
|
||||
Y( Y&& r ): v_( r.v_ )
|
||||
{
|
||||
r.v_ = 0;
|
||||
}
|
||||
|
||||
Y& operator=( Y&& ) = delete;
|
||||
};
|
||||
|
||||
struct E
|
||||
{
|
||||
};
|
||||
|
||||
result<int, E> fi()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
result<int, E> fi2()
|
||||
{
|
||||
return E();
|
||||
}
|
||||
|
||||
result<Y, E> fy()
|
||||
{
|
||||
return Y{ 2 };
|
||||
}
|
||||
|
||||
result<Y, E> fy2()
|
||||
{
|
||||
return E();
|
||||
}
|
||||
|
||||
result<int&, E> fri()
|
||||
{
|
||||
static int x = 2;
|
||||
return x;
|
||||
}
|
||||
|
||||
result<int&, E> fri2()
|
||||
{
|
||||
return E();
|
||||
}
|
||||
|
||||
result<void, E> fv()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
result<void, E> fv2()
|
||||
{
|
||||
return E();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
result<int> r( 1 );
|
||||
|
||||
int x = r | fi | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> const r( 1 );
|
||||
|
||||
int x = r | fi | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x = result<int>( 1 ) | fi | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> r( 1 );
|
||||
|
||||
int x = r | fi2 | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> const r( 1 );
|
||||
|
||||
int x = r | fi2 | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x = result<int>( 1 ) | fi2 | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> r( in_place_error );
|
||||
|
||||
int x = r | fi | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> const r( in_place_error );
|
||||
|
||||
int x = r | fi | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
int x = result<int>( in_place_error ) | fi | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> r( in_place_error );
|
||||
|
||||
int x = r | fi2 | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> const r( in_place_error );
|
||||
|
||||
int x = r | fi2 | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
int x = result<int>( in_place_error ) | fi2 | 3;
|
||||
|
||||
BOOST_TEST_EQ( x, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y = result<X>( X{1} ) | fy | X{3};
|
||||
|
||||
BOOST_TEST_EQ( y.v_, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y = result<X>( X{1} ) | fy2 | X{3};
|
||||
|
||||
BOOST_TEST_EQ( y.v_, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y = result<X, E>( in_place_error ) | fy | X{3};
|
||||
|
||||
BOOST_TEST_EQ( y.v_, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y = result<X, E>( in_place_error ) | fy2 | Y{3};
|
||||
|
||||
BOOST_TEST_EQ( y.v_, 3 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
int x3 = 3;
|
||||
|
||||
result<int&> r( x1 );
|
||||
|
||||
int& x = r | fri | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
int x3 = 3;
|
||||
|
||||
result<int&> const r( x1 );
|
||||
|
||||
int& x = r | fri | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
int x3 = 3;
|
||||
|
||||
int& x = result<int&>( x1 ) | fri | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
int x3 = 3;
|
||||
|
||||
result<int&> r( x1 );
|
||||
|
||||
int& x = r | fri2 | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
int x3 = 3;
|
||||
|
||||
result<int&> const r( x1 );
|
||||
|
||||
int& x = r | fri2 | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
int x3 = 3;
|
||||
|
||||
int& x = result<int&>( x1 ) | fri2 | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x3 = 3;
|
||||
|
||||
result<int&, E> r( in_place_error );
|
||||
|
||||
int& x = r | fri | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &*fri() );
|
||||
}
|
||||
|
||||
{
|
||||
int x3 = 3;
|
||||
|
||||
result<int&, E> const r( in_place_error );
|
||||
|
||||
int& x = r | fri | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &*fri() );
|
||||
}
|
||||
|
||||
{
|
||||
int x3 = 3;
|
||||
|
||||
int& x = result<int&, E>( in_place_error ) | fri | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &*fri() );
|
||||
}
|
||||
|
||||
{
|
||||
int x3 = 3;
|
||||
|
||||
result<int&, E> r( in_place_error );
|
||||
|
||||
int& x = r | fri2 | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x3 );
|
||||
}
|
||||
|
||||
{
|
||||
int x3 = 3;
|
||||
|
||||
result<int&, E> const r( in_place_error );
|
||||
|
||||
int& x = r | fri2 | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x3 );
|
||||
}
|
||||
|
||||
{
|
||||
int x3 = 3;
|
||||
|
||||
int& x = result<int&, E>( in_place_error ) | fri2 | x3;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x3 );
|
||||
}
|
||||
|
||||
{
|
||||
result<void> r;
|
||||
result<void, E> r2 = r | fv;
|
||||
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void> r;
|
||||
result<void, E> r2 = r | fv2;
|
||||
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void> r( in_place_error );
|
||||
result<void, E> r2 = r | fv;
|
||||
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void> r( in_place_error );
|
||||
result<void, E> r2 = r | fv2;
|
||||
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E> r2 = result<void>() | fv;
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E> r2 = result<void>() | fv2;
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E> r2 = result<void>( in_place_error ) | fv;
|
||||
BOOST_TEST( r2.has_value() );
|
||||
}
|
||||
|
||||
{
|
||||
result<void, E> r2 = result<void>( in_place_error ) | fv2;
|
||||
BOOST_TEST( r2.has_error() );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
162
test/result_or_fn0v.cpp
Normal file
162
test/result_or_fn0v.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
// Copyright 2017, 2021, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
struct X
|
||||
{
|
||||
int v_;
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int v_;
|
||||
|
||||
explicit Y( int v ): v_( v ) {}
|
||||
Y( X x ): v_( x.v_) {}
|
||||
|
||||
Y( Y const& ) = delete;
|
||||
Y& operator=( Y const& ) = delete;
|
||||
|
||||
Y( Y&& r ): v_( r.v_ )
|
||||
{
|
||||
r.v_ = 0;
|
||||
}
|
||||
|
||||
Y& operator=( Y&& ) = delete;
|
||||
};
|
||||
|
||||
struct E
|
||||
{
|
||||
};
|
||||
|
||||
int f()
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
X g()
|
||||
{
|
||||
return { 2 };
|
||||
}
|
||||
|
||||
int& h()
|
||||
{
|
||||
static int x = 2;
|
||||
return x;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
result<int> r( 1 );
|
||||
|
||||
int x = r | f;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> const r( 1 );
|
||||
|
||||
int x = r | f;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x = result<int>( 1 ) | f;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E> r( in_place_error );
|
||||
|
||||
int x = r | f;
|
||||
|
||||
BOOST_TEST_EQ( x, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E> const r( in_place_error );
|
||||
|
||||
int x = r | f;
|
||||
|
||||
BOOST_TEST_EQ( x, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
int x = result<int, E>( in_place_error ) | f;
|
||||
|
||||
BOOST_TEST_EQ( x, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y = result<Y>( in_place_value, 1 ) | g;
|
||||
|
||||
BOOST_TEST_EQ( y.v_, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y = result<Y, E>( in_place_error ) | g;
|
||||
|
||||
BOOST_TEST_EQ( y.v_, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
|
||||
result<int&> r( x1 );
|
||||
|
||||
int& x = r | h;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
|
||||
result<int&> const r( x1 );
|
||||
|
||||
int& x = r | h;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
|
||||
int& x = result<int&>( x1 ) | h;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E> r( in_place_error );
|
||||
|
||||
int& x = r | h;
|
||||
|
||||
BOOST_TEST_EQ( &x, &h() );
|
||||
}
|
||||
|
||||
{
|
||||
result<int&, E> const r( in_place_error );
|
||||
|
||||
int& x = r | h;
|
||||
|
||||
BOOST_TEST_EQ( &x, &h() );
|
||||
}
|
||||
|
||||
{
|
||||
int& x = result<int&, E>( in_place_error ) | h;
|
||||
|
||||
BOOST_TEST_EQ( &x, &h() );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
167
test/result_or_value.cpp
Normal file
167
test/result_or_value.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
// Copyright 2017, 2021, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
struct X
|
||||
{
|
||||
int v_;
|
||||
};
|
||||
|
||||
struct Y
|
||||
{
|
||||
int v_;
|
||||
|
||||
explicit Y( int v ): v_( v ) {}
|
||||
Y( X x ): v_( x.v_) {}
|
||||
|
||||
Y( Y const& ) = delete;
|
||||
Y& operator=( Y const& ) = delete;
|
||||
|
||||
Y( Y&& r ): v_( r.v_ )
|
||||
{
|
||||
r.v_ = 0;
|
||||
}
|
||||
|
||||
Y& operator=( Y&& ) = delete;
|
||||
};
|
||||
|
||||
struct E
|
||||
{
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
result<int> r( 1 );
|
||||
|
||||
int x = r | 2;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int> const r( 1 );
|
||||
|
||||
int x = r | 2;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x = result<int>( 1 ) | 2;
|
||||
|
||||
BOOST_TEST_EQ( x, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E> r( in_place_error );
|
||||
|
||||
int x = r | 2;
|
||||
|
||||
BOOST_TEST_EQ( x, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
result<int, E> const r( in_place_error );
|
||||
|
||||
int x = r | 2;
|
||||
|
||||
BOOST_TEST_EQ( x, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
int x = result<int, E>( in_place_error ) | 2;
|
||||
|
||||
BOOST_TEST_EQ( x, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y = result<Y>( in_place_value, 1 ) | Y{2};
|
||||
|
||||
BOOST_TEST_EQ( y.v_, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y = result<Y, E>( in_place_error ) | Y{2};
|
||||
|
||||
BOOST_TEST_EQ( y.v_, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y = result<Y>( in_place_value, 1 ) | X{2};
|
||||
|
||||
BOOST_TEST_EQ( y.v_, 1 );
|
||||
}
|
||||
|
||||
{
|
||||
Y y = result<Y, E>( in_place_error ) | X{2};
|
||||
|
||||
BOOST_TEST_EQ( y.v_, 2 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
int x2 = 2;
|
||||
|
||||
result<int&> r( x1 );
|
||||
|
||||
int& x = r | x2;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
int x2 = 2;
|
||||
|
||||
result<int&> const r( x1 );
|
||||
|
||||
int& x = r | x2;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x1 = 1;
|
||||
int x2 = 2;
|
||||
|
||||
int& x = result<int&>( x1 ) | x2;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x1 );
|
||||
}
|
||||
|
||||
{
|
||||
int x2 = 2;
|
||||
|
||||
result<int&, E> r( in_place_error );
|
||||
|
||||
int& x = r | x2;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x2 );
|
||||
}
|
||||
|
||||
{
|
||||
int x2 = 2;
|
||||
|
||||
result<int&, E> const r( in_place_error );
|
||||
|
||||
int& x = r | x2;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x2 );
|
||||
}
|
||||
|
||||
{
|
||||
int x2 = 2;
|
||||
|
||||
int& x = result<int&, E>( in_place_error ) | x2;
|
||||
|
||||
BOOST_TEST_EQ( &x, &x2 );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
14
test/result_or_value_fail.cpp
Normal file
14
test/result_or_value_fail.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
// Copyright 2017, 2021, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
int main()
|
||||
{
|
||||
int x = 1;
|
||||
result<int const&> r( x );
|
||||
r | 2;
|
||||
}
|
||||
13
test/result_or_value_fail2.cpp
Normal file
13
test/result_or_value_fail2.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017, 2021, 2022 Peter Dimov.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/system/result.hpp>
|
||||
|
||||
using namespace boost::system;
|
||||
|
||||
int main()
|
||||
{
|
||||
int x = 1;
|
||||
result<int const&>( x ) | 2;
|
||||
}
|
||||
@@ -69,6 +69,11 @@ result<std::vector<int>> fv2()
|
||||
return {{ 1, 2 }};
|
||||
}
|
||||
|
||||
result<void> fw0()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
{
|
||||
@@ -148,5 +153,12 @@ int main()
|
||||
BOOST_TEST_EQ( r->at(1), 2 );
|
||||
}
|
||||
|
||||
{
|
||||
result<void> r = fw0();
|
||||
|
||||
BOOST_TEST( r.has_value() );
|
||||
BOOST_TEST( !r.has_error() );
|
||||
}
|
||||
|
||||
return boost::report_errors();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user