Skip to content

Commit ff61017

Browse files
authored
Merge pull request #231 from elbeno/easy-optional-selection
✨ Add easy way to select optional implementation
2 parents 0aafc46 + 50c5fb4 commit ff61017

File tree

2 files changed

+23
-3
lines changed

2 files changed

+23
-3
lines changed

include/stdx/optional.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,12 @@
1515
namespace stdx {
1616
inline namespace v1 {
1717
template <typename T, typename = void> struct tombstone_traits {
18-
static_assert(
19-
stdx::always_false_v<T>,
20-
"To use stdx::optional you must specialize stdx::tombstone_traits");
18+
using unspecialized = int;
19+
constexpr auto operator()() const {
20+
static_assert(
21+
stdx::always_false_v<T>,
22+
"To use stdx::optional you must specialize stdx::tombstone_traits");
23+
}
2124
};
2225

2326
template <typename T>
@@ -47,6 +50,7 @@ template <typename T, typename TS = tombstone_traits<T>> class optional {
4750
not stdx::is_specialization_of_v<TS, tombstone_traits>,
4851
"Don't define tombstone traits for plain integral types");
4952
constexpr static inline auto traits = TS{};
53+
using check_specialization_t [[maybe_unused]] = decltype(traits());
5054
T val{traits()};
5155

5256
public:

test/optional.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,3 +427,19 @@ TEST_CASE("tombstone with non-structural value", "[optional]") {
427427
CHECK(*o == std::string_view{});
428428
}
429429
#endif
430+
431+
#if __cplusplus >= 202002L
432+
namespace {
433+
template <typename T>
434+
using my_optional = stdx::conditional_t<requires {
435+
typename stdx::tombstone_traits<T>::unspecialized;
436+
}, std::optional<T>, stdx::optional<T>>;
437+
} // namespace
438+
439+
TEST_CASE("select optional implementation based on whether tombstone traits "
440+
"are present",
441+
"[optional]") {
442+
static_assert(std::is_same_v<my_optional<S>, stdx::optional<S>>);
443+
static_assert(std::is_same_v<my_optional<int>, std::optional<int>>);
444+
}
445+
#endif

0 commit comments

Comments
 (0)