qxLib
coalesce.inl
Go to the documentation of this file.
1 /**
2 
3  @file coalesce.inl
4  @author Khrapov
5  @date 27.09.2025
6  @copyright © Nick Khrapov, 2025. All right reserved.
7 
8 **/
9 
10 namespace qx
11 {
12 
13 namespace details
14 {
15 
16 template<class T>
18 {
19  using type = T;
20 };
21 
22 template<class T>
23 struct select_reference<T&>
24 {
25  using type = std::reference_wrapper<T>;
26 };
27 
28 } // namespace details
29 
30 template<class return_t, class... args_t>
31 constexpr return_t coalesce(args_t&&... args)
32 {
33  using return_type = typename details::select_reference<return_t>::type;
34 
35  size_t nArg = 0;
36  std::optional<return_type> optResult;
37 
38  (
39  [&nArg, &optResult]<class T>(T&& arg)
40  {
41  if (nArg++ == sizeof...(args_t) || predicates::is_valid(arg))
42  {
43  optResult = static_cast<return_type>(std::forward<T>(arg));
44  return true;
45  }
46  else
47  {
48  return false;
49  }
50  }(std::forward<args_t>(args))
51  || ...);
52 
53  return std::move(*optResult);
54 }
55 
56 template<class... args_t>
57  requires(same_variadic_args_v<args_t...>)
58 constexpr auto coalesce(args_t&&... args)
59 {
60  using return_type = typename details::select_reference<typename same_variadic_args<args_t...>::type>::type;
61 
62  size_t nArg = 0;
63  std::optional<return_type> optResult;
64 
65  (
66  [&nArg, &optResult]<class T>(T&& arg)
67  {
68  if (nArg++ == sizeof...(args_t) || predicates::is_valid(arg))
69  {
70  optResult = std::forward<T>(arg);
71  return true;
72  }
73  else
74  {
75  return false;
76  }
77  }(std::forward<args_t>(args))
78  || ...);
79 
80  return std::move(*optResult);
81 }
82 
83 } // namespace qx
constexpr return_t coalesce(args_t &&... args)
Coalesce function, C# a ?? b analogue.
Definition: coalesce.inl:31
requires(same_variadic_args_v< args_t... >) const expr auto coalesce(args_t &&... args)
Coalesce function, C# a ?? b analogue.
Definition: coalesce.inl:57