FTXUI 7.0.3
C++ functional terminal UI.
Loading...
Searching...
No Matches
src/ftxui/dom/table.cpp
Go to the documentation of this file.
1// Copyright 2021 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
4#include "ftxui/dom/table.hpp"
5
6#include <algorithm> // for max
7#include <initializer_list> // for initializer_list
8#include <memory> // for allocator, shared_ptr, allocator_traits<>::value_type
9#include <utility> // for move, swap
10#include <vector> // for vector
11
12#include "ftxui/dom/elements.hpp" // for Element, operator|, text, separatorCharacter, Elements, BorderStyle, Decorator, emptyElement, size, gridbox, EQUAL, flex, flex_shrink, HEIGHT, WIDTH
13
14namespace ftxui {
15namespace {
16
17bool IsCell(int x, int y) {
18 return x % 2 == 1 && y % 2 == 1;
19}
20
21// NOLINTNEXTLINE
22static std::string table_charset[6][6] = {
23 {"┌", "┐", "└", "┘", "─", "│"}, // LIGHT
24 {"┏", "┓", "┗", "┛", "╍", "╏"}, // DASHED
25 {"┏", "┓", "┗", "┛", "━", "┃"}, // HEAVY
26 {"╔", "╗", "╚", "╝", "═", "║"}, // DOUBLE
27 {"╭", "╮", "╰", "╯", "─", "│"}, // ROUNDED
28 {" ", " ", " ", " ", " ", " "}, // EMPTY
29};
30
31// Résout les indices négatifs en comptant depuis la fin.
32int Wrap(int input, int modulo) {
33 return input < 0 ? input + modulo : input;
34}
35
36bool InRange(int input, int modulo) {
37 return input >= 0 && input < modulo;
38}
39
40void Order(int& a, int& b) {
41 if (a >= b) {
42 std::swap(a, b);
43 }
44}
45
46} // namespace
47
48/// @brief Crée une table vide.
49Table::Table() {
50 Initialize({});
51}
52
53/// @brief Crée une table à partir d'un vecteur de vecteurs de chaînes de caractères.
54/// @param input Les données d'entrée.
55Table::Table(const std::vector<std::vector<std::string>>& input) {
56 std::vector<std::vector<Element>> output;
57 output.reserve(input.size());
58 for (const auto& row : input) {
59 output.emplace_back();
60 auto& output_row = output.back();
61 output_row.reserve(row.size());
62 for (const auto& cell : row) {
63 output_row.push_back(text(std::move(cell)));
64 }
65 }
66 Initialize(std::move(output));
67}
68
69/// @brief Crée une table à partir d'un vecteur de vecteurs d'éléments.
70/// @param input Les éléments d'entrée.
71Table::Table(std::vector<std::vector<Element>> input) {
72 Initialize(std::move(input));
73}
74
75/// @brief Crée un tableau à partir d'une liste de listes de chaînes.
76/// @param init Les données d'entrée.
77Table::Table(std::initializer_list<std::vector<std::string>> init) {
78 std::vector<std::vector<Element>> input;
79 for (const auto& row : init) {
80 std::vector<Element> output_row;
81 output_row.reserve(row.size());
82 for (const auto& cell : row) {
83 output_row.push_back(text(cell));
84 }
85 input.push_back(std::move(output_row));
86 }
87 Initialize(std::move(input));
88}
89
90// privé
91void Table::Initialize(std::vector<std::vector<Element>> input) {
92 input_dim_y_ = static_cast<int>(input.size());
93 input_dim_x_ = 0;
94 for (auto& row : input) {
95 input_dim_x_ = std::max(input_dim_x_, int(row.size()));
96 }
97
98 dim_y_ = 2 * input_dim_y_ + 1;
99 dim_x_ = 2 * input_dim_x_ + 1;
100
101 // Réserve de l'espace.
102 elements_.resize(dim_y_);
103 for (int y = 0; y < dim_y_; ++y) {
104 elements_[y].resize(dim_x_);
105 }
106
107 // Transfère les elements_ de |input| vers |elements_|.
108 {
109 int y = 1;
110 for (auto& row : input) {
111 int x = 1;
112 for (auto& cell : row) {
113 elements_[y][x] = std::move(cell);
114 x += 2;
115 }
116 y += 2;
117 }
118 }
119
120 // Ajoute un élément vide pour la bordure.
121 for (int y = 0; y < dim_y_; ++y) {
122 for (int x = 0; x < dim_x_; ++x) {
123 auto& element = elements_[y][x];
124
125 if (IsCell(x, y)) {
126 if (!element) {
127 element = emptyElement();
128 }
129 continue;
130 }
131
132 element = emptyElement();
133 }
134 }
135}
136
137/// @brief Sélectionne une ligne de la table.
138/// @param index L'indice de la ligne à sélectionner.
139/// @note Vous pouvez utiliser des indices négatifs pour sélectionner à partir de la fin.
140TableSelection Table::SelectRow(int index) {
141 return SelectRectangle(0, -1, index, index);
142}
143
144/// @brief Sélectionne une plage de lignes de la table.
145/// @param row_min La première ligne à sélectionner.
146/// @param row_max La dernière ligne à sélectionner.
147/// @note Vous pouvez utiliser des indices négatifs pour sélectionner à partir de la fin.
148TableSelection Table::SelectRows(int row_min, int row_max) {
149 return SelectRectangle(0, -1, row_min, row_max);
150}
151
152/// @brief Sélectionne une colonne de la table.
153/// @param index L'indice de la colonne à sélectionner.
154/// @note Vous pouvez utiliser des indices négatifs pour sélectionner à partir de la fin.
155TableSelection Table::SelectColumn(int index) {
156 return SelectRectangle(index, index, 0, -1);
157}
158
159/// @brief Sélectionne une plage de colonnes de la table.
160/// @param column_min La première colonne à sélectionner.
161/// @param column_max La dernière colonne à sélectionner.
162/// @note Vous pouvez utiliser des indices négatifs pour sélectionner à partir de la fin.
163TableSelection Table::SelectColumns(int column_min, int column_max) {
164 return SelectRectangle(column_min, column_max, 0, -1);
165}
166
167/// @brief Sélectionne une cellule de la table.
168/// @param column La colonne de la cellule à sélectionner.
169/// @param row La ligne de la cellule à sélectionner.
170/// @note Vous pouvez utiliser des indices négatifs pour sélectionner à partir de la fin.
171TableSelection Table::SelectCell(int column, int row) {
172 return SelectRectangle(column, column, row, row);
173}
174
175/// @brief Sélectionne un rectangle de la table.
176/// @param column_min La première colonne à sélectionner.
177/// @param column_max La dernière colonne à sélectionner.
178/// @param row_min La première ligne à sélectionner.
179/// @param row_max La dernière ligne à sélectionner.
180/// @note Vous pouvez utiliser des indices négatifs pour sélectionner à partir de la fin.
181TableSelection Table::SelectRectangle(int column_min,
182 int column_max,
183 int row_min,
184 int row_max) {
185 TableSelection output; // NOLINT
186 output.table_ = this;
187
188 column_min = Wrap(column_min, input_dim_x_);
189 column_max = Wrap(column_max, input_dim_x_);
190 row_min = Wrap(row_min, input_dim_y_);
191 row_max = Wrap(row_max, input_dim_y_);
192
193 // Les indices hors limites ne sélectionnent rien.
194 if (!InRange(column_min, input_dim_x_) ||
195 !InRange(column_max, input_dim_x_) || !InRange(row_min, input_dim_y_) ||
196 !InRange(row_max, input_dim_y_)) {
197 output.x_min_ = 0;
198 output.x_max_ = -1;
199 output.y_min_ = 0;
200 output.y_max_ = -1;
201 return output;
202 }
203
204 Order(column_min, column_max);
205 Order(row_min, row_max);
206
207 output.x_min_ = 2 * column_min;
208 output.x_max_ = 2 * column_max + 2;
209 output.y_min_ = 2 * row_min;
210 output.y_max_ = 2 * row_max + 2;
211 return output;
212}
213
214/// @brief Sélectionne toute la table.
215TableSelection Table::SelectAll() {
216 TableSelection output; // NOLINT
217 output.table_ = this;
218 output.x_min_ = 0;
219 output.x_max_ = dim_x_ - 1;
220 output.y_min_ = 0;
221 output.y_max_ = dim_y_ - 1;
222 return output;
223}
224
225/// @brief Rend la table.
226/// @return La table rendue. C'est un élément que vous pouvez dessiner.
227Element Table::Render() {
228 for (int y = 0; y < dim_y_; ++y) {
229 for (int x = 0; x < dim_x_; ++x) {
230 auto& it = elements_[y][x];
231
232 // Ligne
233 if ((x + y) % 2 == 1) {
234 it = std::move(it) | flex;
235 continue;
236 }
237
238 // Cellules
239 if ((x % 2) == 1 && (y % 2) == 1) {
240 it = std::move(it) | flex_shrink;
241 continue;
242 }
243
244 // Coins
245 it = std::move(it) | size(WIDTH, EQUAL, 0) | size(HEIGHT, EQUAL, 0);
246 }
247 }
248 dim_x_ = 0;
249 dim_y_ = 0;
250 return gridbox(std::move(elements_));
251}
252
253/// @brief Applique le décorateur à la sélection.
254/// Ceci décore à la fois les cellules, les lignes et les coins.
255/// @param decorator Le décorateur à appliquer.
256// NOLINTNEXTLINE
257void TableSelection::Decorate(const Decorator& decorator) {
258 for (int y = y_min_; y <= y_max_; ++y) {
259 for (int x = x_min_; x <= x_max_; ++x) {
260 Element& e = table_->elements_[y][x];
261 e = std::move(e) | decorator;
262 }
263 }
264}
265
266/// @brief Applique le décorateur à la sélection.
267/// @param decorator Le décorateur à appliquer.
268/// Ceci décore uniquement les cellules.
269// NOLINTNEXTLINE
270void TableSelection::DecorateCells(const Decorator& decorator) {
271 for (int y = y_min_; y <= y_max_; ++y) {
272 for (int x = x_min_; x <= x_max_; ++x) {
273 if (y % 2 == 1 && x % 2 == 1) {
274 Element& e = table_->elements_[y][x];
275 e = std::move(e) | decorator;
276 }
277 }
278 }
279}
280
281/// @brief Applique le décorateur à la sélection.
282/// Ceci décore uniquement les lignes modulo `modulo` avec un décalage de `shift`.
283/// @param decorator Le décorateur à appliquer.
284/// @param modulo Le modulo des lignes à décorer.
285/// @param shift Le décalage des lignes à décorer.
286// NOLINTNEXTLINE
287void TableSelection::DecorateAlternateColumn(const Decorator& decorator,
288 int modulo,
289 int shift) {
290 for (int y = y_min_; y <= y_max_; ++y) {
291 for (int x = x_min_; x <= x_max_; ++x) {
292 if (y % 2 == 1 && (x / 2) % modulo == shift) {
293 Element& e = table_->elements_[y][x];
294 e = std::move(e) | decorator;
295 }
296 }
297 }
298}
299
300/// @brief Applique le décorateur à la sélection.
301/// Ceci décore uniquement les lignes modulo `modulo` avec un décalage de `shift`.
302/// @param decorator Le décorateur à appliquer.
303/// @param modulo Le modulo des lignes à décorer.
304/// @param shift Le décalage des lignes à décorer.
305// NOLINTNEXTLINE
306void TableSelection::DecorateAlternateRow(const Decorator& decorator,
307 int modulo,
308 int shift) {
309 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
310 for (int x = x_min_; x <= x_max_; ++x) {
311 if (y % 2 == 1 && (y / 2) % modulo == shift) {
312 Element& e = table_->elements_[y][x];
313 e = std::move(e) | decorator;
314 }
315 }
316 }
317}
318
319/// @brief Applique le décorateur à la sélection.
320/// Ceci décore uniquement les coins modulo `modulo` avec un décalage de `shift`.
321/// @param decorator Le décorateur à appliquer.
322/// @param modulo Le modulo des coins à décorer.
323/// @param shift Le décalage des coins à décorer.
324// NOLINTNEXTLINE
325void TableSelection::DecorateCellsAlternateColumn(const Decorator& decorator,
326 int modulo,
327 int shift) {
328 for (int y = y_min_; y <= y_max_; ++y) {
329 for (int x = x_min_; x <= x_max_; ++x) {
330 if (y % 2 == 1 && x % 2 == 1 && ((x / 2) % modulo == shift)) {
331 Element& e = table_->elements_[y][x];
332 e = std::move(e) | decorator;
333 }
334 }
335 }
336}
337
338/// @brief Applique le décorateur à la sélection.
339/// Ceci décore uniquement les coins modulo `modulo` avec un décalage de `shift`.
340/// @param decorator Le décorateur à appliquer.
341/// @param modulo Le modulo des coins à décorer.
342/// @param shift Le décalage des coins à décorer.
343// NOLINTNEXTLINE
344void TableSelection::DecorateCellsAlternateRow(const Decorator& decorator,
345 int modulo,
346 int shift) {
347 for (int y = y_min_; y <= y_max_; ++y) {
348 for (int x = x_min_; x <= x_max_; ++x) {
349 if (y % 2 == 1 && x % 2 == 1 && ((y / 2) % modulo == shift)) {
350 Element& e = table_->elements_[y][x];
351 e = std::move(e) | decorator;
352 }
353 }
354 }
355}
356
357/// @brief Applique le `decorator` à la bordure de la sélection.
358/// @param decorator Le décorateur à appliquer.
359void TableSelection::DecorateBorder(const Decorator& decorator) {
360 for (int x = x_min_; x <= x_max_; ++x) {
361 table_->elements_[y_min_][x] =
362 std::move(table_->elements_[y_min_][x]) | decorator;
363 table_->elements_[y_max_][x] =
364 std::move(table_->elements_[y_max_][x]) | decorator;
365 }
366 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
367 table_->elements_[y][x_min_] =
368 std::move(table_->elements_[y][x_min_]) | decorator;
369 table_->elements_[y][x_max_] =
370 std::move(table_->elements_[y][x_max_]) | decorator;
371 }
372}
373
374/// @brief Applique le `decorator` à la bordure gauche de la sélection.
375/// @param decorator Le décorateur à appliquer.
376void TableSelection::DecorateBorderLeft(const Decorator& decorator) {
377 for (int y = y_min_; y <= y_max_; y++) {
378 table_->elements_[y][x_min_] =
379 std::move(table_->elements_[y][x_min_]) | decorator;
380 }
381}
382
383/// @brief Applique le `decorator` à la bordure droite de la sélection.
384/// @param decorator Le décorateur à appliquer.
385void TableSelection::DecorateBorderRight(const Decorator& decorator) {
386 for (int y = y_min_; y <= y_max_; y++) {
387 table_->elements_[y][x_max_] =
388 std::move(table_->elements_[y][x_max_]) | decorator;
389 }
390}
391
392/// @brief Applique le `decorator` à la bordure supérieure de la sélection.
393/// @param decorator Le décorateur à appliquer.
394void TableSelection::DecorateBorderTop(const Decorator& decorator) {
395 for (int x = x_min_; x <= x_max_; x++) {
396 table_->elements_[y_min_][x] =
397 std::move(table_->elements_[y_min_][x]) | decorator;
398 }
399}
400
401/// @brief Applique le `decorator` à la bordure inférieure de la sélection.
402/// @param decorator Le décorateur à appliquer.
403void TableSelection::DecorateBorderBottom(const Decorator& decorator) {
404 for (int x = x_min_; x <= x_max_; x++) {
405 table_->elements_[y_max_][x] =
406 std::move(table_->elements_[y_max_][x]) | decorator;
407 }
408}
409
410/// @brief Applique le `decorator` aux séparateurs de la sélection.
411/// @param decorator Le décorateur à appliquer.
412void TableSelection::DecorateSeparator(const Decorator& decorator) {
413 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
414 for (int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
415 if (y % 2 == 0 || x % 2 == 0) {
416 table_->elements_[y][x] =
417 std::move(table_->elements_[y][x]) | decorator;
418 }
419 }
420 }
421}
422
423/// @brief Applique le `decorator` aux séparateurs verticaux de la sélection.
424/// @param decorator Le décorateur à appliquer.
425void TableSelection::DecorateSeparatorVertical(const Decorator& decorator) {
426 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
427 for (int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
428 if (x % 2 == 0) {
429 table_->elements_[y][x] =
430 std::move(table_->elements_[y][x]) | decorator;
431 }
432 }
433 }
434}
435
436/// @brief Applique le `decorator` aux séparateurs horizontaux de la sélection.
437/// @param decorator Le décorateur à appliquer.
438void TableSelection::DecorateSeparatorHorizontal(const Decorator& decorator) {
439 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
440 for (int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
441 if (y % 2 == 0) {
442 table_->elements_[y][x] =
443 std::move(table_->elements_[y][x]) | decorator;
444 }
445 }
446 }
447}
448
449/// @brief Applique une `bordure` autour de la sélection.
450/// @param border Le style de bordure à appliquer.
451void TableSelection::Border(BorderStyle border) {
452 if (x_min_ > x_max_ || y_min_ > y_max_) {
453 return;
454 }
455
456 BorderLeft(border);
457 BorderRight(border);
458 BorderTop(border);
459 BorderBottom(border);
460
461 // NOLINTNEXTLINE
462 table_->elements_[y_min_][x_min_] =
463 text(table_charset[border][0]) | automerge;
464 // NOLINTNEXTLINE
465 table_->elements_[y_min_][x_max_] =
466 text(table_charset[border][1]) | automerge;
467 // NOLINTNEXTLINE
468 table_->elements_[y_max_][x_min_] =
469 text(table_charset[border][2]) | automerge;
470 // NOLINTNEXTLINE
471 table_->elements_[y_max_][x_max_] =
472 text(table_charset[border][3]) | automerge;
473}
474
475/// @brief Applique une `border` autour de la sélection.
476/// @param border Le style de bordure à appliquer.
477/// @param decorator Le décorateur à appliquer.
478void TableSelection::Border(BorderStyle border, const Decorator& decorator) {
479 Border(border);
480 DecorateBorder(decorator);
481}
482
483/// @brief Dessine des lignes de séparation dans la sélection.
484/// @param border Le style de bordure à appliquer.
485void TableSelection::Separator(BorderStyle border) {
486 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
487 for (int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
488 if (y % 2 == 0 || x % 2 == 0) {
489 Element& e = table_->elements_[y][x];
490 e = (y % 2 == 1) ? separatorCharacter(table_charset[border][5]) |
491 automerge // NOLINT
492 : separatorCharacter(table_charset[border][4]) |
493 automerge; // NOLINT
494 }
495 }
496 }
497}
498
499/// @brief Dessine des lignes de séparation dans la sélection.
500/// @param border Le style de bordure à appliquer.
501/// @param decorator Le décorateur à appliquer.
502void TableSelection::Separator(BorderStyle border, const Decorator& decorator) {
503 Separator(border);
504 DecorateSeparator(decorator);
505}
506
507/// @brief Dessine des lignes de séparation verticales dans la sélection.
508/// @param border Le style de bordure à appliquer.
509void TableSelection::SeparatorVertical(BorderStyle border) {
510 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
511 for (int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
512 if (x % 2 == 0) {
513 table_->elements_[y][x] =
514 separatorCharacter(table_charset[border][5]) | automerge; // NOLINT
515 }
516 }
517 }
518}
519
520/// @brief Dessine des lignes de séparation verticales dans la sélection.
521/// @param border Le style de bordure à appliquer.
522/// @param decorator Le décorateur à appliquer.
523void TableSelection::SeparatorVertical(BorderStyle border,
524 const Decorator& decorator) {
525 SeparatorVertical(border);
526 DecorateSeparatorVertical(decorator);
527}
528
529/// @brief Dessine des lignes de séparation horizontales dans la sélection.
530/// @param border Le style de bordure à appliquer.
531void TableSelection::SeparatorHorizontal(BorderStyle border) {
532 for (int y = y_min_ + 1; y <= y_max_ - 1; ++y) {
533 for (int x = x_min_ + 1; x <= x_max_ - 1; ++x) {
534 if (y % 2 == 0) {
535 table_->elements_[y][x] =
536 separatorCharacter(table_charset[border][4]) | automerge; // NOLINT
537 }
538 }
539 }
540}
541
542/// @brief Dessine des lignes de séparation horizontales dans la sélection.
543/// @param border Le style de bordure à appliquer.
544/// @param decorator Le décorateur à appliquer.
545void TableSelection::SeparatorHorizontal(BorderStyle border,
546 const Decorator& decorator) {
547 SeparatorHorizontal(border);
548 DecorateSeparatorHorizontal(decorator);
549}
550
551/// @brief Dessine des lignes de séparation sur le côté gauche de la sélection.
552/// @param border Le style de bordure à appliquer.
553void TableSelection::BorderLeft(BorderStyle border) {
554 for (int y = y_min_; y <= y_max_; y++) {
555 table_->elements_[y][x_min_] =
556 separatorCharacter(table_charset[border][5]) | automerge; // NOLINT
557 }
558}
559
560/// @brief Dessine des lignes de séparation sur le côté gauche de la sélection.
561/// @param border Le style de bordure à appliquer.
562/// @param decorator Le décorateur à appliquer.
563void TableSelection::BorderLeft(BorderStyle border,
564 const Decorator& decorator) {
565 BorderLeft(border);
566 DecorateBorderLeft(decorator);
567}
568
569/// @brief Dessine des lignes de séparation sur le côté droit de la sélection.
570/// @param border Le style de bordure à appliquer.
571void TableSelection::BorderRight(BorderStyle border) {
572 for (int y = y_min_; y <= y_max_; y++) {
573 table_->elements_[y][x_max_] =
574 separatorCharacter(table_charset[border][5]) | automerge; // NOLINT
575 }
576}
577
578/// @brief Dessine des lignes de séparation sur le côté droit de la sélection.
579/// @param border Le style de bordure à appliquer.
580/// @param decorator Le décorateur à appliquer.
581void TableSelection::BorderRight(BorderStyle border,
582 const Decorator& decorator) {
583 BorderRight(border);
584 DecorateBorderRight(decorator);
585}
586
587/// @brief Dessine des lignes de séparation sur le côté supérieur de la sélection.
588/// @param border Le style de bordure à appliquer.
589void TableSelection::BorderTop(BorderStyle border) {
590 for (int x = x_min_; x <= x_max_; x++) {
591 table_->elements_[y_min_][x] =
592 separatorCharacter(table_charset[border][4]) | automerge; // NOLINT
593 }
594}
595
596/// @brief Dessine des lignes de séparation sur le côté supérieur de la sélection.
597/// @param border Le style de bordure à appliquer.
598/// @param decorator Le décorateur à appliquer.
599void TableSelection::BorderTop(BorderStyle border, const Decorator& decorator) {
600 BorderTop(border);
601 DecorateBorderTop(decorator);
602}
603
604/// @brief Dessine des lignes de séparation sur le côté inférieur de la sélection.
605/// @param border Le style de bordure à appliquer.
606void TableSelection::BorderBottom(BorderStyle border) {
607 for (int x = x_min_; x <= x_max_; x++) {
608 table_->elements_[y_max_][x] =
609 separatorCharacter(table_charset[border][4]) | automerge; // NOLINT
610 }
611}
612
613/// @brief Dessine des lignes de séparation sur le côté inférieur de la sélection.
614/// @param border Le style de bordure à appliquer.
615/// @param decorator Le décorateur à appliquer.
616void TableSelection::BorderBottom(BorderStyle border,
617 const Decorator& decorator) {
618 BorderBottom(border);
619 DecorateBorderBottom(decorator);
620}
621
622} // namespace ftxui
Component Wrap(std::string name, Component component)
Definition gallery.cpp:18
BorderStyle
BorderStyle est une énumération qui représente les différents styles de bordures pouvant être appliqu...
Definition elements.hpp:38
L'espace de noms FTXUI ftxui::
Definition animation.hpp:11
std::shared_ptr< Node > Element
Definition elements.hpp:25
std::function< Element(Element)> Decorator
Definition elements.hpp:27
int y
Definition elements.hpp:134
const Element & element
Definition node.hpp:94