forked from TartanLlama/expected
Merge branch 'master' of github.com:TartanLlama/expected
This commit is contained in:
54
README.md
54
README.md
@@ -1,11 +1,61 @@
|
|||||||
# expected
|
# expected
|
||||||
Single header, work-in-progress implementation of `std::expected` with functional-style extensions.
|
Single header implementation of `std::expected` with functional-style extensions.
|
||||||
|
|
||||||
Clang + GCC: [](https://travis-ci.org/TartanLlama/expected)
|
Clang + GCC: [](https://travis-ci.org/TartanLlama/expected)
|
||||||
MSVC: [](https://ci.appveyor.com/project/TartanLlama/expected)
|
MSVC: [](https://ci.appveyor.com/project/TartanLlama/expected)
|
||||||
|
|
||||||
|
[`std::expected`](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0323r3.pdf) is proposed as the preferred way to represent object which will either have an expected value, or an unexpected value giving information about why something failed. Unfortunately, chaining together many computations which may fail can be verbose, as error-checking code will be mixed in with the actual programming logic. This implementation provides a number of utilities to make coding with `expected` cleaner.
|
||||||
|
|
||||||
|
For example, instead of writing this code:
|
||||||
|
|
||||||
|
```
|
||||||
|
std::expected<image,fail_reason> get_cute_cat (const image& img) {
|
||||||
|
auto cropped = crop_to_cat(img);
|
||||||
|
if (!cropped) {
|
||||||
|
return cropped;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto with_tie = add_bow_tie(*cropped);
|
||||||
|
if (!with_tie) {
|
||||||
|
return with_tie;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto with_sparkles = make_eyes_sparkle(*with_tie);
|
||||||
|
if (!with_sparkles) {
|
||||||
|
return with_sparkles;
|
||||||
|
}
|
||||||
|
|
||||||
|
return add_rainbow(make_smaller(*with_sparkles));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You can do this:
|
||||||
|
|
||||||
|
```
|
||||||
|
tl::expected<image,fail_reason> get_cute_cat (const image& img) {
|
||||||
|
return crop_to_cat(img)
|
||||||
|
.and_then(add_bow_tie)
|
||||||
|
.and_then(make_eyes_sparkle)
|
||||||
|
.map(make_smaller)
|
||||||
|
.map(add_rainbow);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Full documentation available at [expected.tartanllama.xyz](https://expected.tartanllama.xyz)
|
Full documentation available at [expected.tartanllama.xyz](https://expected.tartanllama.xyz)
|
||||||
|
|
||||||
|
The interface is the same as `std::expected` as proposed in [p0323r3](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0323r3.pdf), but the following member functions are also defined. Explicit types are for clarity.
|
||||||
|
|
||||||
|
- `map`: carries out some operation on the stored object if there is one.
|
||||||
|
* `tl::expected<std::size_t,std::error_code> s = exp_string.map(&std::string::size);`
|
||||||
|
- `map_error`: carries out some operation on the unexpected object if there is one.
|
||||||
|
* `my_error_code translate_error (std::error_code);`
|
||||||
|
* `tl::expected<int,my_error_code> s = exp_int.map(translate_error);`
|
||||||
|
- `and_then`: like `map`, but for operations which return a `tl::expected`.
|
||||||
|
* `tl::expected<ast, fail_reason> parse (const std::string& s);`
|
||||||
|
* `tl::expected<ast, fail_reason> exp_ast = exp_string.and_then(parse);`
|
||||||
|
- `or_else`: calls some function if there is no value stored.
|
||||||
|
* `exp.or_else([] { throw std::runtime_error{"oh no"}; });`
|
||||||
|
|
||||||
### Compiler support
|
### Compiler support
|
||||||
|
|
||||||
Tested on:
|
Tested on:
|
||||||
@@ -36,4 +86,4 @@ Requires [Catch](https://github.com/philsquared/Catch) for testing. This is bund
|
|||||||
|
|
||||||
[]("http://creativecommons.org/publicdomain/zero/1.0/")
|
[]("http://creativecommons.org/publicdomain/zero/1.0/")
|
||||||
|
|
||||||
To the extent possible under law, [Simon Brand](https://twitter.com/TartanLlama) has waived all copyright and related or neighboring rights to the `optional` library. This work is published from: United Kingdom.
|
To the extent possible under law, [Simon Brand](https://twitter.com/TartanLlama) has waived all copyright and related or neighboring rights to the `expected` library. This work is published from: United Kingdom.
|
||||||
|
354
docs/index.md
354
docs/index.md
@@ -1,144 +1,146 @@
|
|||||||
# Header file `expected.hpp`<a id="expected.hpp"></a>
|
# Header file `expected.hpp`<a id="expected.hpp"></a>
|
||||||
|
|
||||||
<pre><code class="language-cpp">#define <a href='doc_expected.md#expected.hpp'>TL_EXPECTED_HPP</a>
|
<pre><code class="language-cpp">#define <a href='doc_expected.html#expected.hpp'>TL_EXPECTED_HPP</a>
|
||||||
|
|
||||||
#define <a href='doc_expected.md#expected.hpp'>TL_EXPECTED_GCC49</a>
|
#define <a href='doc_expected.html#expected.hpp'>TL_EXPECTED_VERSION_MAJOR</a>
|
||||||
|
|
||||||
#define <a href='doc_expected.md#expected.hpp'>TL_EXPECTED_NO_CONSTRR</a>
|
#define <a href='doc_expected.html#expected.hpp'>TL_EXPECTED_VERSION_MINOR</a>
|
||||||
|
|
||||||
#define <a href='doc_expected.md#expected.hpp'>TL_EXPECTED_CXX14</a>
|
#define <a href='doc_expected.html#expected.hpp'>TL_MONOSTATE_INPLACE_MUTEX</a>
|
||||||
|
|
||||||
#define <a href='doc_expected.md#expected.hpp'>TL_IN_PLACE_MONOSTATE_DEFINED</a>
|
#define <a href='doc_expected.html#expected.hpp'>TL_TRAITS_MUTEX</a>
|
||||||
|
|
||||||
namespace <a href='doc_expected.md#expected.hpp'>tl</a>
|
#define <a href='doc_expected.html#expected.hpp'>TL_OPTIONAL_EXPECTED_MUTEX</a>
|
||||||
|
|
||||||
|
namespace <a href='doc_expected.html#expected.hpp'>tl</a>
|
||||||
{
|
{
|
||||||
class <a href='doc_expected.md#tl::monostate'>monostate</a>;
|
class <a href='doc_expected.html#tl::monostate'>monostate</a>;
|
||||||
|
|
||||||
struct <a href='doc_expected.md#tl::in_place_t'>in_place_t</a>;
|
struct <a href='doc_expected.html#tl::in_place_t'>in_place_t</a>;
|
||||||
|
|
||||||
constexpr <a href='doc_expected.md#tl::in_place_t'>in_place_t{}</a> <a href='doc_expected.md#tl::in_place'>in_place</a>;
|
constexpr <a href='doc_expected.html#tl::in_place_t'>in_place_t{}</a> <a href='doc_expected.html#tl::in_place'>in_place</a>;
|
||||||
|
|
||||||
template <class E>
|
template <class E>
|
||||||
class <a href='doc_expected.md#tl::unexpected-E-'>unexpected</a>;
|
class <a href='doc_expected.html#tl::unexpected-E-'>unexpected</a>;
|
||||||
|
|
||||||
template <class E>
|
template <class E>
|
||||||
constexpr bool <a href='doc_expected.md#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator==</a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
constexpr bool <a href='doc_expected.html#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator==</a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
||||||
template <class E>
|
template <class E>
|
||||||
constexpr bool <a href='doc_expected.md#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator!=</a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
constexpr bool <a href='doc_expected.html#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator!=</a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
||||||
template <class E>
|
template <class E>
|
||||||
constexpr bool <a href='doc_expected.md#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator<</a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
constexpr bool <a href='doc_expected.html#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator<</a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
||||||
template <class E>
|
template <class E>
|
||||||
constexpr bool <a href='doc_expected.md#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator<=</a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
constexpr bool <a href='doc_expected.html#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator<=</a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
||||||
template <class E>
|
template <class E>
|
||||||
constexpr bool <a href='doc_expected.md#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator></a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
constexpr bool <a href='doc_expected.html#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator></a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
||||||
template <class E>
|
template <class E>
|
||||||
constexpr bool <a href='doc_expected.md#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator>=</a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
constexpr bool <a href='doc_expected.html#tl::operator==(constunexpected-E-&,constunexpected-E-&)'>operator>=</a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
||||||
|
|
||||||
template <class E>
|
template <class E>
|
||||||
<a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a> <a href='doc_expected.md#tl::make_unexpected(E&&)'>make_unexpected</a>(E&& e);
|
<a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a> <a href='doc_expected.html#tl::make_unexpected(E&&)'>make_unexpected</a>(E&& e);
|
||||||
|
|
||||||
struct <a href='doc_expected.md#tl::unexpect_t'>unexpect_t</a>;
|
struct <a href='doc_expected.html#tl::unexpect_t'>unexpect_t</a>;
|
||||||
|
|
||||||
constexpr <a href='doc_expected.md#tl::unexpect_t'>unexpect_t{}</a> <a href='doc_expected.md#tl::unexpect'>unexpect</a>;
|
constexpr <a href='doc_expected.html#tl::unexpect_t'>unexpect_t{}</a> <a href='doc_expected.html#tl::unexpect'>unexpect</a>;
|
||||||
|
|
||||||
template <class E>
|
template <class E>
|
||||||
class <a href='doc_expected.md#expected.hpp'>bad_expected_access</a>;
|
class <a href='doc_expected.html#expected.hpp'>bad_expected_access</a>;
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
class <a href='doc_expected.md#tl::expected-T,E-'>expected</a>;
|
class <a href='doc_expected.html#tl::expected-T,E-'>expected</a>;
|
||||||
|
|
||||||
template <class T, class E, class U, class F>
|
template <class T, class E, class U, class F>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator==</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.md#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator==</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.html#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
||||||
|
|
||||||
template <class T, class E, class U, class F>
|
template <class T, class E, class U, class F>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator!=</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.md#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator!=</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.html#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
||||||
|
|
||||||
template <class T, class E, class U, class F>
|
template <class T, class E, class U, class F>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator<</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.md#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator<</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.html#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
||||||
|
|
||||||
template <class T, class E, class U, class F>
|
template <class T, class E, class U, class F>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator></a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.md#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator></a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.html#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
||||||
|
|
||||||
template <class T, class E, class U, class F>
|
template <class T, class E, class U, class F>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator<=</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.md#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator<=</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.html#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
||||||
|
|
||||||
template <class T, class E, class U, class F>
|
template <class T, class E, class U, class F>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator>=</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.md#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator>=</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& lhs, const <a href='doc_expected.html#tl::expected-T,E-'>expected<U, F></a>& rhs);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator==</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator==</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator==</a>(const U& v, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator==</a>(const U& v, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator!=</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator!=</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator!=</a>(const U& v, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator!=</a>(const U& v, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator<</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator<</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator<</a>(const U& v, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator<</a>(const U& v, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator<=</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator<=</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator<=</a>(const U& v, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator<=</a>(const U& v, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator></a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator></a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator></a>(const U& v, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator></a>(const U& v, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator>=</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator>=</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const U& v);
|
||||||
|
|
||||||
template <class T, class E, class U>
|
template <class T, class E, class U>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator>=</a>(const U& v, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator>=</a>(const U& v, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator==</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator==</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator==</a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator==</a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator!=</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator!=</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator!=</a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator!=</a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator<</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator<</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator<</a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator<</a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator<=</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator<=</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator<=</a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator<=</a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator></a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator></a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator></a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator></a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator>=</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator>=</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e);
|
||||||
|
|
||||||
template <class T, class E>
|
template <class T, class E>
|
||||||
constexpr bool <a href='doc_expected.md#expected.hpp'>operator>=</a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& x);
|
constexpr bool <a href='doc_expected.html#expected.hpp'>operator>=</a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& e, const <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& x);
|
||||||
|
|
||||||
template <class T, class E, 'hidden'>
|
template <class T, class E, 'hidden'>
|
||||||
void <a href='doc_expected.md#expected.hpp'>swap</a>(<a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& lhs, <a href='doc_expected.md#tl::expected-T,E-'>expected<T, E></a>& rhs) noexcept(noexcept(lhs.swap(rhs)));
|
void <a href='doc_expected.html#expected.hpp'>swap</a>(<a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& lhs, <a href='doc_expected.html#tl::expected-T,E-'>expected<T, E></a>& rhs) noexcept(noexcept(lhs.swap(rhs)));
|
||||||
}</code></pre>
|
}</code></pre>
|
||||||
|
|
||||||
## Class `tl::monostate`<a id="tl::monostate"></a>
|
## Class `tl::monostate`<a id="tl::monostate"></a>
|
||||||
@@ -153,14 +155,14 @@ Used to represent an expected with no data
|
|||||||
|
|
||||||
<pre><code class="language-cpp">struct in_place_t
|
<pre><code class="language-cpp">struct in_place_t
|
||||||
{
|
{
|
||||||
<a href='doc_expected.md#tl::in_place_t'>in_place_t</a>() = default;
|
<a href='doc_expected.html#tl::in_place_t'>in_place_t</a>() = default;
|
||||||
};</code></pre>
|
};</code></pre>
|
||||||
|
|
||||||
A tag type to tell expected to construct its value in-place
|
A tag type to tell expected to construct its value in-place
|
||||||
|
|
||||||
## Variable `tl::in_place`<a id="tl::in_place"></a>
|
## Variable `tl::in_place`<a id="tl::in_place"></a>
|
||||||
|
|
||||||
<pre><code class="language-cpp">constexpr <a href='doc_expected.md#tl::in_place_t'>in_place_t{}</a> in_place;</code></pre>
|
<pre><code class="language-cpp">constexpr <a href='doc_expected.html#tl::in_place_t'>in_place_t{}</a> in_place;</code></pre>
|
||||||
|
|
||||||
A tag to tell expected to construct its value in-place
|
A tag to tell expected to construct its value in-place
|
||||||
|
|
||||||
@@ -170,15 +172,15 @@ A tag to tell expected to construct its value in-place
|
|||||||
class unexpected
|
class unexpected
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
<a href='doc_expected.md#tl::unexpected-E-'>unexpected</a>() = delete;
|
<a href='doc_expected.html#tl::unexpected-E-'>unexpected</a>() = delete;
|
||||||
|
|
||||||
constexpr <a href='doc_expected.md#tl::unexpected-E-'>unexpected</a>(const E& e);
|
constexpr <a href='doc_expected.html#tl::unexpected-E-'>unexpected</a>(const E& e);
|
||||||
|
|
||||||
constexpr <a href='doc_expected.md#tl::unexpected-E-'>unexpected</a>(E&& e);
|
constexpr <a href='doc_expected.html#tl::unexpected-E-'>unexpected</a>(E&& e);
|
||||||
|
|
||||||
constexpr const E& <a href='doc_expected.md#tl::unexpected-E-::value()const&'>value</a>() const &;
|
constexpr const E& <a href='doc_expected.html#tl::unexpected-E-::value()const&'>value</a>() const &;
|
||||||
constexpr E& <a href='doc_expected.md#tl::unexpected-E-::value()const&'>value</a>() &;
|
E& <a href='doc_expected.html#tl::unexpected-E-::value()const&'>value</a>() &;
|
||||||
constexpr E&& <a href='doc_expected.md#tl::unexpected-E-::value()const&'>value</a>() &&;
|
E&& <a href='doc_expected.html#tl::unexpected-E-::value()const&'>value</a>() &&;
|
||||||
};</code></pre>
|
};</code></pre>
|
||||||
|
|
||||||
Used as a wrapper to store the unexpected value
|
Used as a wrapper to store the unexpected value
|
||||||
@@ -187,9 +189,9 @@ Used as a wrapper to store the unexpected value
|
|||||||
|
|
||||||
<pre><code class="language-cpp">(1) constexpr const E& value() const &;
|
<pre><code class="language-cpp">(1) constexpr const E& value() const &;
|
||||||
|
|
||||||
(2) constexpr E& value() &;
|
(2) E& value() &;
|
||||||
|
|
||||||
(3) constexpr E&& value() &&;</code></pre>
|
(3) E&& value() &&;</code></pre>
|
||||||
|
|
||||||
*Returns*: the contained value
|
*Returns*: the contained value
|
||||||
|
|
||||||
@@ -198,22 +200,22 @@ Used as a wrapper to store the unexpected value
|
|||||||
## Comparison operator `tl::operator==`<a id="tl::operator==(constunexpected-E-&,constunexpected-E-&)"></a>
|
## Comparison operator `tl::operator==`<a id="tl::operator==(constunexpected-E-&,constunexpected-E-&)"></a>
|
||||||
|
|
||||||
<pre><code class="language-cpp">(1) template <class E>
|
<pre><code class="language-cpp">(1) template <class E>
|
||||||
constexpr bool operator==(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
constexpr bool operator==(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
||||||
|
|
||||||
(2) template <class E>
|
(2) template <class E>
|
||||||
constexpr bool operator!=(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
constexpr bool operator!=(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
||||||
|
|
||||||
(3) template <class E>
|
(3) template <class E>
|
||||||
constexpr bool operator<(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
constexpr bool operator<(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
||||||
|
|
||||||
(4) template <class E>
|
(4) template <class E>
|
||||||
constexpr bool operator<=(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
constexpr bool operator<=(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
||||||
|
|
||||||
(5) template <class E>
|
(5) template <class E>
|
||||||
constexpr bool operator>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
constexpr bool operator>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);
|
||||||
|
|
||||||
(6) template <class E>
|
(6) template <class E>
|
||||||
constexpr bool operator>=(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>& rhs);</code></pre>
|
constexpr bool operator>=(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& lhs, const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>& rhs);</code></pre>
|
||||||
|
|
||||||
Compares two unexpected objects
|
Compares two unexpected objects
|
||||||
|
|
||||||
@@ -222,7 +224,7 @@ Simply compares lhs.value() to rhs.value()
|
|||||||
## Function template `tl::make_unexpected`<a id="tl::make_unexpected(E&&)"></a>
|
## Function template `tl::make_unexpected`<a id="tl::make_unexpected(E&&)"></a>
|
||||||
|
|
||||||
<pre><code class="language-cpp">template <class E>
|
<pre><code class="language-cpp">template <class E>
|
||||||
<a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a> make_unexpected(E&& e);</code></pre>
|
<a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a> make_unexpected(E&& e);</code></pre>
|
||||||
|
|
||||||
Create an `unexpected` from `e`, deducing the return type
|
Create an `unexpected` from `e`, deducing the return type
|
||||||
|
|
||||||
@@ -232,14 +234,14 @@ Create an `unexpected` from `e`, deducing the return type
|
|||||||
|
|
||||||
<pre><code class="language-cpp">struct unexpect_t
|
<pre><code class="language-cpp">struct unexpect_t
|
||||||
{
|
{
|
||||||
<a href='doc_expected.md#tl::unexpect_t'>unexpect_t</a>() = default;
|
<a href='doc_expected.html#tl::unexpect_t'>unexpect_t</a>() = default;
|
||||||
};</code></pre>
|
};</code></pre>
|
||||||
|
|
||||||
A tag type to tell expected to construct the unexpected value
|
A tag type to tell expected to construct the unexpected value
|
||||||
|
|
||||||
## Variable `tl::unexpect`<a id="tl::unexpect"></a>
|
## Variable `tl::unexpect`<a id="tl::unexpect"></a>
|
||||||
|
|
||||||
<pre><code class="language-cpp">constexpr <a href='doc_expected.md#tl::unexpect_t'>unexpect_t{}</a> unexpect;</code></pre>
|
<pre><code class="language-cpp">constexpr <a href='doc_expected.html#tl::unexpect_t'>unexpect_t{}</a> unexpect;</code></pre>
|
||||||
|
|
||||||
A tag to tell expected to construct the unexpected value
|
A tag to tell expected to construct the unexpected value
|
||||||
|
|
||||||
@@ -249,112 +251,116 @@ A tag to tell expected to construct the unexpected value
|
|||||||
class expected
|
class expected
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using <a href='doc_expected.md#tl::expected-T,E-'>value_type</a> = T;
|
using <a href='doc_expected.html#tl::expected-T,E-'>value_type</a> = T;
|
||||||
|
|
||||||
using <a href='doc_expected.md#tl::expected-T,E-'>error_type</a> = E;
|
using <a href='doc_expected.html#tl::expected-T,E-'>error_type</a> = E;
|
||||||
|
|
||||||
using <a href='doc_expected.md#tl::expected-T,E-'>unexpected_type</a> = <a href='doc_expected.md#tl::unexpected-E-'>unexpected<E></a>;
|
using <a href='doc_expected.html#tl::expected-T,E-'>unexpected_type</a> = <a href='doc_expected.html#tl::unexpected-E-'>unexpected<E></a>;
|
||||||
|
|
||||||
template <class F>
|
template <class F>
|
||||||
'hidden' <a href='doc_expected.md#tl::expected-T,E-::and_then(F&&)&'>and_then</a>(F&& f) &;
|
constexpr auto and_then(F &&f) &;
|
||||||
template <class F>
|
template <class F>
|
||||||
constexpr auto and_then(F &&f) &&;
|
constexpr auto and_then(F &&f) &&;
|
||||||
template <class F>
|
template <class F>
|
||||||
constexpr auto and_then(F &&f) const &;
|
constexpr auto and_then(F &&f) const &;
|
||||||
|
template <class F>
|
||||||
|
constexpr auto and_then(F &&f) const &&;
|
||||||
|
|
||||||
template <class F> constexpr auto map(F &&f) &;
|
template <class F> constexpr auto map(F &&f) &;
|
||||||
template <class F> constexpr auto map(F &&f) &&;
|
template <class F> constexpr auto map(F &&f) &&;
|
||||||
template <class F> constexpr auto map(F &&f) const &;
|
template <class F> constexpr auto map(F &&f) const &;
|
||||||
|
template <class F> constexpr auto map(F &&f) const &&;
|
||||||
|
|
||||||
template <class F> constexpr auto map_error(F &&f) &;
|
template <class F> constexpr auto map_error(F &&f) &;
|
||||||
template <class F> constexpr auto map_error(F &&f) &&;
|
template <class F> constexpr auto map_error(F &&f) &&;
|
||||||
template <class F> constexpr auto map_error(F &&f) const &;
|
template <class F> constexpr auto map_error(F &&f) const &;
|
||||||
|
template <class F> constexpr auto map_error(F &&f) const &&;
|
||||||
|
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>expected</a>() = default;
|
template <class F>
|
||||||
|
<a href='doc_expected.html#tl::expected-T,E-'>expected</a> <a href='doc_expected.html#tl::expected-T,E-::or_else(F&&)&'>or_else</a>(F&& f) &;
|
||||||
|
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>expected</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected</a>& rhs) = default;
|
template <class F>
|
||||||
|
<a href='doc_expected.html#tl::expected-T,E-'>expected</a> <a href='doc_expected.html#tl::expected-T,E-'>or_else</a>(F&& f) &&;
|
||||||
|
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>expected</a>(<a href='doc_expected.md#tl::expected-T,E-'>expected</a>&& rhs) = default;
|
template <class F>
|
||||||
|
constexpr <a href='doc_expected.html#tl::expected-T,E-'>expected</a> <a href='doc_expected.html#tl::expected-T,E-'>or_else</a>(F&& f) const &;
|
||||||
|
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>expected</a>& <a href='doc_expected.md#tl::expected-T,E-'>operator=</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected</a>& rhs) = default;
|
template <class F>
|
||||||
|
constexpr <a href='doc_expected.html#tl::expected-T,E-'>expected</a> <a href='doc_expected.html#tl::expected-T,E-'>or_else</a>(F&& f) const &&;
|
||||||
|
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>expected</a>& <a href='doc_expected.md#tl::expected-T,E-'>operator=</a>(<a href='doc_expected.md#tl::expected-T,E-'>expected</a>&& rhs) = default;
|
constexpr <a href='doc_expected.html#tl::expected-T,E-'>expected</a>() = default;
|
||||||
|
|
||||||
|
constexpr <a href='doc_expected.html#tl::expected-T,E-'>expected</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected</a>& rhs) = default;
|
||||||
|
|
||||||
|
constexpr <a href='doc_expected.html#tl::expected-T,E-'>expected</a>(<a href='doc_expected.html#tl::expected-T,E-'>expected</a>&& rhs) = default;
|
||||||
|
|
||||||
|
<a href='doc_expected.html#tl::expected-T,E-'>expected</a>& <a href='doc_expected.html#tl::expected-T,E-'>operator=</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected</a>& rhs) = default;
|
||||||
|
|
||||||
|
<a href='doc_expected.html#tl::expected-T,E-'>expected</a>& <a href='doc_expected.html#tl::expected-T,E-'>operator=</a>(<a href='doc_expected.html#tl::expected-T,E-'>expected</a>&& rhs) = default;
|
||||||
|
|
||||||
template <class ... Args, 'hidden' ... = nullptr>
|
template <class ... Args, 'hidden' ... = nullptr>
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>expected</a>(<a href='doc_expected.md#tl::in_place_t'>in_place_t</a>, Args&&... args);
|
constexpr <a href='doc_expected.html#tl::expected-T,E-'>expected</a>(<a href='doc_expected.html#tl::in_place_t'>in_place_t</a>, Args&&... args);
|
||||||
|
|
||||||
template <class U, class ... Args, 'hidden' ... = nullptr>
|
template <class U, class ... Args, 'hidden' ... = nullptr>
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>expected</a>(<a href='doc_expected.md#tl::in_place_t'>in_place_t</a>, <a href='http://en.cppreference.com/mwiki/index.php?title=Special%3ASearch&search=std::initializer_list%3cU%3e'>std::initializer_list<U></a> il, Args&&... args);
|
constexpr <a href='doc_expected.html#tl::expected-T,E-'>expected</a>(<a href='doc_expected.html#tl::in_place_t'>in_place_t</a>, <a href='http://en.cppreference.com/mwiki/index.php?title=Special%3ASearch&search=std::initializer_list%3cU%3e'>std::initializer_list<U></a> il, Args&&... args);
|
||||||
|
|
||||||
EXPLICIT constexpr expected(const unexpected<G> &e);
|
EXPLICIT constexpr expected(const unexpected<G> &e);
|
||||||
EXPLICIT constexpr expected(unexpected<G> &&e);
|
EXPLICIT constexpr expected(unexpected<G> &&e);
|
||||||
|
|
||||||
template <class ... Args, 'hidden' ... = nullptr>
|
template <class ... Args, 'hidden' ... = nullptr>
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>expected</a>(<a href='doc_expected.md#tl::unexpect_t'>unexpect_t</a>, Args&&... args);
|
constexpr <a href='doc_expected.html#tl::expected-T,E-'>expected</a>(<a href='doc_expected.html#tl::unexpect_t'>unexpect_t</a>, Args&&... args);
|
||||||
|
|
||||||
template <class U, class G, 'hidden'>
|
template <class U, class G, 'hidden', 'hidden'>
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>expected</a>(const <a href='doc_expected.md#tl::expected-T,E-'>expected<U, G></a>& rhs);
|
<a href='doc_expected.html#tl::expected-T,E-'>expected</a>(const <a href='doc_expected.html#tl::expected-T,E-'>expected<U, G></a>& rhs);
|
||||||
|
|
||||||
template <class U, class G, 'hidden'>
|
template <class U, class G, 'hidden', 'hidden'>
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>expected</a>(<a href='doc_expected.md#tl::expected-T,E-'>expected<U, G></a>&& rhs);
|
<a href='doc_expected.html#tl::expected-T,E-'>expected</a>(<a href='doc_expected.html#tl::expected-T,E-'>expected<U, G></a>&& rhs);
|
||||||
|
|
||||||
template <class U = T, 'hidden'>
|
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>expected</a>(U&& v);
|
|
||||||
|
|
||||||
template <class U = T, 'hidden', 'hidden'>
|
template <class U = T, 'hidden', 'hidden'>
|
||||||
<a href='doc_expected.md#tl::expected-T,E-'>expected</a>& <a href='doc_expected.md#tl::expected-T,E-'>operator=</a>(U&& v);
|
constexpr <a href='doc_expected.html#tl::expected-T,E-'>expected</a>(U&& v);
|
||||||
|
|
||||||
|
template <class U = T, 'hidden', 'hidden'>
|
||||||
|
<a href='doc_expected.html#tl::expected-T,E-'>expected</a>& <a href='doc_expected.html#tl::expected-T,E-'>operator=</a>(U&& v);
|
||||||
|
|
||||||
template <class G = E, 'hidden'>
|
template <class G = E, 'hidden'>
|
||||||
<a href='doc_expected.md#tl::expected-T,E-'>expected</a>& <a href='doc_expected.md#tl::expected-T,E-'>operator=</a>(const <a href='doc_expected.md#tl::unexpected-E-'>unexpected<G></a>& rhs);
|
<a href='doc_expected.html#tl::expected-T,E-'>expected</a>& <a href='doc_expected.html#tl::expected-T,E-'>operator=</a>(const <a href='doc_expected.html#tl::unexpected-E-'>unexpected<G></a>& rhs);
|
||||||
|
|
||||||
template <class G = E, 'hidden'>
|
template <class G = E, 'hidden'>
|
||||||
<a href='doc_expected.md#tl::expected-T,E-'>expected</a>& <a href='doc_expected.md#tl::expected-T,E-'>operator=</a>(<a href='doc_expected.md#tl::unexpected-E-'>unexpected<G></a>&& rhs) noexcept;
|
<a href='doc_expected.html#tl::expected-T,E-'>expected</a>& <a href='doc_expected.html#tl::expected-T,E-'>operator=</a>(<a href='doc_expected.html#tl::unexpected-E-'>unexpected<G></a>&& rhs) noexcept;
|
||||||
|
|
||||||
template <class ... Args, 'hidden' ... = nullptr>
|
template <class ... Args, 'hidden' ... = nullptr>
|
||||||
void <a href='doc_expected.md#tl::expected-T,E-'>emplace</a>(Args&&... args);
|
void <a href='doc_expected.html#tl::expected-T,E-'>emplace</a>(Args&&... args);
|
||||||
|
|
||||||
template <class U, class ... Args, 'hidden' ... = nullptr>
|
template <class U, class ... Args, 'hidden' ... = nullptr>
|
||||||
void <a href='doc_expected.md#tl::expected-T,E-'>emplace</a>(<a href='http://en.cppreference.com/mwiki/index.php?title=Special%3ASearch&search=std::initializer_list%3cU%3e'>std::initializer_list<U></a> il, Args&&... args);
|
void <a href='doc_expected.html#tl::expected-T,E-'>emplace</a>(<a href='http://en.cppreference.com/mwiki/index.php?title=Special%3ASearch&search=std::initializer_list%3cU%3e'>std::initializer_list<U></a> il, Args&&... args);
|
||||||
|
|
||||||
void <a href='doc_expected.md#tl::expected-T,E-'>swap</a>(<a href='doc_expected.md#tl::expected-T,E-'>expected</a>& rhs) noexcept(std::is_nothrow_move_constructible<T>::value&&noexcept(swap(std::declval<T&>(), std::declval<T&>()))&&std::is_nothrow_move_constructible<E>::value&&noexcept(swap(std::declval<E&>(), std::declval<E&>())));
|
void <a href='doc_expected.html#tl::expected-T,E-'>swap</a>(<a href='doc_expected.html#tl::expected-T,E-'>expected</a>& rhs) noexcept(std::is_nothrow_move_constructible<T>::value&&noexcept(swap(std::declval<T&>(), std::declval<T&>()))&&std::is_nothrow_move_constructible<E>::value&&noexcept(swap(std::declval<E&>(), std::declval<E&>())));
|
||||||
|
|
||||||
constexpr const T* <a href='doc_expected.md#tl::expected-T,E-'>operator-></a>() const;
|
constexpr const T* <a href='doc_expected.html#tl::expected-T,E-::operator--()const'>operator-></a>() const;
|
||||||
|
T* <a href='doc_expected.html#tl::expected-T,E-::operator--()const'>operator-></a>();
|
||||||
|
|
||||||
constexpr T* <a href='doc_expected.md#tl::expected-T,E-'>operator-></a>();
|
constexpr const T& <a href='doc_expected.html#tl::expected-T,E-::operator*()const&'>operator*</a>() const &;
|
||||||
|
T& <a href='doc_expected.html#tl::expected-T,E-::operator*()const&'>operator*</a>() &;
|
||||||
|
constexpr const T&& <a href='doc_expected.html#tl::expected-T,E-::operator*()const&'>operator*</a>() const &&;
|
||||||
|
T&& <a href='doc_expected.html#tl::expected-T,E-::operator*()const&'>operator*</a>() &&;
|
||||||
|
|
||||||
constexpr const T& <a href='doc_expected.md#tl::expected-T,E-'>operator*</a>() const &;
|
constexpr bool <a href='doc_expected.html#tl::expected-T,E-::has_value()const'>has_value</a>() const noexcept;
|
||||||
|
constexpr <a href='doc_expected.html#tl::expected-T,E-::has_value()const'>operator bool</a>() const noexcept;
|
||||||
|
|
||||||
constexpr T& <a href='doc_expected.md#tl::expected-T,E-'>operator*</a>() &;
|
constexpr const T& <a href='doc_expected.html#tl::expected-T,E-::value()const&'>value</a>() const &;
|
||||||
|
T& <a href='doc_expected.html#tl::expected-T,E-::value()const&'>value</a>() &;
|
||||||
|
constexpr const T&& <a href='doc_expected.html#tl::expected-T,E-::value()const&'>value</a>() const &&;
|
||||||
|
T&& <a href='doc_expected.html#tl::expected-T,E-::value()const&'>value</a>() &&;
|
||||||
|
|
||||||
constexpr const T&& <a href='doc_expected.md#tl::expected-T,E-'>operator*</a>() const &&;
|
constexpr const E& <a href='doc_expected.html#tl::expected-T,E-::error()const&'>error</a>() const &;
|
||||||
|
E& <a href='doc_expected.html#tl::expected-T,E-::error()const&'>error</a>() &;
|
||||||
constexpr T&& <a href='doc_expected.md#tl::expected-T,E-'>operator*</a>() &&;
|
constexpr const E&& <a href='doc_expected.html#tl::expected-T,E-::error()const&'>error</a>() const &&;
|
||||||
|
E&& <a href='doc_expected.html#tl::expected-T,E-::error()const&'>error</a>() &&;
|
||||||
constexpr <a href='doc_expected.md#tl::expected-T,E-'>operator bool</a>() const noexcept;
|
|
||||||
|
|
||||||
constexpr bool <a href='doc_expected.md#tl::expected-T,E-'>has_value</a>() const noexcept;
|
|
||||||
|
|
||||||
constexpr const T& <a href='doc_expected.md#tl::expected-T,E-'>value</a>() const &;
|
|
||||||
|
|
||||||
constexpr T& <a href='doc_expected.md#tl::expected-T,E-'>value</a>() &;
|
|
||||||
|
|
||||||
constexpr const T&& <a href='doc_expected.md#tl::expected-T,E-'>value</a>() const &&;
|
|
||||||
|
|
||||||
constexpr T&& <a href='doc_expected.md#tl::expected-T,E-'>value</a>() &&;
|
|
||||||
|
|
||||||
constexpr const E& <a href='doc_expected.md#tl::expected-T,E-'>error</a>() const &;
|
|
||||||
|
|
||||||
constexpr E& <a href='doc_expected.md#tl::expected-T,E-'>error</a>() &;
|
|
||||||
|
|
||||||
constexpr const E&& <a href='doc_expected.md#tl::expected-T,E-'>error</a>() const &&;
|
|
||||||
|
|
||||||
constexpr E&& <a href='doc_expected.md#tl::expected-T,E-'>error</a>() &&;
|
|
||||||
|
|
||||||
template <class U>
|
template <class U>
|
||||||
constexpr T <a href='doc_expected.md#tl::expected-T,E-'>value_or</a>(U&& v) const &;
|
constexpr T <a href='doc_expected.html#tl::expected-T,E-::value_or(U&&)const&'>value_or</a>(U&& v) const &;
|
||||||
|
|
||||||
template <class U>
|
template <class U>
|
||||||
T <a href='doc_expected.md#tl::expected-T,E-'>value_or</a>(U&& v) &&;
|
T <a href='doc_expected.html#tl::expected-T,E-::value_or(U&&)const&'>value_or</a>(U&& v) &&;
|
||||||
};</code></pre>
|
};</code></pre>
|
||||||
|
|
||||||
An `expected<T, E>` object is an object that contains the storage for another object and manages the lifetime of this contained object `T`. Alternatively it could contain the storage for another unexpected object `E`. The contained object may not be initialized after the expected object has been initialized, and may not be destroyed before the expected object has been destroyed. The initialization state of the contained object is tracked by the expected object.
|
An `expected<T, E>` object is an object that contains the storage for another object and manages the lifetime of this contained object `T`. Alternatively it could contain the storage for another unexpected object `E`. The contained object may not be initialized after the expected object has been initialized, and may not be destroyed before the expected object has been destroyed. The initialization state of the contained object is tracked by the expected object.
|
||||||
@@ -362,15 +368,18 @@ An `expected<T, E>` object is an object that contains the storage for another ob
|
|||||||
### Function template `tl::expected::and_then`<a id="tl::expected-T,E-::and_then(F&&)&"></a>
|
### Function template `tl::expected::and_then`<a id="tl::expected-T,E-::and_then(F&&)&"></a>
|
||||||
|
|
||||||
<pre><code class="language-cpp">(1) template <class F>
|
<pre><code class="language-cpp">(1) template <class F>
|
||||||
'hidden' and_then(F&& f) &;
|
constexpr auto and_then(F &&f) &;
|
||||||
|
|
||||||
(2) template <class F>
|
(2) template <class F>
|
||||||
constexpr auto and_then(F &&f) &&;
|
constexpr auto and_then(F &&f) &&;
|
||||||
|
|
||||||
(3) template <class F>
|
(3) template <class F>
|
||||||
constexpr auto and_then(F &&f) const &;</code></pre>
|
constexpr auto and_then(F &&f) const &;
|
||||||
|
|
||||||
Carries out some operation which returns an optional on the stored object if there is one. \\requires `std::invoke(std::forward<F>(f), value())` returns a `std::optional<U>` for some `U`. \\returns Let `U` be the result of `std::invoke(std::forward<F>(f), value())`. Returns a `std::optional<U>`. The return value is empty if `*this` is empty, otherwise the return value of `std::invoke(std::forward<F>(f), value())` is returned. \\group and\_then \\synopsis template \<class F\>\\nconstexpr auto and\_then(F &\&f) &;
|
(4) template <class F>
|
||||||
|
constexpr auto and_then(F &&f) const &&;</code></pre>
|
||||||
|
|
||||||
|
Carries out some operation which returns an expected on the stored object if there is one. \\requires `std::invoke(std::forward<F>(f), value())` returns a `std::expected<U>` for some `U`. \\returns Let `U` be the result of `std::invoke(std::forward<F>(f), value())`. Returns a `std::expected<U>`. The return value is empty if `*this` is empty, otherwise the return value of `std::invoke(std::forward<F>(f), value())` is returned.
|
||||||
|
|
||||||
### Function template `tl::expected::map`<a id="tl::expected-T,E-::map(F&&)&"></a>
|
### Function template `tl::expected::map`<a id="tl::expected-T,E-::map(F&&)&"></a>
|
||||||
|
|
||||||
@@ -378,7 +387,9 @@ Carries out some operation which returns an optional on the stored object if the
|
|||||||
|
|
||||||
(2) template <class F> constexpr auto map(F &&f) &&;
|
(2) template <class F> constexpr auto map(F &&f) &&;
|
||||||
|
|
||||||
(3) template <class F> constexpr auto map(F &&f) const &;</code></pre>
|
(3) template <class F> constexpr auto map(F &&f) const &;
|
||||||
|
|
||||||
|
(4) template <class F> constexpr auto map(F &&f) const &&;</code></pre>
|
||||||
|
|
||||||
Carries out some operation on the stored object if there is one.
|
Carries out some operation on the stored object if there is one.
|
||||||
|
|
||||||
@@ -390,18 +401,99 @@ Carries out some operation on the stored object if there is one.
|
|||||||
|
|
||||||
(2) template <class F> constexpr auto map_error(F &&f) &&;
|
(2) template <class F> constexpr auto map_error(F &&f) &&;
|
||||||
|
|
||||||
(3) template <class F> constexpr auto map_error(F &&f) const &;</code></pre>
|
(3) template <class F> constexpr auto map_error(F &&f) const &;
|
||||||
|
|
||||||
|
(4) template <class F> constexpr auto map_error(F &&f) const &&;</code></pre>
|
||||||
|
|
||||||
Carries out some operation on the stored unexpected object if there is one.
|
Carries out some operation on the stored unexpected object if there is one.
|
||||||
|
|
||||||
*Returns*: Let `U` be the result of `std::invoke(std::forward<F>(f), value())`. Returns a `std::expected<T,U>`. If `*this` has an expected value, the result is `*this`, otherwise an `expected<T,U>` is constructed from `make_unexpected(std::invoke(std::forward<F>(f), value()))` and is returned.
|
*Returns*: Let `U` be the result of `std::invoke(std::forward<F>(f), value())`. Returns a `std::expected<T,U>`. If `*this` has an expected value, the result is `*this`, otherwise an `expected<T,U>` is constructed from `make_unexpected(std::invoke(std::forward<F>(f), value()))` and is returned.
|
||||||
|
|
||||||
|
### Function template `tl::expected::or_else`<a id="tl::expected-T,E-::or_else(F&&)&"></a>
|
||||||
|
|
||||||
|
<pre><code class="language-cpp">(1) template <class F>
|
||||||
|
<a href='doc_expected.html#tl::expected-T,E-'>expected</a> or_else(F&& f) &;</code></pre>
|
||||||
|
|
||||||
|
Calls `f` if the expectd is in the unexpected state
|
||||||
|
|
||||||
|
*Requires*: `std::invoke_result_t<F>` must be void or convertible to `expcted<T,E>`.
|
||||||
|
|
||||||
|
*Effects*: If `*this` has a value, returns `*this`. Otherwise, if `f` returns `void`, calls `std::forward<F>(f)` and returns `std::nullopt`. Otherwise, returns `std::forward<F>(f)()`.
|
||||||
|
|
||||||
### Function template `tl::expected::expected`<a id="tl::expected-T,E-::expected(constunexpected-G-&)"></a>
|
### Function template `tl::expected::expected`<a id="tl::expected-T,E-::expected(constunexpected-G-&)"></a>
|
||||||
|
|
||||||
<pre><code class="language-cpp">(1) EXPLICIT constexpr expected(const unexpected<G> &e);
|
<pre><code class="language-cpp">(1) EXPLICIT constexpr expected(const unexpected<G> &e);
|
||||||
|
|
||||||
(2) EXPLICIT constexpr expected(unexpected<G> &&e);</code></pre>
|
(2) EXPLICIT constexpr expected(unexpected<G> &&e);</code></pre>
|
||||||
|
|
||||||
|
### Operator `tl::expected::operator->`<a id="tl::expected-T,E-::operator--()const"></a>
|
||||||
|
|
||||||
|
<pre><code class="language-cpp">(1) constexpr const T* operator->() const;
|
||||||
|
|
||||||
|
(2) T* operator->();</code></pre>
|
||||||
|
|
||||||
|
*Returns*: a pointer to the stored value
|
||||||
|
|
||||||
|
*Requires*: a value is stored
|
||||||
|
|
||||||
|
### Operator `tl::expected::operator*`<a id="tl::expected-T,E-::operator*()const&"></a>
|
||||||
|
|
||||||
|
<pre><code class="language-cpp">(1) constexpr const T& operator*() const &;
|
||||||
|
|
||||||
|
(2) T& operator*() &;
|
||||||
|
|
||||||
|
(3) constexpr const T&& operator*() const &&;
|
||||||
|
|
||||||
|
(4) T&& operator*() &&;</code></pre>
|
||||||
|
|
||||||
|
*Returns*: the stored value
|
||||||
|
|
||||||
|
*Requires*: a value is stored
|
||||||
|
|
||||||
|
### Function `tl::expected::has_value`<a id="tl::expected-T,E-::has_value()const"></a>
|
||||||
|
|
||||||
|
<pre><code class="language-cpp">(1) constexpr bool has_value() const noexcept;
|
||||||
|
|
||||||
|
(2) constexpr operator bool() const noexcept;</code></pre>
|
||||||
|
|
||||||
|
*Returns*: whether or not the optional has a value
|
||||||
|
|
||||||
|
### Function `tl::expected::value`<a id="tl::expected-T,E-::value()const&"></a>
|
||||||
|
|
||||||
|
<pre><code class="language-cpp">(1) constexpr const T& value() const &;
|
||||||
|
|
||||||
|
(2) T& value() &;
|
||||||
|
|
||||||
|
(3) constexpr const T&& value() const &&;
|
||||||
|
|
||||||
|
(4) T&& value() &&;</code></pre>
|
||||||
|
|
||||||
|
*Returns*: the contained value if there is one, otherwise throws \[bad\_expected\_access\]
|
||||||
|
|
||||||
|
### Function `tl::expected::error`<a id="tl::expected-T,E-::error()const&"></a>
|
||||||
|
|
||||||
|
<pre><code class="language-cpp">(1) constexpr const E& error() const &;
|
||||||
|
|
||||||
|
(2) E& error() &;
|
||||||
|
|
||||||
|
(3) constexpr const E&& error() const &&;
|
||||||
|
|
||||||
|
(4) E&& error() &&;</code></pre>
|
||||||
|
|
||||||
|
*Returns*: the unexpected value
|
||||||
|
|
||||||
|
*Requires*: there is an unexpected value
|
||||||
|
|
||||||
|
### Function template `tl::expected::value_or`<a id="tl::expected-T,E-::value_or(U&&)const&"></a>
|
||||||
|
|
||||||
|
<pre><code class="language-cpp">(1) template <class U>
|
||||||
|
constexpr T value_or(U&& v) const &;
|
||||||
|
|
||||||
|
(2) template <class U>
|
||||||
|
T value_or(U&& v) &&;</code></pre>
|
||||||
|
|
||||||
|
*Returns*: the stored value if there is one, otherwise returns `u`
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
84
expected.hpp
84
expected.hpp
@@ -14,6 +14,9 @@
|
|||||||
#ifndef TL_EXPECTED_HPP
|
#ifndef TL_EXPECTED_HPP
|
||||||
#define TL_EXPECTED_HPP
|
#define TL_EXPECTED_HPP
|
||||||
|
|
||||||
|
#define TL_EXPECTED_VERSION_MAJOR 0
|
||||||
|
#define TL_EXPECTED_VERSION_MINOR 1
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -21,38 +24,49 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#if (defined(_MSC_VER) && _MSC_VER == 1900)
|
#if (defined(_MSC_VER) && _MSC_VER == 1900)
|
||||||
|
/// \exclude
|
||||||
#define TL_EXPECTED_MSVC2015
|
#define TL_EXPECTED_MSVC2015
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9)
|
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9)
|
||||||
|
/// \exclude
|
||||||
#define TL_EXPECTED_GCC49
|
#define TL_EXPECTED_GCC49
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4)
|
#if (defined(__GNUC__) && __GNUC__ == 5 && __GNUC_MINOR__ <= 4)
|
||||||
|
/// \exclude
|
||||||
#define TL_EXPECTED_GCC54
|
#define TL_EXPECTED_GCC54
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
|
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
|
||||||
!defined(__clang__))
|
!defined(__clang__))
|
||||||
// GCC < 5 doesn't support overloading on const&& for member functions
|
// GCC < 5 doesn't support overloading on const&& for member functions
|
||||||
|
/// \exclude
|
||||||
#define TL_EXPECTED_NO_CONSTRR
|
#define TL_EXPECTED_NO_CONSTRR
|
||||||
|
|
||||||
// GCC < 5 doesn't support some standard C++11 type traits
|
// GCC < 5 doesn't support some standard C++11 type traits
|
||||||
|
/// \exclude
|
||||||
#define IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
|
#define IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
|
||||||
std::has_trivial_copy_constructor<T>::value
|
std::has_trivial_copy_constructor<T>::value
|
||||||
|
/// \exclude
|
||||||
#define IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::has_trivial_copy_assign<T>::value
|
#define IS_TRIVIALLY_COPY_ASSIGNABLE(T) std::has_trivial_copy_assign<T>::value
|
||||||
|
|
||||||
// This one will be different for GCC 5.7 if it's ever supported
|
// This one will be different for GCC 5.7 if it's ever supported
|
||||||
|
/// \exclude
|
||||||
#define IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
|
#define IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
|
||||||
#else
|
#else
|
||||||
|
/// \exclude
|
||||||
#define IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
|
#define IS_TRIVIALLY_COPY_CONSTRUCTIBLE(T) \
|
||||||
std::is_trivially_copy_constructible<T>::value
|
std::is_trivially_copy_constructible<T>::value
|
||||||
|
/// \exclude
|
||||||
#define IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
|
#define IS_TRIVIALLY_COPY_ASSIGNABLE(T) \
|
||||||
std::is_trivially_copy_assignable<T>::value
|
std::is_trivially_copy_assignable<T>::value
|
||||||
|
/// \exclude
|
||||||
#define IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
|
#define IS_TRIVIALLY_DESTRUCTIBLE(T) std::is_trivially_destructible<T>::value
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __cplusplus > 201103L
|
#if __cplusplus > 201103L
|
||||||
|
/// \exclude
|
||||||
#define TL_EXPECTED_CXX14
|
#define TL_EXPECTED_CXX14
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -69,7 +83,8 @@
|
|||||||
namespace tl {
|
namespace tl {
|
||||||
template <class T, class E> class expected;
|
template <class T, class E> class expected;
|
||||||
|
|
||||||
#ifndef TL_OPTIONAL_EXPECTED_MUTEX
|
#ifndef TL_MONOSTATE_INPLACE_MUTEX
|
||||||
|
#define TL_MONOSTATE_INPLACE_MUTEX
|
||||||
/// \brief Used to represent an expected with no data
|
/// \brief Used to represent an expected with no data
|
||||||
class monostate {};
|
class monostate {};
|
||||||
|
|
||||||
@@ -156,7 +171,8 @@ static constexpr unexpect_t unexpect{};
|
|||||||
|
|
||||||
/// \exclude
|
/// \exclude
|
||||||
namespace detail {
|
namespace detail {
|
||||||
#ifndef TL_OPTIONAL_EXPECTED_MUTEX
|
#ifndef TL_TRAITS_MUTEX
|
||||||
|
#define TL_TRAITS_MUTEX
|
||||||
// C++14-style aliases for brevity
|
// C++14-style aliases for brevity
|
||||||
template <class T> using remove_const_t = typename std::remove_const<T>::type;
|
template <class T> using remove_const_t = typename std::remove_const<T>::type;
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -240,6 +256,9 @@ using expected_enable_from_other = detail::enable_if_t<
|
|||||||
|
|
||||||
/// \exclude
|
/// \exclude
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
struct no_init_t{};
|
||||||
|
static constexpr no_init_t no_init{};
|
||||||
|
|
||||||
// Implements the storage of the values, and ensures that the destructor is
|
// Implements the storage of the values, and ensures that the destructor is
|
||||||
// trivial if it can be.
|
// trivial if it can be.
|
||||||
//
|
//
|
||||||
@@ -250,6 +269,7 @@ template <class T, class E, bool = std::is_trivially_destructible<T>::value,
|
|||||||
bool = std::is_trivially_destructible<E>::value>
|
bool = std::is_trivially_destructible<E>::value>
|
||||||
struct expected_storage_base {
|
struct expected_storage_base {
|
||||||
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
||||||
|
constexpr expected_storage_base(no_init_t) : m_has_val(false) {}
|
||||||
|
|
||||||
template <class... Args,
|
template <class... Args,
|
||||||
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
|
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
|
||||||
@@ -295,6 +315,7 @@ struct expected_storage_base {
|
|||||||
// so the destructor of the `expected` can be trivial.
|
// so the destructor of the `expected` can be trivial.
|
||||||
template <class T, class E> struct expected_storage_base<T, E, true, true> {
|
template <class T, class E> struct expected_storage_base<T, E, true, true> {
|
||||||
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
||||||
|
constexpr expected_storage_base(no_init_t) : m_has_val(false) {}
|
||||||
|
|
||||||
template <class... Args,
|
template <class... Args,
|
||||||
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
|
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
|
||||||
@@ -333,6 +354,7 @@ template <class T, class E> struct expected_storage_base<T, E, true, true> {
|
|||||||
// T is trivial, E is not.
|
// T is trivial, E is not.
|
||||||
template <class T, class E> struct expected_storage_base<T, E, true, false> {
|
template <class T, class E> struct expected_storage_base<T, E, true, false> {
|
||||||
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
||||||
|
constexpr expected_storage_base(no_init_t) : m_has_val(false) {}
|
||||||
|
|
||||||
template <class... Args,
|
template <class... Args,
|
||||||
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
|
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
|
||||||
@@ -376,6 +398,7 @@ template <class T, class E> struct expected_storage_base<T, E, true, false> {
|
|||||||
// E is trivial, T is not.
|
// E is trivial, T is not.
|
||||||
template <class T, class E> struct expected_storage_base<T, E, false, true> {
|
template <class T, class E> struct expected_storage_base<T, E, false, true> {
|
||||||
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
constexpr expected_storage_base() : m_val(T{}), m_has_val(true) {}
|
||||||
|
constexpr expected_storage_base(no_init_t) : m_has_val(false) {}
|
||||||
|
|
||||||
template <class... Args,
|
template <class... Args,
|
||||||
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
|
detail::enable_if_t<std::is_constructible<T, Args &&...>::value> * =
|
||||||
@@ -579,7 +602,8 @@ struct expected_copy_base<T, E, false> : expected_operations_base<T, E> {
|
|||||||
using expected_operations_base<T, E>::expected_operations_base;
|
using expected_operations_base<T, E>::expected_operations_base;
|
||||||
|
|
||||||
expected_copy_base() = default;
|
expected_copy_base() = default;
|
||||||
expected_copy_base(const expected_copy_base &rhs) {
|
expected_copy_base(const expected_copy_base &rhs) :
|
||||||
|
expected_operations_base<T,E>(no_init) {
|
||||||
if (rhs.has_value()) {
|
if (rhs.has_value()) {
|
||||||
this->construct(rhs.get());
|
this->construct(rhs.get());
|
||||||
} else {
|
} else {
|
||||||
@@ -614,7 +638,8 @@ struct expected_move_base<T, E, false> : expected_copy_base<T, E> {
|
|||||||
expected_move_base(const expected_move_base &rhs) = default;
|
expected_move_base(const expected_move_base &rhs) = default;
|
||||||
|
|
||||||
expected_move_base(expected_move_base &&rhs) noexcept(
|
expected_move_base(expected_move_base &&rhs) noexcept(
|
||||||
std::is_nothrow_move_constructible<T>::value) {
|
std::is_nothrow_move_constructible<T>::value) :
|
||||||
|
expected_copy_base<T,E>(no_init) {
|
||||||
if (rhs.has_value()) {
|
if (rhs.has_value()) {
|
||||||
this->construct(std::move(rhs.get()));
|
this->construct(std::move(rhs.get()));
|
||||||
} else {
|
} else {
|
||||||
@@ -900,8 +925,8 @@ public:
|
|||||||
/// of `std::invoke(std::forward<F>(f), value())`. Returns a
|
/// of `std::invoke(std::forward<F>(f), value())`. Returns a
|
||||||
/// `std::expected<U>`. The return value is empty if `*this` is empty,
|
/// `std::expected<U>`. The return value is empty if `*this` is empty,
|
||||||
/// otherwise the return value of `std::invoke(std::forward<F>(f), value())`
|
/// otherwise the return value of `std::invoke(std::forward<F>(f), value())`
|
||||||
/// is returned. \group and_then \synopsis template <class F>\nconstexpr auto
|
/// is returned.
|
||||||
/// and_then(F &&f) &;
|
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
|
||||||
template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & {
|
template <class F> TL_EXPECTED_11_CONSTEXPR auto and_then(F &&f) & {
|
||||||
using result = detail::invoke_result_t<F, T &>;
|
using result = detail::invoke_result_t<F, T &>;
|
||||||
static_assert(detail::is_expected<result>::value,
|
static_assert(detail::is_expected<result>::value,
|
||||||
@@ -954,8 +979,8 @@ public:
|
|||||||
/// of `std::invoke(std::forward<F>(f), value())`. Returns a
|
/// of `std::invoke(std::forward<F>(f), value())`. Returns a
|
||||||
/// `std::expected<U>`. The return value is empty if `*this` is empty,
|
/// `std::expected<U>`. The return value is empty if `*this` is empty,
|
||||||
/// otherwise the return value of `std::invoke(std::forward<F>(f), value())`
|
/// otherwise the return value of `std::invoke(std::forward<F>(f), value())`
|
||||||
/// is returned. \group and_then \synopsis template <class F>\nconstexpr auto
|
/// is returned.
|
||||||
/// and_then(F &&f) &;
|
/// \synopsis template <class F>\nconstexpr auto and_then(F &&f) &;
|
||||||
template <class F>
|
template <class F>
|
||||||
TL_EXPECTED_11_CONSTEXPR detail::invoke_result_t<F, T &> and_then(F &&f) & {
|
TL_EXPECTED_11_CONSTEXPR detail::invoke_result_t<F, T &> and_then(F &&f) & {
|
||||||
using result = detail::invoke_result_t<F, T &>;
|
using result = detail::invoke_result_t<F, T &>;
|
||||||
@@ -1516,44 +1541,77 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \returns a pointer to the stored value
|
||||||
|
/// \requires a value is stored
|
||||||
|
/// \group pointer
|
||||||
constexpr const T *operator->() const { return valptr(); }
|
constexpr const T *operator->() const { return valptr(); }
|
||||||
|
/// \group pointer
|
||||||
TL_EXPECTED_11_CONSTEXPR T *operator->() { return valptr(); }
|
TL_EXPECTED_11_CONSTEXPR T *operator->() { return valptr(); }
|
||||||
|
|
||||||
|
/// \returns the stored value
|
||||||
|
/// \requires a value is stored
|
||||||
|
/// \group deref
|
||||||
constexpr const T &operator*() const & { return val(); }
|
constexpr const T &operator*() const & { return val(); }
|
||||||
|
/// \group deref
|
||||||
TL_EXPECTED_11_CONSTEXPR T &operator*() & { return val(); }
|
TL_EXPECTED_11_CONSTEXPR T &operator*() & { return val(); }
|
||||||
|
/// \group deref
|
||||||
constexpr const T &&operator*() const && { return std::move(val()); }
|
constexpr const T &&operator*() const && { return std::move(val()); }
|
||||||
|
/// \group deref
|
||||||
TL_EXPECTED_11_CONSTEXPR T &&operator*() && { return std::move(val()); }
|
TL_EXPECTED_11_CONSTEXPR T &&operator*() && { return std::move(val()); }
|
||||||
constexpr explicit operator bool() const noexcept { return this->m_has_val; }
|
|
||||||
|
/// \returns whether or not the optional has a value
|
||||||
|
/// \group has_value
|
||||||
constexpr bool has_value() const noexcept { return this->m_has_val; }
|
constexpr bool has_value() const noexcept { return this->m_has_val; }
|
||||||
|
/// \group has_value
|
||||||
|
constexpr explicit operator bool() const noexcept { return this->m_has_val; }
|
||||||
|
|
||||||
|
|
||||||
|
/// \returns the contained value if there is one, otherwise throws [bad_expected_access]
|
||||||
|
/// \group value
|
||||||
constexpr const T &value() const & {
|
constexpr const T &value() const & {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
throw bad_expected_access<E>(err());
|
throw bad_expected_access<E>(err().value());
|
||||||
return val();
|
return val();
|
||||||
}
|
}
|
||||||
|
/// \group value
|
||||||
TL_EXPECTED_11_CONSTEXPR T &value() & {
|
TL_EXPECTED_11_CONSTEXPR T &value() & {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
throw bad_expected_access<E>(err());
|
throw bad_expected_access<E>(err().value());
|
||||||
return val();
|
return val();
|
||||||
}
|
}
|
||||||
|
/// \group value
|
||||||
constexpr const T &&value() const && {
|
constexpr const T &&value() const && {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
throw bad_expected_access<E>(err());
|
throw bad_expected_access<E>(err().value());
|
||||||
return std::move(val());
|
return std::move(val());
|
||||||
}
|
}
|
||||||
|
/// \group value
|
||||||
TL_EXPECTED_11_CONSTEXPR T &&value() && {
|
TL_EXPECTED_11_CONSTEXPR T &&value() && {
|
||||||
if (!has_value())
|
if (!has_value())
|
||||||
throw bad_expected_access<E>(err());
|
throw bad_expected_access<E>(err().value());
|
||||||
return std::move(val());
|
return std::move(val());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \returns the unexpected value
|
||||||
|
/// \requires there is an unexpected value
|
||||||
|
/// \group error
|
||||||
constexpr const E &error() const & { return err().value(); }
|
constexpr const E &error() const & { return err().value(); }
|
||||||
|
/// \group error
|
||||||
TL_EXPECTED_11_CONSTEXPR E &error() & { return err().value(); }
|
TL_EXPECTED_11_CONSTEXPR E &error() & { return err().value(); }
|
||||||
|
/// \group error
|
||||||
constexpr const E &&error() const && { return std::move(err().value()); }
|
constexpr const E &&error() const && { return std::move(err().value()); }
|
||||||
|
/// \group error
|
||||||
TL_EXPECTED_11_CONSTEXPR E &&error() && { return std::move(err().value()); }
|
TL_EXPECTED_11_CONSTEXPR E &&error() && { return std::move(err().value()); }
|
||||||
|
|
||||||
|
/// \returns the stored value if there is one, otherwise returns `u`
|
||||||
|
/// \group value_or
|
||||||
template <class U> constexpr T value_or(U &&v) const & {
|
template <class U> constexpr T value_or(U &&v) const & {
|
||||||
static_assert(std::is_copy_constructible<T>::value &&
|
static_assert(std::is_copy_constructible<T>::value &&
|
||||||
std::is_convertible<U &&, T>::value,
|
std::is_convertible<U &&, T>::value,
|
||||||
"T must be copy-constructible and convertible to from U&&");
|
"T must be copy-constructible and convertible to from U&&");
|
||||||
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
|
return bool(*this) ? **this : static_cast<T>(std::forward<U>(v));
|
||||||
}
|
}
|
||||||
|
/// \group value_or
|
||||||
template <class U> TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) && {
|
template <class U> TL_EXPECTED_11_CONSTEXPR T value_or(U &&v) && {
|
||||||
static_assert(std::is_move_constructible<T>::value &&
|
static_assert(std::is_move_constructible<T>::value &&
|
||||||
std::is_convertible<U &&, T>::value,
|
std::is_convertible<U &&, T>::value,
|
||||||
|
@@ -1,2 +1,3 @@
|
|||||||
[output]
|
[output]
|
||||||
format=commonmark
|
format=commonmark
|
||||||
|
link_extension=html
|
||||||
|
125
tests/bases.cpp
Normal file
125
tests/bases.cpp
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
#include "catch.hpp"
|
||||||
|
#include "expected.hpp"
|
||||||
|
|
||||||
|
// Old versions of GCC don't have the correct trait names. Could fix them up if needs be.
|
||||||
|
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 9 && \
|
||||||
|
!defined(__clang__))
|
||||||
|
// nothing for now
|
||||||
|
#else
|
||||||
|
TEST_CASE("Triviality", "[bases.triviality]") {
|
||||||
|
REQUIRE(std::is_trivially_copy_constructible<tl::expected<int,int>>::value);
|
||||||
|
REQUIRE(std::is_trivially_copy_assignable<tl::expected<int,int>>::value);
|
||||||
|
REQUIRE(std::is_trivially_move_constructible<tl::expected<int,int>>::value);
|
||||||
|
REQUIRE(std::is_trivially_move_assignable<tl::expected<int,int>>::value);
|
||||||
|
REQUIRE(std::is_trivially_destructible<tl::expected<int,int>>::value);
|
||||||
|
|
||||||
|
{
|
||||||
|
struct T {
|
||||||
|
T(const T&) = default;
|
||||||
|
T(T&&) = default;
|
||||||
|
T& operator=(const T&) = default;
|
||||||
|
T& operator=(T&&) = default;
|
||||||
|
~T() = default;
|
||||||
|
};
|
||||||
|
REQUIRE(std::is_trivially_copy_constructible<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(std::is_trivially_copy_assignable<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(std::is_trivially_move_constructible<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(std::is_trivially_move_assignable<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(std::is_trivially_destructible<tl::expected<T,int>>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
struct T {
|
||||||
|
T(const T&){}
|
||||||
|
T(T&&) {};
|
||||||
|
T& operator=(const T&) {}
|
||||||
|
T& operator=(T&&) {};
|
||||||
|
~T(){}
|
||||||
|
};
|
||||||
|
REQUIRE(!std::is_trivially_copy_constructible<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(!std::is_trivially_copy_assignable<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(!std::is_trivially_move_constructible<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(!std::is_trivially_move_assignable<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(!std::is_trivially_destructible<tl::expected<T,int>>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Deletion", "[bases.deletion]") {
|
||||||
|
REQUIRE(std::is_copy_constructible<tl::expected<int,int>>::value);
|
||||||
|
REQUIRE(std::is_copy_assignable<tl::expected<int,int>>::value);
|
||||||
|
REQUIRE(std::is_move_constructible<tl::expected<int,int>>::value);
|
||||||
|
REQUIRE(std::is_move_assignable<tl::expected<int,int>>::value);
|
||||||
|
REQUIRE(std::is_destructible<tl::expected<int,int>>::value);
|
||||||
|
|
||||||
|
{
|
||||||
|
struct T {
|
||||||
|
T()=default;
|
||||||
|
};
|
||||||
|
REQUIRE(std::is_default_constructible<tl::expected<T,int>>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
struct T {
|
||||||
|
T(int);
|
||||||
|
};
|
||||||
|
REQUIRE(!std::is_default_constructible<tl::expected<T,int>>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
struct T {
|
||||||
|
T(const T&) = default;
|
||||||
|
T(T&&) = default;
|
||||||
|
T& operator=(const T&) = default;
|
||||||
|
T& operator=(T&&) = default;
|
||||||
|
~T() = default;
|
||||||
|
};
|
||||||
|
REQUIRE(std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(std::is_move_constructible<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(std::is_move_assignable<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(std::is_destructible<tl::expected<T,int>>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
struct T {
|
||||||
|
T(const T&)=delete;
|
||||||
|
T(T&&)=delete;
|
||||||
|
T& operator=(const T&)=delete;
|
||||||
|
T& operator=(T&&)=delete;
|
||||||
|
};
|
||||||
|
REQUIRE(!std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(!std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(!std::is_move_constructible<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(!std::is_move_assignable<tl::expected<T,int>>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
struct T {
|
||||||
|
T(const T&)=delete;
|
||||||
|
T(T&&)=default;
|
||||||
|
T& operator=(const T&)=delete;
|
||||||
|
T& operator=(T&&)=default;
|
||||||
|
};
|
||||||
|
REQUIRE(!std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(!std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(std::is_move_constructible<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(std::is_move_assignable<tl::expected<T,int>>::value);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
struct T {
|
||||||
|
T(const T&)=default;
|
||||||
|
T(T&&)=delete;
|
||||||
|
T& operator=(const T&)=default;
|
||||||
|
T& operator=(T&&)=delete;
|
||||||
|
};
|
||||||
|
REQUIRE(std::is_copy_constructible<tl::expected<T,int>>::value);
|
||||||
|
REQUIRE(std::is_copy_assignable<tl::expected<T,int>>::value);
|
||||||
|
//TODO see why this fails
|
||||||
|
//REQUIRE(!std::is_move_constructible<tl::expected<T,int>>::value);
|
||||||
|
//REQUIRE(!std::is_move_assignable<tl::expected<T,int>>::value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
6
tests/constexpr.cpp
Normal file
6
tests/constexpr.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "catch.hpp"
|
||||||
|
#include "expected.hpp"
|
||||||
|
|
||||||
|
TEST_CASE("Constexpr", "[constexpr]") {
|
||||||
|
//TODO
|
||||||
|
}
|
@@ -18,6 +18,18 @@ TEST_CASE("Constructors", "[constructors]") {
|
|||||||
REQUIRE(e == 0);
|
REQUIRE(e == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::expected<int,int> e = tl::make_unexpected(0);
|
||||||
|
REQUIRE(!e);
|
||||||
|
REQUIRE(e.error() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::expected<int,int> e (tl::unexpect, 0);
|
||||||
|
REQUIRE(!e);
|
||||||
|
REQUIRE(e.error() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
tl::expected<int,int> e (tl::in_place, 42);
|
tl::expected<int,int> e (tl::in_place, 42);
|
||||||
REQUIRE(e);
|
REQUIRE(e);
|
||||||
|
@@ -1,4 +1,50 @@
|
|||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
#include "expected.hpp"
|
#include "expected.hpp"
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
struct takes_init_and_variadic {
|
||||||
|
std::vector<int> v;
|
||||||
|
std::tuple<int, int> t;
|
||||||
|
template <class... Args>
|
||||||
|
takes_init_and_variadic(std::initializer_list<int> l, Args &&... args)
|
||||||
|
: v(l), t(std::forward<Args>(args)...) {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE("Emplace", "[emplace]") {
|
TEST_CASE("Emplace", "[emplace]") {
|
||||||
|
{
|
||||||
|
tl::expected<std::unique_ptr<int>,int> e;
|
||||||
|
e.emplace(new int{42});
|
||||||
|
REQUIRE(e);
|
||||||
|
REQUIRE(**e == 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::expected<std::vector<int>,int> e;
|
||||||
|
e.emplace({0,1});
|
||||||
|
REQUIRE(e);
|
||||||
|
REQUIRE((*e)[0] == 0);
|
||||||
|
REQUIRE((*e)[1] == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::expected<std::tuple<int,int>,int> e;
|
||||||
|
e.emplace(2,3);
|
||||||
|
REQUIRE(e);
|
||||||
|
REQUIRE(std::get<0>(*e) == 2);
|
||||||
|
REQUIRE(std::get<1>(*e) == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
tl::expected<takes_init_and_variadic,int> e = tl::make_unexpected(0);
|
||||||
|
e.emplace({0,1}, 2, 3);
|
||||||
|
REQUIRE(e);
|
||||||
|
REQUIRE(e->v[0] == 0);
|
||||||
|
REQUIRE(e->v[1] == 1);
|
||||||
|
REQUIRE(std::get<0>(e->t) == 2);
|
||||||
|
REQUIRE(std::get<1>(e->t) == 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
6
tests/noexcept.cpp
Normal file
6
tests/noexcept.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "catch.hpp"
|
||||||
|
#include "expected.hpp"
|
||||||
|
|
||||||
|
TEST_CASE("Noexcept", "[noexcept]") {
|
||||||
|
//TODO
|
||||||
|
}
|
36
tests/observers.cpp
Normal file
36
tests/observers.cpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
#include "catch.hpp"
|
||||||
|
#include "expected.hpp"
|
||||||
|
|
||||||
|
struct move_detector {
|
||||||
|
move_detector() = default;
|
||||||
|
move_detector(move_detector &&rhs) { rhs.been_moved = true; }
|
||||||
|
bool been_moved = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_CASE("Observers", "[observers]") {
|
||||||
|
tl::expected<int,int> o1 = 42;
|
||||||
|
tl::expected<int,int> o2 {tl::unexpect, 0};
|
||||||
|
const tl::expected<int,int> o3 = 42;
|
||||||
|
|
||||||
|
REQUIRE(*o1 == 42);
|
||||||
|
REQUIRE(*o1 == o1.value());
|
||||||
|
REQUIRE(o2.value_or(42) == 42);
|
||||||
|
REQUIRE(o2.error() == 0);
|
||||||
|
REQUIRE(o3.value() == 42);
|
||||||
|
auto success = std::is_same<decltype(o1.value()), int &>::value;
|
||||||
|
REQUIRE(success);
|
||||||
|
success = std::is_same<decltype(o3.value()), const int &>::value;
|
||||||
|
REQUIRE(success);
|
||||||
|
success = std::is_same<decltype(std::move(o1).value()), int &&>::value;
|
||||||
|
REQUIRE(success);
|
||||||
|
|
||||||
|
#ifndef TL_EXPECTED_NO_CONSTRR
|
||||||
|
success = std::is_same<decltype(std::move(o3).value()), const int &&>::value;
|
||||||
|
REQUIRE(success);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tl::expected<move_detector,int> o4{tl::in_place};
|
||||||
|
move_detector o5 = std::move(o4).value();
|
||||||
|
REQUIRE(o4->been_moved);
|
||||||
|
REQUIRE(!o5.been_moved);
|
||||||
|
}
|
6
tests/relops.cpp
Normal file
6
tests/relops.cpp
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#include "catch.hpp"
|
||||||
|
#include "expected.hpp"
|
||||||
|
|
||||||
|
TEST_CASE("Relational operators", "[relops]") {
|
||||||
|
//TODO
|
||||||
|
}
|
Reference in New Issue
Block a user