gimo v0.3.2
Loading...
Searching...
No Matches
ValueOrElse.hpp
Go to the documentation of this file.
1// Copyright Dominic (DNKpp) Koepke 2026.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef GIMO_ALGORITHM_VALUE_OR_ELSE_HPP
7#define GIMO_ALGORITHM_VALUE_OR_ELSE_HPP
8
9#pragma once
10
11#include "gimo/Common.hpp"
12#include "gimo/Pipeline.hpp"
14
15#include <concepts>
16#include <functional>
17#include <tuple>
18#include <utility>
19
20namespace gimo::detail::value_or_else
21{
22 template <typename Nullable>
23 using result_t = std::remove_cvref_t<value_result_t<Nullable>>;
24
25 template <typename Nullable, typename Action>
26 consteval Nullable* print_diagnostics()
27 {
28 if constexpr (!std::convertible_to<std::invoke_result_t<Action>, result_t<Nullable>>)
29 {
30 static_assert(always_false_v<Nullable>, "The value_or algorithm requires an alternative that is convertible to the nullable's value-type.");
31 }
32
33 return nullptr;
34 }
35
36 struct traits
37 {
38 template <nullable Nullable, typename Action>
39 static constexpr bool is_applicable_on = requires {
40 requires std::convertible_to<
41 std::invoke_result_t<Action>,
42 result_t<Nullable>>;
43 };
44
45 template <typename Action, nullable Nullable>
46 [[nodiscard]]
47 static constexpr auto on_value(Action&& /*action*/, Nullable&& opt)
48 {
49 GIMO_ASSERT(detail::has_value(opt), "Nullable is empty while it's expected to contain a value.");
50
51 if constexpr (is_applicable_on<Nullable, Action>)
52 {
53 return detail::forward_value<Nullable>(opt);
54 }
55 else
56 {
57 return *value_or_else::print_diagnostics<Nullable, Action>();
58 }
59 }
60
61 template <typename Action, nullable Nullable>
62 [[nodiscard]]
63 static constexpr auto on_null(Action&& action, [[maybe_unused]] Nullable&& opt)
64 {
65 GIMO_ASSERT(!detail::has_value(opt), "Nullable contains a value while it's expected to be empty.");
66
67 if constexpr (is_applicable_on<Nullable, Action>)
68 {
69 return static_cast<result_t<Nullable>>(
70 std::invoke(std::forward<Action>(action)));
71 }
72 else
73 {
74 return *value_or_else::print_diagnostics<Nullable, Action>();
75 }
76 }
77 };
78}
79
80namespace gimo
81{
82 namespace detail
83 {
84 template <typename Action>
85 using value_or_else_t = BasicAlgorithm<
86 value_or_else::traits,
87 std::remove_cvref_t<Action>>;
88
89 template <unqualified T>
90 class ValueStorageFun
91 {
92 public:
93 [[nodiscard]]
94 explicit constexpr ValueStorageFun(T value) noexcept(std::is_nothrow_move_constructible_v<T>)
95 : m_value{std::move(value)}
96 {
97 }
98
99 [[nodiscard]]
100 constexpr T& operator()() & noexcept
101 {
102 return m_value;
103 }
104
105 [[nodiscard]]
106 constexpr T const& operator()() const& noexcept
107 {
108 return m_value;
109 }
110
111 [[nodiscard]]
112 constexpr T&& operator()() && noexcept
113 {
114 return std::move(m_value);
115 }
116
117 [[nodiscard]]
118 constexpr T const&& operator()() const&& noexcept
119 {
120 return std::move(m_value);
121 }
122
123 private:
124 T m_value;
125 };
126
127 template <typename Alternative>
128 using value_or_t = value_or_else_t<
129 ValueStorageFun<std::decay_t<Alternative>>>;
130 }
131
145 template <std::invocable Action>
146 [[nodiscard]]
147 constexpr auto value_or_else(Action&& action)
148 {
149 using Algorithm = detail::value_or_else_t<Action>;
150
151 return Pipeline{
152 std::tuple<Algorithm>{std::forward<Action>(action)}};
153 }
154
167 template <typename Alternative>
168 [[nodiscard]]
169 constexpr auto value_or(Alternative&& alternative)
170 {
171 using Algorithm = detail::value_or_t<Alternative>;
172
173 return Pipeline{std::tuple<Algorithm>{std::forward<Alternative>(alternative)}};
174 }
175}
176
177#endif
#define GIMO_ASSERT(condition, msg,...)
Definition Config.hpp:11
A composite object representing a sequence of monadic operations.
Definition Pipeline.hpp:30
constexpr auto value_or_else(Action &&action)
Creates a terminating pipeline step that returns the contained value or invokes a fallback action if ...
Definition ValueOrElse.hpp:147
constexpr auto value_or(Alternative &&alternative)
Creates a terminating pipeline step that returns the contained value or a specified alternative if th...
Definition ValueOrElse.hpp:169
Definition AndForward.hpp:21