Skip to content

Commit 18b7b05

Browse files
authored
add tl-optional (#558)
1 parent 9853479 commit 18b7b05

5 files changed

Lines changed: 205 additions & 0 deletions

File tree

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# Add tl::optional 1.1.0 as compat.tl-optional
2+
3+
## Source and shape
4+
5+
- Upstream: <https://github.com/TartanLlama/optional>.
6+
- Version: `1.1.0`, the newest stable tag observed with
7+
`git ls-remote --tags --refs`.
8+
- License: CC0-1.0.
9+
- Shape: Form B, header-only. The single public header is
10+
`include/tl/optional.hpp`; upstream's CMake INTERFACE target exposes
11+
`include/`. The package uses `include_dirs = { "*/include" }` and a trivial
12+
anchor C TU to provide a buildable `optional` lib target.
13+
- No features: the library has no optional compilable source component.
14+
Upstream's Catch2 tests are not part of the library.
15+
16+
The header supports C++11/14/17. The package's own anchor is compiled as C++;
17+
consumers choose their language mode. The workspace test uses C++23, and a
18+
direct smoke test also compiles and runs the same API in C++14.
19+
20+
## Download and mirror
21+
22+
- GLOBAL:
23+
`https://github.com/TartanLlama/optional/archive/refs/tags/v1.1.0.tar.gz`
24+
- SHA-256:
25+
`88ece79f3de5ccaec4191951a222f95cc80c4381dafd3163bdb1ff87cedf3118`
26+
- The archive was downloaded twice and compared byte-for-byte; both copies had
27+
the same digest.
28+
- No verified `mcpp-res` release is available, so the descriptor uses the
29+
upstream plain-string URL fallback rather than inventing a CN mirror.
30+
31+
## Automatic updates
32+
33+
The package meets the automatic-update criteria: it has GitHub numeric tags,
34+
stable archive URLs, identical resources on all declared platforms, and future
35+
versions do not require a build-recipe change. `extensions.autoupdate` uses the
36+
prefixed `v${version}` tag spelling and the GitHub tag-archive URL template.
37+
38+
## Test member
39+
40+
`tests/examples/tl-optional/` is registered in the root workspace. It asserts:
41+
42+
- value and empty construction, `value_or`, reset and emplace;
43+
- constexpr construction;
44+
- `map`, `and_then`, `or_else` and `map_or`;
45+
- reference optional binding, rebinding and mutation;
46+
- `take()` moving the value out and emptying the source;
47+
- `make_optional` preserving reference optionals.
48+
49+
Every assertion affects the process exit status (`return ok ? 0 : 1`).
50+
51+
## Verification
52+
53+
Pending local validation and updater declaration checks.

‎mcpp.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ members = [
172172
"tests/examples/websocket-features",
173173
"tests/examples/websocket-tls",
174174
"tests/examples/wolfssl",
175+
"tests/examples/tl-optional",
175176
"tests/examples/tray",
176177
"tests/examples/xsimd",
177178
"tests/examples/xxhash",

‎pkgs/c/compat.tl-optional.lua‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
-- Form B inline descriptor for tl::optional — a single-header implementation
2+
-- of std::optional with monadic extensions and optional references.
3+
--
4+
-- HEADER-ONLY: upstream's CMake INTERFACE target exposes `include/`, and the
5+
-- only public header is `include/tl/optional.hpp`. Tests and packaging files
6+
-- stay outside the consumer's include path. A trivial anchor TU gives mcpp a
7+
-- buildable `optional` lib target, following compat.gtl / compat.safeint.
8+
--
9+
-- LANGUAGE FLOOR: upstream describes the library as C++11/14/17 and selects
10+
-- its monadic overloads with TL_OPTIONAL_CXX14. The package's own anchor is
11+
-- compiled as C++; consumers choose their language mode. The test uses the
12+
-- workspace default C++23 mode and directly compiles the same API in C++14.
13+
--
14+
-- No features: the library has one header and no optional compilable source.
15+
-- Its tests fetch Catch2 and are not part of the library.
16+
--
17+
-- No verified mcpp-res mirror is available, so the upstream URL is a plain
18+
-- string rather than a fabricated GLOBAL/CN resource table.
19+
package = {
20+
spec = "1",
21+
namespace = "compat",
22+
name = "tl-optional",
23+
description = "tl::optional — std::optional with monadic operations and reference support (header-only)",
24+
licenses = {"CC0-1.0"},
25+
repo = "https://github.com/TartanLlama/optional",
26+
type = "package",
27+
28+
extensions = {
29+
autoupdate = {
30+
tag = "v${version}",
31+
url = "https://github.com/TartanLlama/optional/archive/refs/tags/${tag}.tar.gz",
32+
},
33+
},
34+
35+
xpm = {
36+
linux = {
37+
["1.1.0"] = {
38+
url = "https://github.com/TartanLlama/optional/archive/refs/tags/v1.1.0.tar.gz",
39+
sha256 = "88ece79f3de5ccaec4191951a222f95cc80c4381dafd3163bdb1ff87cedf3118",
40+
},
41+
},
42+
macosx = {
43+
["1.1.0"] = {
44+
url = "https://github.com/TartanLlama/optional/archive/refs/tags/v1.1.0.tar.gz",
45+
sha256 = "88ece79f3de5ccaec4191951a222f95cc80c4381dafd3163bdb1ff87cedf3118",
46+
},
47+
},
48+
windows = {
49+
["1.1.0"] = {
50+
url = "https://github.com/TartanLlama/optional/archive/refs/tags/v1.1.0.tar.gz",
51+
sha256 = "88ece79f3de5ccaec4191951a222f95cc80c4381dafd3163bdb1ff87cedf3118",
52+
},
53+
},
54+
},
55+
56+
mcpp = {
57+
language = "c++23",
58+
import_std = false,
59+
c_standard = "c11",
60+
include_dirs = { "*/include" },
61+
generated_files = {
62+
["mcpp_generated/tl_optional_anchor.c"] = [==[
63+
int mcpp_compat_tl_optional_headers_anchor(void) { return 0; }
64+
]==],
65+
},
66+
sources = { "mcpp_generated/tl_optional_anchor.c" },
67+
targets = { ["optional"] = { kind = "lib" } },
68+
deps = { },
69+
},
70+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# tl-optional test project: exercise the standard optional surface plus the
2+
# extensions that distinguish this library from std::optional.
3+
[package]
4+
name = "tl-optional-tests"
5+
version = "0.1.0"
6+
7+
[dependencies.compat]
8+
tl-optional = "1.1.0"
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// compat.tl-optional — assert value/empty state, observers, mutation, monadic
2+
// chaining, reference binding, and constexpr construction through the public
3+
// header. The test uses only the standard library in addition to tl/optional.
4+
#include <tl/optional.hpp>
5+
6+
#include <cstdio>
7+
#include <string>
8+
#include <type_traits>
9+
10+
int main() {
11+
bool ok = true;
12+
auto check = [&](bool condition, const char* what) {
13+
if (!condition) {
14+
std::printf("FAIL: %s\n", what);
15+
ok = false;
16+
}
17+
};
18+
19+
tl::optional<int> value = tl::make_optional(42);
20+
tl::optional<int> empty = tl::nullopt;
21+
check(value.has_value() && *value == 42, "value construction and observer");
22+
check(!empty.has_value(), "nullopt constructs an empty optional");
23+
check(value.value_or(7) == 42 && empty.value_or(7) == 7,
24+
"value_or handles both states");
25+
26+
constexpr tl::optional<int> constexpr_value = tl::make_optional(11);
27+
static_assert(constexpr_value.has_value(), "constexpr optional");
28+
29+
value.reset();
30+
check(!value, "reset clears the value");
31+
value.emplace(21);
32+
check(value && *value == 21, "emplace constructs a new value");
33+
34+
const auto doubled = empty.map([](int x) { return x * 2; });
35+
check(!doubled, "map on an empty optional stays empty");
36+
const auto mapped = tl::make_optional(21).map([](int x) { return x * 2; });
37+
check(mapped && *mapped == 42, "map transforms a present value");
38+
39+
const auto chained = tl::make_optional(5).and_then([](int x) {
40+
return tl::make_optional(x * 3);
41+
});
42+
check(chained && *chained == 15, "and_then chains optional-producing calls");
43+
44+
const auto fallback = empty.or_else([] { return tl::make_optional(13); });
45+
check(fallback && *fallback == 13, "or_else supplies a fallback");
46+
check(tl::make_optional(42).map_or([](int x) { return x + 1; }, 0) == 43,
47+
"map_or applies the mapper when present");
48+
check(empty.map_or([](int x) { return x + 1; }, 0) == 0,
49+
"map_or returns the fallback when empty");
50+
51+
int first = 1;
52+
int second = 2;
53+
tl::optional<int&> reference = first;
54+
check(&*reference == &first, "reference optional binds the original object");
55+
reference = second;
56+
check(&*reference == &second, "assignment rebinds the reference");
57+
*reference = 9;
58+
check(second == 9, "writing through a reference optional mutates the object");
59+
60+
tl::optional<std::string> text = std::string("hello");
61+
auto taken = text.take();
62+
check(taken && *taken == "hello" && !text,
63+
"take moves out the value and empties the source");
64+
65+
static_assert(std::is_same<decltype(tl::make_optional<int&>(first)),
66+
tl::optional<int&>>::value,
67+
"make_optional preserves reference optionals");
68+
69+
if (ok) {
70+
std::puts("tl-optional OK");
71+
}
72+
return ok ? 0 : 1;
73+
}

0 commit comments

Comments
 (0)