Nui
switch.hpp
Go to the documentation of this file.
1 #pragma once
2 
7 
8 #include <utility>
9 
10 namespace Nui::Elements
11 {
12  namespace Detail
13  {
14  template <typename T>
15  struct CaseBaked
16  {
17  T value;
19  };
20 
21  template <typename T>
22  struct Case
23  {
24  T value;
25 
26  auto operator()(Nui::ElementRenderer renderer) &&
27  {
28  return CaseBaked<T>{std::move(value), std::move(renderer)};
29  }
30  };
31 
32  struct DefaultBaked
33  {
35  };
36 
37  struct Default
38  {
39  auto operator()(Nui::ElementRenderer renderer) &&
40  {
41  return DefaultBaked{std::move(renderer)};
42  }
43  };
44  }
45 
46  template <typename T>
47  inline auto case_(T&& value)
48  {
49  return Detail::Case<T>{std::forward<T>(value)};
50  }
51  inline auto default_()
52  {
53  return Detail::Default{};
54  }
55 
56  template <typename T>
57  constexpr auto switch_(Observed<T>& observed)
58  {
59  return overloaded{
60  [&observed](auto&&... bakedCases) {
61  return fragment(
62  observe(observed),
63  [&observed, ... cases = std::forward<std::decay_t<decltype(bakedCases)>>(bakedCases)] {
64  Nui::ElementRenderer renderer;
65  return !((cases.value == observed.value() ? (renderer = cases.renderer, true) : false) || ...)
66  ? [](auto&, auto const&) -> std::shared_ptr<Dom::Element> {
67  Console::warn("Nui::switch_ error! No case matched and no default case was provided!");
68  return nullptr;
69  } : renderer;
70  });
71  },
72  [&observed](Detail::DefaultBaked bakedDefault, auto&&... bakedCases) {
73  return fragment(
74  observe(observed),
75  [&observed,
76  bakedDefault = std::move(bakedDefault),
77  ... cases = std::forward<std::decay_t<decltype(bakedCases)>>(bakedCases)]() {
78  Nui::ElementRenderer renderer;
79  return !((cases.value == observed.value() ? (renderer = cases.renderer, true) : false) || ...)
80  ? bakedDefault.renderer
81  : renderer;
82  });
83  },
84  };
85  }
86 }
static void warn(Args &&... args)
Definition: console.hpp:23
ContainedT const & value() const
Definition: observed_value.hpp:313
Definition: observed_value.hpp:1202
Definition: comment.hpp:10
constexpr auto fragment(ParametersT &&... params)
A fragment is a collection of elements that can be inserted into a parent without an enclosing tag.
Definition: fragment.hpp:15
constexpr auto switch_(Observed< T > &observed)
Definition: switch.hpp:57
auto default_()
Definition: switch.hpp:51
auto case_(T &&value)
Definition: switch.hpp:47
std::function< std::shared_ptr< Dom::Element >(Dom::Element &, Renderer const &)> ElementRenderer
Definition: element_renderer.hpp:11
Definition: switch.hpp:16
Nui::ElementRenderer renderer
Definition: switch.hpp:18
T value
Definition: switch.hpp:17
Definition: switch.hpp:23
auto operator()(Nui::ElementRenderer renderer) &&
Definition: switch.hpp:26
T value
Definition: switch.hpp:24
Definition: switch.hpp:33
Nui::ElementRenderer renderer
Definition: switch.hpp:34
Definition: switch.hpp:38
auto operator()(Nui::ElementRenderer renderer) &&
Definition: switch.hpp:39
Definition: overloaded.hpp:7