TermOx
array.hpp
1 #ifndef TERMOX_WIDGET_ARRAY_HPP
2 #define TERMOX_WIDGET_ARRAY_HPP
3 #include <array>
4 #include <cstddef>
5 #include <functional>
6 #include <type_traits>
7 #include <utility>
8 
9 #include <termox/widget/layouts/horizontal.hpp>
10 #include <termox/widget/layouts/stack.hpp>
11 #include <termox/widget/layouts/vertical.hpp>
12 
13 namespace ox {
14 
16 
17 template <typename Layout_t, std::size_t N>
18 class Array : public Layout_t {
19  public:
21  template <typename... Args>
22  explicit Array(Args&&... args)
23  : refs_{create_n_children(std::make_index_sequence<N>(),
24  std::forward<Args>(args)...)}
25  {}
26 
27  // sfinae enable this only if Widget_t has a constructor taking a Parameters
28  template <
29  typename Child_t = typename Layout_t::Child_t,
30  typename = std::enable_if_t<
31  std::is_constructible_v<Child_t, typename Child_t::Parameters>,
32  void>>
33  explicit Array(
34  std::array<typename Layout_t::Child_t::Parameters, N> parameters)
35  : refs_{create_n_children(std::make_index_sequence<N>(),
36  std::move(parameters))}
37  {}
38 
39  explicit Array(
40  std::array<std::unique_ptr<typename Layout_t::Child_t>, N> widget_ptrs)
41  : refs_{create_n_children(std::make_index_sequence<N>(),
42  std::move(widget_ptrs))}
43  {}
44 
45  public:
47  template <std::size_t Index>
48  [[nodiscard]] auto get() -> auto&
49  {
50  return std::get<Index>(refs_).get();
51  }
52 
54  template <std::size_t Index>
55  [[nodiscard]] auto get() const -> auto const&
56  {
57  return std::get<Index>(refs_).get();
58  }
59 
60  private:
61  using References =
62  std::array<std::reference_wrapper<typename Layout_t::Child_t>, N>;
63  References refs_;
64 
65  private:
66  template <std::size_t... Is, typename... Args>
67  [[nodiscard]] auto create_n_children(std::index_sequence<Is...>,
68  Args&&... args) -> References
69  {
70  return {this->insert_child(std::make_unique<typename Layout_t::Child_t>(
71  std::forward<Args>(args)...),
72  Is)...};
73  }
74 
75  template <std::size_t... Is>
76  [[nodiscard]] auto create_n_children(
77  std::index_sequence<Is...>,
78  std::array<typename Layout_t::Child_t::Parameters, N> parameters)
79  -> References
80  {
81  return {this->insert_child(std::make_unique<typename Layout_t::Child_t>(
82  std::move(parameters[Is])),
83  Is)...};
84  }
85 
86  template <std::size_t... Is>
87  [[nodiscard]] auto create_n_children(
88  std::index_sequence<Is...>,
89  std::array<std::unique_ptr<typename Layout_t::Child_t>, N> widget_ptrs)
90  -> References
91  {
92  return {this->insert_child(std::move(widget_ptrs[Is]), Is)...};
93  }
94 
95  private:
96  using Layout_t::append_child;
97  using Layout_t::delete_all_children;
98  using Layout_t::insert_child;
99  using Layout_t::make_child;
100  using Layout_t::remove_and_delete_child;
101  using Layout_t::remove_and_delete_child_at;
102  using Layout_t::remove_and_delete_child_if;
103  using Layout_t::remove_child;
104  using Layout_t::remove_child_at;
105  using Layout_t::remove_child_if;
106  using Layout_t::swap_children;
107 };
108 
110 template <typename Layout_t, std::size_t N>
111 [[nodiscard]] auto array() -> std::unique_ptr<Array<Layout_t, N>>
112 {
113  return std::make_unique<Array<Layout_t, N>>();
114 }
115 
117 template <typename Layout_t, std::size_t N>
118 [[nodiscard]] auto array(
119  std::array<typename Layout_t::Child_t::Parameters, N> parameters)
120  -> std::unique_ptr<Array<Layout_t, N>>
121 {
122  return std::make_unique<Array<Layout_t, N>>(std::move(parameters));
123 }
124 
126 template <typename Layout_t, std::size_t N>
127 [[nodiscard]] auto array(
128  std::array<std::unique_ptr<typename Layout_t::Child_t::Parameters>, N>
129  parameter_ptrs) -> std::unique_ptr<Array<Layout_t, N>>
130 {
131  return std::make_unique<Array<Layout_t, N>>(std::move(parameter_ptrs));
132 }
133 
134 template <typename Widget_t, std::size_t N>
135 using VArray = Array<layout::Vertical<Widget_t>, N>;
136 
138 template <typename Widget_t, std::size_t N>
139 [[nodiscard]] auto varray() -> std::unique_ptr<VArray<Widget_t, N>>
140 {
141  return std::make_unique<VArray<Widget_t, N>>();
142 }
143 
145 template <typename Widget_t, std::size_t N>
146 [[nodiscard]] auto varray(
147  std::array<typename Widget_t::Parameters, N> parameters)
148  -> std::unique_ptr<VArray<Widget_t, N>>
149 {
150  return std::make_unique<VArray<Widget_t, N>>(std::move(parameters));
151 }
152 
154 template <typename Widget_t, std::size_t N>
155 [[nodiscard]] auto varray(std::array<std::unique_ptr<Widget_t>, N> widget_ptrs)
156  -> std::unique_ptr<VArray<Widget_t, N>>
157 {
158  return std::make_unique<VArray<Widget_t, N>>(std::move(widget_ptrs));
159 }
160 
161 template <typename Widget_t, std::size_t N>
162 using HArray = Array<layout::Horizontal<Widget_t>, N>;
163 
165 template <typename Widget_t, std::size_t N>
166 [[nodiscard]] auto harray() -> std::unique_ptr<HArray<Widget_t, N>>
167 {
168  return std::make_unique<HArray<Widget_t, N>>();
169 }
170 
172 template <typename Widget_t, std::size_t N>
173 [[nodiscard]] auto harray(
174  std::array<typename Widget_t::Parameters, N> parameters)
175  -> std::unique_ptr<HArray<Widget_t, N>>
176 {
177  return std::make_unique<HArray<Widget_t, N>>(std::move(parameters));
178 }
179 
181 template <typename Widget_t, std::size_t N>
182 [[nodiscard]] auto harray(std::array<std::unique_ptr<Widget_t>, N> widget_ptrs)
183  -> std::unique_ptr<HArray<Widget_t, N>>
184 {
185  return std::make_unique<HArray<Widget_t, N>>(std::move(widget_ptrs));
186 }
187 
188 template <typename Widget_t, std::size_t N>
189 using SArray = Array<layout::Stack<Widget_t>, N>;
190 
192 template <typename Widget_t, std::size_t N>
193 [[nodiscard]] auto sarray() -> std::unique_ptr<SArray<Widget_t, N>>
194 {
195  return std::make_unique<SArray<Widget_t, N>>();
196 }
197 
199 template <typename Widget_t, std::size_t N>
200 [[nodiscard]] auto sarray(
201  std::array<typename Widget_t::Parameters, N> parameters)
202  -> std::unique_ptr<SArray<Widget_t, N>>
203 {
204  return std::make_unique<SArray<Widget_t, N>>(std::move(parameters));
205 }
206 
208 template <typename Widget_t, std::size_t N>
209 [[nodiscard]] auto sarray(std::array<std::unique_ptr<Widget_t>, N> widget_ptrs)
210  -> std::unique_ptr<SArray<Widget_t, N>>
211 {
212  return std::make_unique<SArray<Widget_t, N>>(std::move(widget_ptrs));
213 }
214 
215 } // namespace ox
216 #endif // TERMOX_WIDGET_ARRAY_HPP
Homogeneous collection of Widgets within a Layout_t<Widget_t>.
Definition: array.hpp:18
auto get() const -> auto const &
Get child by index.
Definition: array.hpp:55
Array(Args &&... args)
args will be copied into each Widget's constructor call.
Definition: array.hpp:22
auto get() -> auto &
Get child by index.
Definition: array.hpp:48