diff --git a/include/ftxui/dom/take_any_args.hpp b/include/ftxui/dom/take_any_args.hpp index 52c83248d..1677905b8 100644 --- a/include/ftxui/dom/take_any_args.hpp +++ b/include/ftxui/dom/take_any_args.hpp @@ -5,7 +5,11 @@ #define FTXUI_DOM_TAKE_ANY_ARGS_HPP // IWYU pragma: private, include "ftxui/dom/elements.hpp" +#include #include +#include +#include +#include namespace ftxui { @@ -17,13 +21,34 @@ inline void Merge(Elements& container, Element element) { container.push_back(std::move(element)); } -template <> -inline void Merge(Elements& container, Elements elements) { +template +concept ElementRange = + std::ranges::range && + std::same_as, Element>; + +template +inline void Merge(Elements& container, T elements) { for (auto& element : elements) { container.push_back(std::move(element)); } } +template <> +inline void Merge(Elements& container, std::stack elements) { + while (!elements.empty()) { + container.push_back(std::move(elements.top())); + elements.pop(); + } +} + +template <> +inline void Merge(Elements& container, std::queue elements) { + while (!elements.empty()) { + container.push_back(std::move(elements.back())); + elements.pop(); + } +} + // Turn a set of arguments into a vector. template Elements unpack(Args... args) { diff --git a/src/ftxui/dom/hbox_test.cpp b/src/ftxui/dom/hbox_test.cpp index 982bfde45..217d22c32 100644 --- a/src/ftxui/dom/hbox_test.cpp +++ b/src/ftxui/dom/hbox_test.cpp @@ -2,9 +2,12 @@ // Use of this source code is governed by the MIT license that can be found in // the LICENSE file. #include // for Test, TestInfo (ptr only), EXPECT_EQ, Message, TEST, TestPartResult -#include // for size_t -#include // for allocator, basic_string, string -#include // for vector +#include // for array +#include // for size_t +#include // for stack +#include // for allocator, basic_string, string +#include // for unordered_set +#include // for vector #include "ftxui/dom/elements.hpp" // for text, operator|, Element, flex_grow, flex_shrink, hbox #include "ftxui/dom/node.hpp" // for Render @@ -358,5 +361,39 @@ TEST(HBoxTest, FlexGrow_NoFlex_FlewShrink) { } } +TEST(HBoxTest, FromElementsContainer) { + Elements elements_vector{text("0"), text("1")}; + + std::array elements_array{text("0"), text("1")}; + + std::deque elements_deque{text("0"), text("1")}; + + std::stack elements_stack; + elements_stack.push(text("1")); + elements_stack.push(text("0")); + + std::queue elements_queue; + elements_queue.emplace(text("0")); + elements_queue.emplace(text("1")); + + const std::vector collection_hboxes{ + hbox(std::move(elements_vector)), hbox(std::move(elements_array)), + hbox(std::move(elements_stack)), hbox(std::move(elements_deque)), + hbox(std::move(elements_queue)), + }; + + for (const Element& collection_hbox : collection_hboxes) { + Screen screen(2, 1); + Render(screen, collection_hbox); + EXPECT_EQ("01", screen.ToString()); + } + + // Exception: unordered set, which has no guaranteed order. + std::unordered_set elements_set{text("0"), text("0")}; + Screen screen(2, 1); + Render(screen, hbox(elements_set)); + EXPECT_EQ("00", screen.ToString()); +}; + } // namespace ftxui // NOLINTEND