Thoth
A functional, expressive, asynchronous C++26 webdev library
Loading...
Searching...
No Matches
Functional.hpp
Go to the documentation of this file.
1#pragma once
2#include <functional>
3#include <expected>
4#include <concepts>
5#include <ranges>
6#include <algorithm>
7
8
9namespace Thoth::Utils {
10
12 template<auto V>
13 constexpr auto ToValue() { return V; }
14
16 template<class T>
17 constexpr T ToValue() { return T{}; }
18
19#pragma region Const/Mut
20
21 template<class Ret, class Class, class... Args>
22 constexpr auto Const(Ret (Class::*ptr)(Args...) const) { return ptr; }
23 template<class Ret, class Class, class... Args>
24 constexpr auto Mut(Ret (Class::*ptr)(Args...)) { return ptr; }
25
26 template<class Ret, class Class, class... Args>
27 constexpr auto ConstFn(Ret (Class::*ptr)(Args...) const) { return std::mem_fn(ptr); }
28 template<class Ret, class Class, class... Args>
29 constexpr auto MutFn(Ret (Class::*ptr)(Args...)) { return std::mem_fn(ptr); }
30
31#pragma endregion
32
33
34#pragma region ValueOr
35
37 template<class Opt, class Err>
38 constexpr std::expected<typename std::remove_cvref_t<Opt>::value_type, Err> ValueOr(Opt&& val, Err&& err) {
39 if (val) {
40 if constexpr (std::is_rvalue_reference_v<Opt>)
41 return std::move(*val);
42 else
43 return *val;
44 }
45 return std::unexpected{ std::forward<Err>(err) };
46 }
47
49 template<class Opt, class Err>
50 constexpr auto ValueOrHof(Err&& err) {
51 using OptT = std::optional<Opt>&&;
52 using ValT = typename std::remove_cvref_t<OptT>::value_type;
53
54 return [err = std::forward<Err>(err)](OptT val) -> std::expected<ValT, Err> {
55 if (val) {
56 if constexpr (std::is_rvalue_reference_v<OptT>)
57 return std::move(*val);
58 else
59 return *val;
60 }
61 return std::unexpected{ err };
62 };
63 }
64
65#pragma endregion
66
67
68#pragma region CallIfError/Not
69
70 template<bool Negate, class Pred, class Trans, class Val>
71 requires std::predicate<Pred&, Val&> && std::invocable<Trans, Val>
72 constexpr std::expected<Val, std::invoke_result_t<Trans, Val>>
73 S_CallIfErrorImpl(Pred&& pred, Trans&& trans, Val&& value) {
74 if (std::invoke(pred, value) ^ Negate)
75 return std::forward<Val>(value);
76 return std::unexpected{ std::invoke(trans, std::forward<Val>(value)) };
77 }
78
81 template<class Pred, class Trans, class Val>
82 constexpr auto CallIfError(Pred&& pred, Trans&& trans, Val&& value) {
83 return S_CallIfErrorImpl<false>(
84 std::forward<Pred>(pred),
85 std::forward<Trans>(trans),
86 std::forward<Val>(value)
87 );
88 }
89
91 template<auto Pred, class Trans, class Val>
92 constexpr auto CallIfError(Trans&& trans, Val&& val) {
93 return CallIfError(ToValue<Pred>(), std::forward<Trans>(trans), std::forward<Val>(val));
94 }
95
97 template<auto Pred, auto Trans, class Val>
98 constexpr auto CallIfError(Val&& val) {
99 return CallIfError(ToValue<Pred>(), ToValue<Trans>(), std::forward<Val>(val));
100 }
101
104 template<class Pred, class Trans, class Val>
105 constexpr auto CallIfErrorNot(Pred&& pred, Trans&& trans, Val&& value) {
106 return S_CallIfErrorImpl<true>(
107 std::forward<Pred>(pred),
108 std::forward<Trans>(trans),
109 std::forward<Val>(value)
110 );
111 }
112
114 template<auto Pred, class Trans, class Val>
115 constexpr auto CallIfErrorNot(Trans&& trans, Val&& val) {
116 return CallIfErrorNot(ToValue<Pred>(), std::forward<Trans>(trans), std::forward<Val>(val));
117 }
118
120 template<auto Pred, auto Trans, class Val>
121 constexpr auto CallIfErrorNot(Val&& val) {
122 return CallIfErrorNot(ToValue<Pred>(), ToValue<Trans>(), std::forward<Val>(val));
123 }
124
126 template<class Pred, class Trans>
127 constexpr auto CallIfErrorHof(Pred&& pred, Trans&& trans) {
128 return [pred = std::forward<Pred>(pred),
129 trans = std::forward<Trans>(trans)](auto&& value) {
130 return CallIfError(pred, trans, std::forward<decltype(value)>(value));
131 };
132 }
133
135 template<auto Pred, class Trans>
136 constexpr auto CallIfErrorHof(Trans&& trans) {
137 return [trans = std::forward<Trans>(trans)](auto&& value) {
138 return CallIfError(ToValue<Pred>(), trans, std::forward<decltype(value)>(value));
139 };
140 }
141
143 template<auto Pred, auto Trans>
144 constexpr auto CallIfErrorHof() {
145 return CallIfErrorHof<Pred, Trans>(ToValue<Pred>(), ToValue<Trans>());
146 }
147
149 template<class Pred, class Trans>
150 constexpr auto CallIfErrorNotHof(Pred&& pred, Trans&& trans) {
151 return [pred = std::forward<Pred>(pred),
152 trans = std::forward<Trans>(trans)](auto&& value) {
153 return CallIfErrorNot(pred, trans, std::forward<decltype(value)>(value));
154 };
155 }
156
158 template<auto Pred, class Trans>
159 constexpr auto CallIfErrorNotHof(Trans&& trans) {
160 return [trans = std::forward<Trans>(trans)](auto&& value) {
161 return CallIfErrorNot(ToValue<Pred>(), trans, std::forward<decltype(value)>(value));
162 };
163 }
164
166 template<auto Pred, auto Trans>
167 constexpr auto CallIfErrorNotHof() {
168 return CallIfErrorNotHof<Pred, Trans>(ToValue<Pred>(), ToValue<Trans>());
169 }
170
171#pragma endregion
172
173#pragma region ErrorIf/Not
174
175 template<bool Negate, class Pred, class Val>
176 requires std::predicate<Pred&, Val&>
177 constexpr bool S_TestIfImpl(Pred&& pred, Val& value) {
178 return std::invoke(pred, value) ^ Negate;
179 }
180
181 template<bool Negate, class Pred, class Val, class Err>
182 requires std::predicate<Pred&, Val&>
183 constexpr std::expected<Val, std::decay_t<Err>>
184 S_ErrorIfImpl(Pred&& pred, Val&& value, Err&& error) {
185 if (!S_TestIfImpl<Negate>(pred, value))
186 return std::forward<Val>(value);
187 return std::unexpected{ std::forward<Err>(error) };
188 }
189
191 template<class Pred, class Val, class Err>
192 constexpr auto ErrorIf(Pred&& pred, Val&& value, Err&& error) {
193 return S_ErrorIfImpl<false>(
194 std::forward<Pred>(pred),
195 std::forward<Val>(value),
196 std::forward<Err>(error)
197 );
198 }
199
201 template<auto Pred, class Val, class Err>
202 constexpr auto ErrorIf(Val&& value, Err&& error) {
203 return ErrorIf(ToValue<Pred>(), std::forward<Val>(value), std::forward<Err>(error));
204 }
205
207 template<class Pred, class Val, class Err>
208 constexpr auto ErrorIfNot(Pred&& pred, Val&& value, Err&& error) {
209 return S_ErrorIfImpl<true>(
210 std::forward<Pred>(pred),
211 std::forward<Val>(value),
212 std::forward<Err>(error)
213 );
214 }
215
217 template<auto Pred, class Val, class Err>
218 constexpr auto ErrorIfNot(Val&& value, Err&& error) {
219 return ErrorIf(ToValue<Pred>(), std::forward<Val>(value), std::forward<Err>(error));
220 }
221
223 template<class Pred, class Err>
224 constexpr auto ErrorIfHof(Pred&& pred, Err&& error) {
225 return [pred = std::forward<Pred>(pred),
226 error = std::forward<Err>(error)](auto&& value) {
227 return ErrorIf(pred, std::forward<decltype(value)>(value), error);
228 };
229 }
230
232 template<auto Pred, class Err>
233 constexpr auto ErrorIfHof(Err&& error) {
234 return [error = std::forward<Err>(error)](auto&& value) {
235 return ErrorIf(ToValue<Pred>(), std::forward<decltype(value)>(value), error);
236 };
237 }
239 template<class Pred, class Err>
240 constexpr auto ErrorIfNotHof(Pred&& pred, Err&& error) {
241 return [pred = std::forward<Pred>(pred),
242 error = std::forward<Err>(error)](auto&& value) {
243 return ErrorIfNot(pred, std::forward<decltype(value)>(value), error);
244 };
245 }
247 template<auto Pred, class Err>
248 constexpr auto ErrorIfNotHof(Err&& error) {
249 return [error = std::forward<Err>(error)](auto&& value) {
250 return ErrorIfNot(ToValue<Pred>(), std::forward<decltype(value)>(value), error);
251 };
252 }
253
254#pragma endregion
255
256
257#pragma region Transform{Opt,Exp}If/Not
258
259 template<bool Negate, class Pred, class Trans, class Val>
260 requires std::predicate<Pred&, Val&> && std::invocable<Trans, Val>
261 constexpr auto S_TransformOptIfImpl(Pred&& pred, Trans&& trans, Val&& value)
262 -> std::optional<std::invoke_result_t<Trans, Val>>
263 {
264 if (std::invoke(pred, value) ^ Negate)
265 return std::invoke(trans, std::forward<Val>(value));
266 return std::nullopt;
267 }
268
269 template<bool Negate, class Pred, class Trans, class Val, class Err>
270 requires std::predicate<Pred&, Val&> && std::invocable<Trans, Val>
271 constexpr auto S_TransformExpIfImpl(Pred&& pred, Trans&& trans, Val&& value, Err&& error)
272 -> std::expected<std::invoke_result_t<Trans, Val>, std::decay_t<Err>>
273 {
274 if (std::invoke(pred, value) ^ Negate)
275 return std::invoke(trans, std::forward<Val>(value));
276 return std::unexpected{ std::forward<Err>(error) };
277 }
278
279#pragma region std::optional
280
283 template<class Pred, class Trans, class Val>
284 requires std::predicate<Pred&, Val&> && std::invocable<Trans, Val>
285 constexpr auto TransformOptIf(Pred&& pred, Trans&& trans, Val&& value) {
286 return S_TransformOptIfImpl<false>(
287 std::forward<Pred>(pred),
288 std::forward<Trans>(trans),
289 std::forward<Val>(value)
290 );
291 }
292
294 template<auto Pred, class Trans, class Val>
295 requires std::predicate<decltype(Pred), Val&> && std::invocable<Trans, Val>
296 constexpr auto TransformOptIf(Trans&& trans, Val&& value) {
297 return TransformOptIf<Pred>(ToValue<Pred>(), std::forward<Trans>(trans), std::forward<Val>(value));
298 }
299
301 template<auto Pred, auto Trans, class Val>
302 requires std::invocable<decltype(Trans), Val>
303 constexpr auto TransformOptIf(Val&& value) {
304 return TransformOptIf<Pred, Trans>(ToValue<Pred>(), ToValue<Trans>(), std::forward<Val>(value));
305 }
306
309 template<class Pred, class Trans, class Val>
310 requires std::predicate<Pred&, Val&> && std::invocable<Trans, Val>
311 constexpr auto TransformOptIfNot(Pred&& pred, Trans&& trans, Val&& value) {
312 return S_TransformOptIfImpl<true>(
313 std::forward<Pred>(pred),
314 std::forward<Trans>(trans),
315 std::forward<Val>(value)
316 );
317 }
318
320 template<auto Pred, class Trans, class Val>
321 requires std::predicate<decltype(Pred), Val&> && std::invocable<Trans, Val>
322 constexpr auto TransformOptIfNot(Trans&& trans, Val&& value) {
323 return TransformOptIfNot<Pred>(ToValue<Pred>(), std::forward<Trans>(trans), std::forward<Val>(value));
324 }
325
327 template<auto Pred, auto Trans, class Val>
328 requires std::invocable<decltype(Trans), Val>
329 constexpr auto TransformOptIfNot(Val&& value) {
330 return TransformOptIfNot<Pred, Trans>(ToValue<Pred>(), ToValue<Trans>(), std::forward<Val>(value));
331 }
332
334 template<class Pred, class Trans>
335 constexpr auto TransformOptIfHof(Pred&& pred, Trans&& trans) {
336 return [pred = std::forward<Pred>(pred),
337 trans = std::forward<Trans>(trans)](auto&& value) {
338 return TransformOptIf(pred, trans, std::forward<decltype(value)>(value));
339 };
340 }
341
343 template<auto Pred, class Trans>
344 constexpr auto TransformOptIfHof(Trans&& trans) {
345 return [trans = std::forward<Trans>(trans)](auto&& value) {
346 return TransformOptIf<Pred>(ToValue<Pred>(), trans, std::forward<decltype(value)>(value));
347 };
348 }
349
351 template<auto Pred, auto Trans>
352 constexpr auto TransformOptIfHof() {
353 return TransformOptIfHof<Pred, Trans>(ToValue<Pred>(), ToValue<Trans>());
354 }
355
357 template<class Pred, class Trans>
358 constexpr auto TransformOptIfNotHof(Pred&& pred, Trans&& trans) {
359 return [pred = std::forward<Pred>(pred),
360 trans = std::forward<Trans>(trans)](auto&& value) {
361 return TransformOptIfNot(pred, trans, std::forward<decltype(value)>(value));
362 };
363 }
364
366 template<auto Pred, class Trans>
367 constexpr auto TransformOptIfNotHof(Trans&& trans) {
368 return [trans = std::forward<Trans>(trans)](auto&& value) {
369 return TransformOptIfNot<Pred>(ToValue<Pred>(), trans, std::forward<decltype(value)>(value));
370 };
371 }
372
374 template<auto Pred, auto Trans>
375 constexpr auto TransformOptIfNotHof() {
376 return TransformOptIfNotHof<Pred, Trans>(ToValue<Pred>(), ToValue<Trans>());
377 }
378#pragma endregion
379
380#pragma region std::expected
381
384 template<class Pred, class Trans, class Val, class Err>
385 requires std::predicate<Pred&, Val&> && std::invocable<Trans, Val>
386 constexpr auto TransformExpIf(Pred&& pred, Trans&& trans, Val&& value, Err&& error) {
387 return S_TransformExpIfImpl<false>(
388 std::forward<Pred>(pred),
389 std::forward<Trans>(trans),
390 std::forward<Val>(value),
391 std::forward<Err>(error)
392 );
393 }
394
396 template<auto Pred, class Trans, class Val, class Err>
397 requires std::predicate<decltype(Pred), Val&> && std::invocable<Trans, Val>
398 constexpr auto TransformExpIf(Trans&& trans, Val&& value, Err&& error) {
399 return S_TransformExpIfImpl<false>(
400 ToValue<Pred>(),
401 std::forward<Trans>(trans),
402 std::forward<Val>(value),
403 std::forward<Err>(error)
404 );
405 }
406
408 template<auto Pred, auto Trans, class Val, class Err>
409 requires std::invocable<decltype(Trans), Val>
410 constexpr auto TransformExpIf(Val&& value, Err&& error) {
411 return S_TransformExpIfImpl<false>(
412 ToValue<Pred>(),
413 ToValue<Trans>(),
414 std::forward<Val>(value),
415 std::forward<Err>(error)
416 );
417 }
420 template<class Pred, class Trans, class Val, class Err>
421 requires std::predicate<Pred&, Val&> && std::invocable<Trans, Val>
422 constexpr auto TransformExpIfNot(Pred&& pred, Trans&& trans, Val&& value, Err&& error) {
423 return S_TransformExpIfImpl<true>(
424 std::forward<Pred>(pred),
425 std::forward<Trans>(trans),
426 std::forward<Val>(value),
427 std::forward<Err>(error)
428 );
429 }
430
432 template<auto Pred, class Trans, class Val, class Err>
433 requires std::predicate<decltype(Pred), Val&> && std::invocable<Trans, Val>
434 constexpr auto TransformExpIfNot(Trans&& trans, Val&& value, Err&& error) {
435 return S_TransformExpIfImpl<true>(
436 ToValue<Pred>(),
437 std::forward<Trans>(trans),
438 std::forward<Val>(value),
439 std::forward<Err>(error)
440 );
441 }
442
444 template<auto Pred, auto Trans, class Val, class Err>
445 requires std::invocable<decltype(Trans), Val>
446 constexpr auto TransformExpIfNot(Val&& value, Err&& error) {
447 return S_TransformExpIfImpl<true>(
448 ToValue<Pred>(),
449 ToValue<Trans>(),
450 std::forward<Val>(value),
451 std::forward<Err>(error)
452 );
453 }
454
456 template<class Pred, class Trans, class Err>
457 constexpr auto TransformExpIfHof(Pred&& pred, Trans&& trans, Err&& error) {
458 return [pred = std::forward<Pred>(pred),
459 trans = std::forward<Trans>(trans),
460 error = std::forward<Err>(error)](auto&& value) {
461 return TransformExpIf(pred, trans, std::forward<decltype(value)>(value), error);
462 };
463 }
464
466 template<auto Pred, class Trans, class Err>
467 constexpr auto TransformExpIfHof(Trans&& trans, Err&& error) {
468 return [trans = std::forward<Trans>(trans),
469 error = std::forward<Err>(error)](auto&& value) {
470 return TransformExpIf(ToValue<Pred>(), trans, std::forward<decltype(value)>(value), error);
471 };
472 }
473
475 template<auto Pred, auto Trans, class Err>
476 constexpr auto TransformExpIfHof(Err&& error) {
477 return TransformExpIfHof(ToValue<Pred>(), ToValue<Trans>(), std::forward<Err>(error));
478 }
479
481 template<class Pred, class Trans, class Err>
482 constexpr auto TransformExpIfNotHof(Pred&& pred, Trans&& trans, Err&& error) {
483 return [pred = std::forward<Pred>(pred),
484 trans = std::forward<Trans>(trans),
485 error = std::forward<Err>(error)](auto&& value) {
486 return TransformExpIfNot(pred, trans, std::forward<decltype(value)>(value), error);
487 };
488 }
489
491 template<auto Pred, class Trans, class Err>
492 constexpr auto TransformExpIfNotHof(Trans&& trans, Err&& error) {
493 return [trans = std::forward<Trans>(trans),
494 error = std::forward<Err>(error)](auto&& value) {
495 return TransformExpIfNot(ToValue<Pred>(), trans, std::forward<decltype(value)>(value), error);
496 };
497 }
498
500 template<auto Pred, auto Trans, class Err>
501 constexpr auto TransformExpIfNotHof(Err&& error) {
502 return TransformExpIfNotHof(ToValue<Pred>(), ToValue<Trans>(), std::forward<Err>(error));
503 }
504#pragma endregion
505
506#pragma endregion
507
508#pragma region NulloptIf/Not
509
510 template<bool Negate, class Pred, class Val>
511 requires std::predicate<Pred&, Val&>
512 constexpr std::optional<std::remove_cvref_t<Val>>
513 S_NulloptIfImpl(Pred&& pred, Val&& value) {
514 if (!S_TestIf<Negate>(pred, value))
515 return std::forward<Val>(value);
516 return std::nullopt;
517 }
518
520 template<class Pred, class Val>
521 constexpr auto NulloptIf(Pred&& pred, Val&& value) {
522 return S_NulloptIfImpl<false>(
523 std::forward<Pred>(pred),
524 std::forward<Val>(value)
525 );
526 }
527
529 template<auto Pred, class Val>
530 constexpr auto NulloptIf(Val&& value) {
531 return NulloptIf(ToValue<Pred>(), std::forward<Val>(value));
532 }
533
535 template<class Pred, class Val>
536 constexpr auto NulloptIfNot(Pred&& pred, Val&& value) {
537 return S_NulloptIfImpl<true>(
538 std::forward<Pred>(pred),
539 std::forward<Val>(value)
540 );
541 }
542
544 template<auto Pred, class Val>
545 constexpr auto NulloptIfNot(Val&& value) {
546 return NulloptIfNot(ToValue<Pred>(), std::forward<Val>(value));
547 }
548
550 template<class Pred>
551 constexpr auto NulloptIfHof(Pred&& pred) {
552 return [pred = std::forward<Pred>(pred)](auto&& value) {
553 return NulloptIf(pred, std::forward<decltype(value)>(value));
554 };
555 }
556
558 template<auto Pred>
559 constexpr auto NulloptIfHof() {
560 return NulloptIfHof<Pred>(ToValue(Pred));
561 }
562
564 template<class Pred>
565 constexpr auto NulloptIfNotHof(Pred&& pred) {
566 return [pred = std::forward<Pred>(pred)](auto&& value) {
567 return NulloptIfNot(pred, std::forward<decltype(value)>(value));
568 };
569 }
570
572 template<auto Pred>
573 constexpr auto NulloptIfNotHof() {
574 return NulloptIfNotHof<Pred>(ToValue<Pred>());
575 }
576
577#pragma endregion
578
579#pragma region WhileNotFail
580
585 template<std::ranges::input_range R, class F, class Acc,
586 class Exp = std::iter_value_t<R>, class Val = Exp::value_type, class Err = Exp::error_type>
587 requires std::same_as<Exp, std::expected<Val, Err>>
588 && std::invocable<F, Acc, Val> && std::same_as<Acc, std::invoke_result_t<F, Acc, Val>>
589 constexpr std::expected<std::remove_cvref_t<Acc>, std::remove_cvref_t<Err>>
590 FoldWhileSuccess(R&& range, F&& callable, Acc&& initial = {}) {
591
592 using AccT = std::remove_cvref_t<Acc>;
593 using ValT = std::remove_cvref_t<Val>;
594 using ErrT = std::remove_cvref_t<Err>;
595
596 AccT accumulator = std::forward<Acc>(initial);
597
598 for (auto&& val : range) {
599 if (!val)
600 return std::unexpected{ val.error() };
601
602 accumulator = std::invoke(callable, std::forward<Acc>(accumulator), *val);
603 }
604
605 return accumulator;
606 }
607
609 template<class F, class Exp>
610 constexpr auto FoldWhileSuccessHof(F&& callable, Exp&& reducer = {}) {
611 return [callable = std::forward<F>(callable), reducer = std::forward<Exp>(reducer)]
612 <std::ranges::input_range R>(R&& range){
613 return FoldWhileSuccess(std::forward<R>(range), std::forward<F>(callable), std::forward<Exp>(reducer));
614 };
615 }
616#pragma endregion
617
618#pragma region Self
619
620 template<class T, class F>
621 requires std::invocable<F, T>
622 constexpr auto Self(T&& val, F&& callable) {
623 std::invoke(std::forward<F>(callable), val);
624 return std::forward<T>(val);
625 }
626
627 template<class F>
628 constexpr auto SelfHof(F&& callable) {
629 return [callable = std::forward<F>(callable)]<class T>(T&& val) {
630 return Self(std::forward<F>(callable), std::forward<T>(val));
631 };
632 }
633#pragma endregion
634}
Definition Env.hpp:5
constexpr auto CallIfErrorHof()
@hof{CallIfError}
Definition Functional.hpp:144
constexpr std::expected< Val, std::decay_t< Err > > S_ErrorIfImpl(Pred &&pred, Val &&value, Err &&error)
Definition Functional.hpp:184
constexpr auto TransformExpIfHof(Pred &&pred, Trans &&trans, Err &&error)
@hof{TransformExpIf}
Definition Functional.hpp:457
constexpr auto FoldWhileSuccessHof(F &&callable, Exp &&reducer={})
@hof{FoldWhileSuccess}
Definition Functional.hpp:610
constexpr auto Const(Ret(Class::*ptr)(Args...) const)
Definition Functional.hpp:22
constexpr auto TransformOptIfHof()
@hof{TransformOptIf}
Definition Functional.hpp:352
constexpr auto ErrorIf(Pred &&pred, Val &&value, Err &&error)
In a std::expected<Val, Err> context, transform an error into a value only if the predicate match.
Definition Functional.hpp:192
constexpr auto ToValue()
If the template parameter is a value, then returns it. If is a type then construct and returns it.
Definition Functional.hpp:13
constexpr auto NulloptIfHof()
@hof{NulloptIf}
Definition Functional.hpp:559
constexpr auto ErrorIfNotHof(Pred &&pred, Err &&error)
@hof{ErrorIfNof}
Definition Functional.hpp:240
constexpr std::optional< std::remove_cvref_t< Val > > S_NulloptIfImpl(Pred &&pred, Val &&value)
Definition Functional.hpp:513
constexpr auto ValueOrHof(Err &&err)
@hof{ValueOr}
Definition Functional.hpp:50
constexpr std::expected< std::remove_cvref_t< Acc >, std::remove_cvref_t< Err > > FoldWhileSuccess(R &&range, F &&callable, Acc &&initial={})
fast fail foldr
Definition Functional.hpp:590
constexpr auto TransformExpIfNot(Pred &&pred, Trans &&trans, Val &&value, Err &&error)
In the std::expected<Val, Err> context, returns the transformation applied to the value if the predic...
Definition Functional.hpp:422
constexpr auto TransformExpIf(Pred &&pred, Trans &&trans, Val &&value, Err &&error)
In the std::expected<Val, Err> context, returns the transformation applied to the value if the predic...
Definition Functional.hpp:386
constexpr std::expected< typename std::remove_cvref_t< Opt >::value_type, Err > ValueOr(Opt &&val, Err &&err)
Monad friendly function to transform std::expected<std::optional<T>, Err> into std::expected<T,...
Definition Functional.hpp:38
constexpr std::expected< Val, std::invoke_result_t< Trans, Val > > S_CallIfErrorImpl(Pred &&pred, Trans &&trans, Val &&value)
Definition Functional.hpp:73
constexpr auto ConstFn(Ret(Class::*ptr)(Args...) const)
Definition Functional.hpp:27
constexpr auto MutFn(Ret(Class::*ptr)(Args...))
Definition Functional.hpp:29
constexpr auto S_TransformOptIfImpl(Pred &&pred, Trans &&trans, Val &&value) -> std::optional< std::invoke_result_t< Trans, Val > >
Definition Functional.hpp:261
constexpr auto SelfHof(F &&callable)
Definition Functional.hpp:628
constexpr auto TransformOptIfNot(Pred &&pred, Trans &&trans, Val &&value)
In the std::optional<Val> context, returns the transformation applied to the value if the predicate d...
Definition Functional.hpp:311
constexpr auto NulloptIfNotHof()
@hof{NulloptIfNot}
Definition Functional.hpp:573
constexpr auto ErrorIfNot(Pred &&pred, Val &&value, Err &&error)
In a std::expected<Val, Err> context, transform an error into a value only if the predicate doesn't m...
Definition Functional.hpp:208
constexpr auto CallIfErrorNot(Pred &&pred, Trans &&trans, Val &&value)
In the std::expected<Val, Err> context, returns the value if the predicate doesn't match,...
Definition Functional.hpp:105
constexpr bool S_TestIfImpl(Pred &&pred, Val &value)
Definition Functional.hpp:177
constexpr auto TransformOptIf(Pred &&pred, Trans &&trans, Val &&value)
In the std::optional<Val> context, returns the transformation applied to the value if the predicate m...
Definition Functional.hpp:285
constexpr auto ErrorIfHof(Pred &&pred, Err &&error)
@hof{ErrorIf}
Definition Functional.hpp:224
constexpr auto Mut(Ret(Class::*ptr)(Args...))
Definition Functional.hpp:24
constexpr auto CallIfErrorNotHof()
@hof{CallIfErrorNot}
Definition Functional.hpp:167
constexpr auto CallIfError(Pred &&pred, Trans &&trans, Val &&value)
In the std::expected<Val, Err> context, returns the value if the predicate match, or the std::unexpec...
Definition Functional.hpp:82
constexpr auto S_TransformExpIfImpl(Pred &&pred, Trans &&trans, Val &&value, Err &&error) -> std::expected< std::invoke_result_t< Trans, Val >, std::decay_t< Err > >
Definition Functional.hpp:271
constexpr auto NulloptIf(Pred &&pred, Val &&value)
In a std::optional<T> context, transforms the value to std::nullopt if the predicate match.
Definition Functional.hpp:521
constexpr auto TransformOptIfNotHof()
@hof{TransformOptIfNot}
Definition Functional.hpp:375
constexpr auto NulloptIfNot(Pred &&pred, Val &&value)
In a std::optional<T> context, transforms the value to std::nullopt if the predicate doesn't match.
Definition Functional.hpp:536
constexpr auto TransformExpIfNotHof(Pred &&pred, Trans &&trans, Err &&error)
@hof{TransformExpIfNot}
Definition Functional.hpp:482
constexpr auto Self(T &&val, F &&callable)
Definition Functional.hpp:622