C++11/14/17 std::optional with functional-style extensions and reference support
Single header implementation of std::optional
with functional-style extensions and support for references.
std::optional
is the preferred way to represent an object which may or may not have a value. Unfortunately, chaining together many computations which may or may not produce a value can be verbose, as empty-checking code will be mixed in with the actual programming logic. This implementation provides a number of utilities to make coding with optional
cleaner.
For example, instead of writing this code:
std::optional<image> get_cute_cat (const image& img) {
auto cropped = crop_to_cat(img);
if (!cropped) {
return std::nullopt;
}
auto with_tie = add_bow_tie(*cropped);
if (!with_tie) {
return std::nullopt;
}
auto with_sparkles = make_eyes_sparkle(*with_tie);
if (!with_sparkles) {
return std::nullopt;
}
return add_rainbow(make_smaller(*with_sparkles));
}
You can do this:
tl::optional<image> 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);
}
The interface is the same as std::optional
, 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::optional<std::size_t> s = opt_string.map(&std::string::size);
and_then
: likemap
, but for operations which return atl::optional
.tl::optional<int> stoi (const std::string& s);
tl::optional<int> i = opt_string.and_then(stoi);
or_else
: calls some function if there is no value stored.opt.or_else([] { throw std::runtime_error{"oh no"}; });
map_or
: carries out amap
if there is a value, otherwise returns a default value.tl::optional<std::size_t> s = opt_string.map_or(&std::string::size, 0);
map_or_else
: carries out amap
if there is a value, otherwise returns the result of a given default function.std::size_t get_default();
tl::optional<std::size_t> s = opt_string.map_or_else(&std::string::size, get_default);
conjunction
: returns the argument if a value is stored in the optional, otherwise an empty optional.tl::make_optional(42).conjunction(13); //13
tl::optional<int>{}.conjunction(13); //empty
disjunction
: returns the argument if the optional is empty, otherwise the current value.tl::make_optional(42).disjunction(13); //42
tl::optional<int>{}.disjunction(13); //13
take
: returns the current value, leaving the optional empty.opt_string.take().map(&std::string::size); //opt_string now empty;
In addition to those member functions, optional references are also supported:
int i = 42;
tl::optional<int&> o = i;
*o == 42; //true
i = 12;
*o == 12; //true
&*o == &i; //true
Assignment has rebind semantics rather than assign-through semantics:
int j = 8;
o = j;
&*o == &j; //true
Compiler support
Tested on:
- Linux
- clang 6.0.1
- clang 5.0.2
- clang 4.0.1
- clang 3.9
- clang 3.8
- clang 3.7
- clang 3.6
- clang 3.5
- g++ 8.0.1
- g++ 7.3
- g++ 6.4
- g++ 5.5
- g++ 4.9
- g++ 4.8
- Windows
- MSVC 2015
- MSVC 2017
Standards Proposal
This library also serves as an implementation of WG21 standards paper P0798R0: Monadic operations for std::optional. This paper proposes adding map
, and_then
, and or_else
to std::optional
.
To the extent possible under law, Sy Brand has waived all copyright and related or neighboring rights to the optional
library. This work is published from: United Kingdom.
version | 1.1.0+1 |
---|---|
license | CC0-1.0 UniversalCreative Commons Zero v1.0 Universal |
repository | https://pkg.cppget.org/1/stable |
download | tl-optional-1.1.0+1.tar.gz |
sha256 | d272e8b790ac502baee6f6901fb510cd779d144bfdb44de25ffc27ae6e7f35c8 |
project | tl |
---|---|
doc-url | tl.tartanllama.xyz/en/latest/ |
package-url | github.com/build2-packaging/build2-tl |
package-email | wmbat-dev@protonmail.com |
Requires (1)
c++ >= 11 |
Tests
tl-optional-tests == 1.1.0 |
Builds
toolchain | public-0.16.0 |
---|---|
target | x86_64-apple-darwin22.5.0 |
tgt config | macos_13-clang_15.0-static_O3 |
timestamp | 2024-05-14 15:18:25 UTC (16:12:45 hours ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-apple-darwin22.5.0 |
tgt config | macos_13-clang_15.0-O3 |
timestamp | 2024-05-14 15:17:45 UTC (16:13:25 hours ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-apple-darwin22.5.0 |
tgt config | macos_13-clang_15.0 |
timestamp | 2024-05-14 15:17:04 UTC (16:14:06 hours ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_fedora_38-gcc_13-bindist |
timestamp | 2024-05-14 06:15:38 UTC (01 01:15:32 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-gcc_13-static_O3 |
timestamp | 2024-05-14 05:28:47 UTC (01 02:02:23 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-gcc_13-ndebug_O3 |
timestamp | 2024-05-14 05:27:45 UTC (01 02:03:25 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-gcc_13-O3 |
timestamp | 2024-05-14 05:22:01 UTC (01 02:09:09 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-gcc_13 |
timestamp | 2024-05-14 05:17:02 UTC (01 02:14:08 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_fedora_37-gcc_12.2-bindist |
timestamp | 2024-05-14 05:12:52 UTC (01 02:18:18 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-apple-darwin22.5.0 |
tgt config | macos_13-gcc_13_homebrew-static_O3 |
timestamp | 2024-05-13 23:45:19 UTC (01 07:45:51 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-apple-darwin22.5.0 |
tgt config | macos_13-gcc_13_homebrew-O3 |
timestamp | 2024-05-13 23:40:58 UTC (01 07:50:12 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-apple-darwin22.5.0 |
tgt config | macos_13-gcc_13_homebrew |
timestamp | 2024-05-13 23:40:20 UTC (01 07:50:50 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-w64-mingw32 |
tgt config | windows_10-gcc_12.2_mingw_w64-O2 |
timestamp | 2024-05-13 22:29:53 UTC (01 09:01:17 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-w64-mingw32 |
tgt config | windows_10-gcc_12.2_mingw_w64 |
timestamp | 2024-05-13 22:26:06 UTC (01 09:05:04 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-w64-mingw32 |
tgt config | windows_10-gcc_12.2_mingw_w64-static_O2 |
timestamp | 2024-05-13 22:21:29 UTC (01 09:09:41 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_11-gcc_12 |
timestamp | 2024-05-13 21:47:25 UTC (01 09:43:45 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-gcc_12-bindist |
timestamp | 2024-05-13 20:57:08 UTC (01 10:34:02 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-gcc_13.1-static_O3 |
timestamp | 2024-05-13 20:47:59 UTC (01 10:43:11 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-gcc_13.1-ndebug_O3 |
timestamp | 2024-05-13 20:46:46 UTC (01 10:44:24 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-gcc_13.1-O3 |
timestamp | 2024-05-13 20:45:33 UTC (01 10:45:37 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-gcc_13.1 |
timestamp | 2024-05-13 20:42:27 UTC (01 10:48:43 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_11-gcc_12.1 |
timestamp | 2024-05-13 20:37:37 UTC (01 10:53:33 days ago) |
result | success | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_16_libc++-O3 |
timestamp | 2024-05-13 13:32:13 UTC (01 17:58:57 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_16_libc++-static_O3 |
timestamp | 2024-05-13 13:32:01 UTC (01 17:59:09 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_16_libc++ |
timestamp | 2024-05-13 13:31:40 UTC (01 17:59:30 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-apple-darwin22.5.0 |
tgt config | macos_13-clang_14.0-static_O3 |
timestamp | 2024-05-13 13:31:12 UTC (01 17:59:58 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_16-static_O3 |
timestamp | 2024-05-13 13:31:07 UTC (01 18:00:03 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_16-O3 |
timestamp | 2024-05-13 13:30:55 UTC (01 18:00:15 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-apple-darwin22.5.0 |
tgt config | macos_13-clang_14.0-O3 |
timestamp | 2024-05-13 13:30:35 UTC (01 18:00:35 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-apple-darwin22.5.0 |
tgt config | macos_13-clang_14.0 |
timestamp | 2024-05-13 13:29:56 UTC (01 18:01:14 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_16 |
timestamp | 2024-05-13 13:29:53 UTC (01 18:01:18 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-clang_16.0_llvm_msvc_17.6-O2 |
timestamp | 2024-05-13 12:01:10 UTC (01 19:30:00 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-clang_16.0_llvm_msvc_17.6-static_O2 |
timestamp | 2024-05-13 12:00:12 UTC (01 19:30:58 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-clang_16.0_llvm_msvc_17.6 |
timestamp | 2024-05-13 11:59:49 UTC (01 19:31:21 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_16.0-O3 |
timestamp | 2024-05-13 11:55:57 UTC (01 19:35:13 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_16.0_libc++-static_O3 |
timestamp | 2024-05-13 11:55:19 UTC (01 19:35:51 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_16.0_libc++-O3 |
timestamp | 2024-05-13 11:55:11 UTC (01 19:35:59 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_16.0-static_O3 |
timestamp | 2024-05-13 11:54:48 UTC (01 19:36:22 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_16.0 |
timestamp | 2024-05-13 11:54:45 UTC (01 19:36:25 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_16.0_libc++ |
timestamp | 2024-05-13 11:52:47 UTC (01 19:38:23 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_15 |
timestamp | 2024-05-13 11:50:02 UTC (01 19:41:08 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | aarch64-linux-gnu |
tgt config | linux_debian_12-clang_15_libc++ |
timestamp | 2024-05-13 11:49:42 UTC (01 19:41:28 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-clang_15.0_msvc_msvc_17.6 |
timestamp | 2024-05-13 11:43:21 UTC (01 19:47:49 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_15.0 |
timestamp | 2024-05-13 11:38:41 UTC (01 19:52:30 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-linux-gnu |
tgt config | linux_debian_12-clang_15.0_libc++ |
timestamp | 2024-05-13 11:38:15 UTC (01 19:52:55 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-msvc_17.6-static_O2 |
timestamp | 2024-05-13 11:37:58 UTC (01 19:53:12 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-msvc_17.6-O2 |
timestamp | 2024-05-13 11:37:46 UTC (01 19:53:24 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-msvc_17.6 |
timestamp | 2024-05-13 11:37:18 UTC (01 19:53:52 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-freebsd13.2 |
tgt config | freebsd_13-clang_14.0-static_O3 |
timestamp | 2024-05-13 11:34:30 UTC (01 19:56:40 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-freebsd13.2 |
tgt config | freebsd_13-clang_14.0-O3 |
timestamp | 2024-05-13 11:33:54 UTC (01 19:57:16 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-freebsd13.2 |
tgt config | freebsd_13-clang_14.0 |
timestamp | 2024-05-13 11:32:47 UTC (01 19:58:23 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-microsoft-win32-msvc14.3 |
tgt config | windows_10-msvc_17.5 |
timestamp | 2024-05-13 11:32:45 UTC (01 19:58:25 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |
toolchain | public-0.16.0 |
---|---|
target | x86_64-freebsd12.4 |
tgt config | freebsd_12-clang_13.0 |
timestamp | 2024-05-13 11:24:05 UTC (01 20:07:05 days ago) |
result | warning (test) | warning (test-installed) | log | rebuild |