32#ifndef DELAYED_CONSTRUCT_H
33#define DELAYED_CONSTRUCT_H
53 using Base = std::optional<T>;
59 template <
typename... Ts>
60 KBLIB_CXX20(
requires(std::constructible_from<Base, Ts...>))
62 : storage(
std::forward<Ts>(args)...) {}
64 std::enable_if_t<std::is_assignable_v<T&, U&&>,
int> = 0>
66 storage = std::forward<U>(t);
71 template <
typename... Ts>
72 auto emplace(Ts&&... args)
const ->
decltype(
auto) {
73 return storage.emplace(std::forward<Ts>(args)...);
82 auto operator->() const -> decltype(auto) {
return storage.operator->(); }
83 auto operator*() const -> decltype(auto) {
return storage.operator*(); }
84 auto value() const -> decltype(auto) {
return storage.value(); }
85 explicit operator bool()
const {
return static_cast<bool>(storage); }
87 return storage.has_value();
94 template <std::three_way_comparable_with<Base> U>
96 operator<=>(
const U& other)
const {
97 return storage <=> other;
99 template <std::equality_comparable_with<Base> U>
101 operator==(
const U& other)
const {
102 return storage == other;
105 const delayed_construct& other)
const =
default;
106 KBLIB_NODISCARD auto operator==(
const delayed_construct& other)
const ->
bool
111# define OVERLOAD_DEFER_OP(op) \
112 KBLIB_NODISCARD friend constexpr auto operator op( \
113 const delayed_construct& lhs, \
114 const delayed_construct& rhs) noexcept->bool { \
115 return lhs.storage op rhs.storage; \
117 template <typename U> \
118 KBLIB_NODISCARD friend constexpr auto operator op( \
119 const delayed_construct& lhs, \
120 const delayed_construct<U>& rhs) noexcept->bool { \
121 return lhs.storage op static_cast<const std::optional<U>&>(rhs); \
123 KBLIB_NODISCARD friend constexpr auto operator op( \
124 const delayed_construct& lhs, \
125 std::nullopt_t rhs) noexcept->bool { \
126 return lhs.storage op rhs; \
128 KBLIB_NODISCARD friend constexpr auto operator op( \
129 std::nullopt_t lhs, \
130 const delayed_construct& rhs) noexcept->bool { \
131 return lhs op rhs.storage; \
133 template <typename U> \
134 KBLIB_NODISCARD friend constexpr auto operator op( \
135 const delayed_construct& opt, const U& value) noexcept->bool { \
136 return opt.storage op value; \
138 template <typename U> \
139 KBLIB_NODISCARD friend constexpr auto operator op( \
140 const U& value, const delayed_construct& opt) noexcept->bool { \
141 return value op opt.storage; \
169# undef OVERLOAD_DEFER_OP
199struct hash<
kblib::delayed_construct<T>> : hash<T> {
202 return hash<optional<T>>{}(
static_cast<const optional<T>&
>(value));
auto emplace(Ts &&... args) const -> decltype(auto)
~delayed_construct()=default
auto value() const -> decltype(auto)
auto operator=(U &&t) -> delayed_construct &
auto operator=(std::nullopt_t) -> delayed_construct &=delete
constexpr auto is_constructed() const noexcept -> bool
delayed_construct(delayed_construct &&)=default
auto operator=(delayed_construct &&) -> delayed_construct &=default
delayed_construct(const delayed_construct &)=default
auto operator=(const delayed_construct &) -> delayed_construct &=default
auto operator->() const -> decltype(auto)
auto operator*() const -> decltype(auto)
#define OVERLOAD_DEFER_OP(op)
Provides generic facilities for hashing data, and aliases for standard unordered containers using the...
The main namespace in which all entities from kblib are defined.
constexpr std::size_t operator()(const delayed_construct< T > &key, std::size_t offset=fnv::fnv_offset< std::size_t >::value) const noexcept
The primary template has to exist, but not be constructible, in order to be compatible with std::hash...
The starting value for the FNVa hash algorithm, as a type trait.
auto operator()(const argument_type &value) const noexcept -> std::size_t
Provides macros and basic templates used by the rest of kblib.
#define KBLIB_NODISCARD
This internal macro is used to provide a fallback for [[nodiscard]] in C++14.
#define KBLIB_CXX20(args)
This internal macro is used to selectively use C++20 features.