Skip to content

Commit

Permalink
Copying the initializer list.
Browse files Browse the repository at this point in the history
  • Loading branch information
rmpowell77 committed Dec 25, 2023
1 parent 00c77bb commit 2610e49
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
3 changes: 3 additions & 0 deletions cmake/compiler.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ macro(wxUI_SetupCompilerForTarget arg)
set_property(TARGET ${arg} PROPERTY COMPILE_WARNING_AS_ERROR ON)
endmacro()

# Adding address sanitizer (see https://stackoverflow.com/questions/44320465/whats-the-proper-way-to-enable-addresssanitizer-in-cmake-that-works-in-xcode)
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address)
22 changes: 20 additions & 2 deletions include/wxUI/ForEach.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ SOFTWARE.
#include "Layout.h"

namespace wxUI::details {
// clang-format off
// Big help to Dennis Kormalev (https://www.linkedin.com/in/dkormalev/) for the example at:
// https://godbolt.org/z/sv5seP79q
template <typename, typename, typename = void>
Expand All @@ -34,12 +35,28 @@ struct CanApply : std::false_type { };
template <typename F, typename... Arg>
struct CanApply<F, std::tuple<Arg...>, std::enable_if_t<std::is_invocable_v<F, Arg...>, void>> : std::true_type { };

template <typename F, typename Arg, typename = void>
struct invoke_apply_result : std::invoke_result<F, Arg> { };

template <typename F, typename... Args1>
struct invoke_apply_result<F, std::tuple<Args1...>, std::enable_if_t<std::is_invocable_v<F, Args1...>, void>> : std::invoke_result<F, Args1...> { };

template <typename F, typename... Args>
using invoke_apply_result_t = typename invoke_apply_result<F, Args...>::type;

template <typename F, typename Arg>
concept ForEachFunction = CreateAndAddable<typename invoke_apply_result<F, Arg>::type>;
// clang-format on

}

namespace wxUI {

// clang-format off
template <std::ranges::input_range Range, typename Function>
requires(details::ForEachFunction<Function, std::ranges::range_value_t<Range>>)
struct ForEach {
// clang-format on

ForEach(Range&& args, Function&& createFunction)
: args(std::forward<Range>(args))
Expand Down Expand Up @@ -72,11 +89,12 @@ struct ForEach {
Function createFunction;
};

// initializer_list is like a string_view, we want a copy. So deduce as vector so we have a copy
template <typename Function, typename T>
ForEach(std::initializer_list<T>, Function) -> ForEach<std::initializer_list<T>, Function>;
ForEach(std::initializer_list<T>, Function&&) -> ForEach<std::vector<T>, Function>;

template <typename Function, typename T>
ForEach(wxSizerFlags const& flags, std::initializer_list<T>, Function) -> ForEach<std::initializer_list<T>, Function>;
ForEach(wxSizerFlags const& flags, std::initializer_list<T>, Function&&) -> ForEach<std::vector<T>, Function>;

template <typename T, typename Function>
auto VForEach(std::initializer_list<T> args, Function&& function)
Expand Down

0 comments on commit 2610e49

Please sign in to comment.