From c4b4f33e7391725ce9de4b0a35d6d16e566a3e52 Mon Sep 17 00:00:00 2001 From: Kris Jusiak Date: Sun, 13 Aug 2023 11:14:31 -0500 Subject: [PATCH] order fixup --- README.md | 4 +- tips/338.md | 169 ++++++++++++++++++++++++++++++++++++++++++++++++---- tips/339.md | 169 ++++------------------------------------------------ 3 files changed, 171 insertions(+), 171 deletions(-) diff --git a/README.md b/README.md index d895d55..5289414 100644 --- a/README.md +++ b/README.md @@ -16,8 +16,8 @@ * [[342]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/342.md) - Did you know that C++26 added 'A nice placeholder with no name'? * [[341]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/341.md) - Did you know that C++26 added user-generated static_assert messages? * [[340]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/340.md) - Did you know that C++26 added bind front and back to NTTP callables? -* [[339]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/339.md) - Did you know about C++20 `std::next_permutation` algorithm? -* [[338]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/338.md) - Did you know that C++26 added `@, $, and `` to the basic character set? +* [[339]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/339.md) - Did you know that C++26 added `@, $, and `` to the basic character set? +* [[338]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/338.md) - Did you know about C++20 `std::next_permutation` algorithm? * [[337]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/337.md) - Did you know that run-time dispatching over type-list can be implemented many different ways? * [[336]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/336.md) - Did you know about `gnu::vector_size` extension? * [[335]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/335.md) - Did you know that you can simplify `boost.mp11` API with DSL? diff --git a/tips/338.md b/tips/338.md index 57b810f..7d9158a 100644 --- a/tips/338.md +++ b/tips/338.md @@ -1,33 +1,176 @@
Info

-* **Did you know that C++26 added `@, $, and `` to the basic character set?** +* **Did you know about C++20 `std::next_permutation` algorithm?** - * https://wg21.link/P2558R2 + * https://eel.is/c++draft/alg.permutation.generators#lib:next_permutation

Example

```cpp -auto $dollar_sign = 42; -auto @commerical_at = 42; -auto `grave_accent = 42; +[[nodiscard]] constexpr auto factorial(const auto n) { + if (n == 0 or n == 1) { + return 1; + } + auto result = 1; + for (auto i = 2; i <= n; ++i) { + result *= i; + } + return result; +} +static_assert(1 == factorial(0)); +static_assert(1 == factorial(1)); +static_assert(1 * 2 == factorial(2)); +static_assert(1 * 2 * 3 == factorial(3)); +static_assert(1 * 2 * 3 * 4 == factorial(4)); +static_assert(1 * 2 * 3 * 4 * 5 == factorial(5)); +static_assert(1 * 2 * 3 * 4 * 5 * 6 == factorial(6)); ``` +> https://godbolt.org/z/14r8EdevM +

Puzzle

-* **Can you write code snippets where added characters can be used with added value?** +* **Can you implement `permute invoke` which will try to call using all possible permutations?** + +```cpp +// TODO invoke + +template +struct Foo {}; + +constexpr auto foo() { return 1; } +constexpr auto bar(Foo<0>) { return 2; } constexpr auto baz(Foo<0>, Foo<1>) { return 3; } + +static_assert(1 == invoke(foo)); +static_assert(2 == invoke(bar, Foo<0>{})); +static_assert(3 == invoke(baz, Foo<0>{}, Foo<1>{})); +static_assert(3 == invoke(baz, Foo<1>{}, Foo<0>{})); +``` + +> https://godbolt.org/z/xeaxP46qW

Solutions

```cpp -// math -auto a = 42; -auto a` = a*2; +template +[[nodiscard]] constexpr auto permute(std::array nums) { + std::array, factorial(N)> result{}; + auto i = 0; + do { + result[i++] = nums; + } while (std::next_permutation(nums.begin(), nums.end())); + return result; +} + +namespace detail { +template constexpr auto invoke(auto fn, auto... ts) -> std::pair { return {true, fn(ts...)}; } +template constexpr auto invoke(...) -> std::pair { return {false, {}}; } + +template constexpr auto nth(auto... args) { + return [&](std::index_sequence) { + return [](decltype((void*)Ns)..., auto* nth, auto*...) { + return *nth; + }(&args...); + } + (std::make_index_sequence{}); +} +} // namespace detail + +template +constexpr auto invoke(auto fn, auto... ts) -> R { + constexpr auto ids = [](std::index_sequence) { return std::array{Ns...}; }(std::make_index_sequence{}); + constexpr auto permutations = permute(ids); + + R result; + bool called{}; + [&](std::index_sequence) { + ([&](std::index_sequence) { + std::tie(called, result) = detail::invoke(fn, detail::nth(ts...)...); + return called; + }.template operator()(std::make_index_sequence{}) or ...); + }(std::make_index_sequence{}); + return result; +} +``` + +> https://godbolt.org/z/vKbofePes + +```cpp +template +[[nodiscard]] constexpr auto permute(std::array nums) { + std::array, factorial(N)> result{}; + auto i = 0; + do { + result[i++] = nums; + } while (std::next_permutation(nums.begin(), nums.end())); + return result; +} + +namespace detail { +template constexpr auto invoke(auto fn, auto... ts) -> std::pair, decltype(fn(ts...))> { return {{}, fn(ts...)}; } +template constexpr auto invoke(...) -> std::pair, R> { return {}; } -// macros -$macro(...) ``` +template constexpr auto nth(auto... args) { + return [&](std::index_sequence) { + return [](decltype((void*)Ns)..., auto* nth, auto*...) { + return *nth; + }(&args...); + } + (std::make_index_sequence{}); +} -// twitter -auto id = @krisjusiak; +template +constexpr auto invoke_impl(auto fn, auto... ts) -> R { + if constexpr (I >= Size) { + return {}; + } else { + constexpr auto N = [&](std::index_sequence) { + return ([&](std::index_sequence) { + return decltype(detail::invoke(fn, detail::nth(ts...)...)){}.first.value; + }.template operator()(std::make_index_sequence{}) + ...); + }(std::make_index_sequence{}); + + if constexpr (N > 0) { + constexpr auto N_ = N - 1; + return [&](std::index_sequence) { + return detail::invoke(fn, detail::nth(ts...)...).second; + }(std::make_index_sequence{}); + } else { + constexpr auto chunks = Size / Split; + return invoke_impl(fn, ts...); + } + } +} +} // namespace detail + +template +constexpr auto invoke(auto fn, auto... ts) -> R { + constexpr auto ids = [](std::index_sequence) { return std::array{Ns...}; }(std::make_index_sequence{}); + constexpr auto permutations = permute(ids); + constexpr auto max_params_without_chunking = 7; + constexpr auto split = 10; + + if constexpr (sizeof...(ts) < max_params_without_chunking) { + constexpr auto N = [&](std::index_sequence) { + return ([&](std::index_sequence) { + return decltype(detail::invoke(fn, detail::nth(ts...)...)){}.first.value; + }.template operator()(std::make_index_sequence{}) + ...); + }(std::make_index_sequence{}); + + if constexpr (N > 0) { + constexpr auto N_ = N - 1; + return [&](std::index_sequence) { + return detail::invoke(fn, detail::nth(ts...)...).second; + }(std::make_index_sequence{}); + } else { + return {}; + } + } else { + return detail::invoke_impl(fn, ts...); + } +} ``` +> https://godbolt.org/z/97ejzW4Px +

diff --git a/tips/339.md b/tips/339.md index 7d9158a..57b810f 100644 --- a/tips/339.md +++ b/tips/339.md @@ -1,176 +1,33 @@
Info

-* **Did you know about C++20 `std::next_permutation` algorithm?** +* **Did you know that C++26 added `@, $, and `` to the basic character set?** - * https://eel.is/c++draft/alg.permutation.generators#lib:next_permutation + * https://wg21.link/P2558R2

Example

```cpp -[[nodiscard]] constexpr auto factorial(const auto n) { - if (n == 0 or n == 1) { - return 1; - } - auto result = 1; - for (auto i = 2; i <= n; ++i) { - result *= i; - } - return result; -} -static_assert(1 == factorial(0)); -static_assert(1 == factorial(1)); -static_assert(1 * 2 == factorial(2)); -static_assert(1 * 2 * 3 == factorial(3)); -static_assert(1 * 2 * 3 * 4 == factorial(4)); -static_assert(1 * 2 * 3 * 4 * 5 == factorial(5)); -static_assert(1 * 2 * 3 * 4 * 5 * 6 == factorial(6)); +auto $dollar_sign = 42; +auto @commerical_at = 42; +auto `grave_accent = 42; ``` -> https://godbolt.org/z/14r8EdevM -

Puzzle

-* **Can you implement `permute invoke` which will try to call using all possible permutations?** - -```cpp -// TODO invoke - -template -struct Foo {}; - -constexpr auto foo() { return 1; } -constexpr auto bar(Foo<0>) { return 2; } constexpr auto baz(Foo<0>, Foo<1>) { return 3; } - -static_assert(1 == invoke(foo)); -static_assert(2 == invoke(bar, Foo<0>{})); -static_assert(3 == invoke(baz, Foo<0>{}, Foo<1>{})); -static_assert(3 == invoke(baz, Foo<1>{}, Foo<0>{})); -``` - -> https://godbolt.org/z/xeaxP46qW +* **Can you write code snippets where added characters can be used with added value?**

Solutions

```cpp -template -[[nodiscard]] constexpr auto permute(std::array nums) { - std::array, factorial(N)> result{}; - auto i = 0; - do { - result[i++] = nums; - } while (std::next_permutation(nums.begin(), nums.end())); - return result; -} - -namespace detail { -template constexpr auto invoke(auto fn, auto... ts) -> std::pair { return {true, fn(ts...)}; } -template constexpr auto invoke(...) -> std::pair { return {false, {}}; } - -template constexpr auto nth(auto... args) { - return [&](std::index_sequence) { - return [](decltype((void*)Ns)..., auto* nth, auto*...) { - return *nth; - }(&args...); - } - (std::make_index_sequence{}); -} -} // namespace detail - -template -constexpr auto invoke(auto fn, auto... ts) -> R { - constexpr auto ids = [](std::index_sequence) { return std::array{Ns...}; }(std::make_index_sequence{}); - constexpr auto permutations = permute(ids); - - R result; - bool called{}; - [&](std::index_sequence) { - ([&](std::index_sequence) { - std::tie(called, result) = detail::invoke(fn, detail::nth(ts...)...); - return called; - }.template operator()(std::make_index_sequence{}) or ...); - }(std::make_index_sequence{}); - return result; -} -``` - -> https://godbolt.org/z/vKbofePes - -```cpp -template -[[nodiscard]] constexpr auto permute(std::array nums) { - std::array, factorial(N)> result{}; - auto i = 0; - do { - result[i++] = nums; - } while (std::next_permutation(nums.begin(), nums.end())); - return result; -} - -namespace detail { -template constexpr auto invoke(auto fn, auto... ts) -> std::pair, decltype(fn(ts...))> { return {{}, fn(ts...)}; } -template constexpr auto invoke(...) -> std::pair, R> { return {}; } +// math +auto a = 42; +auto a` = a*2; -template constexpr auto nth(auto... args) { - return [&](std::index_sequence) { - return [](decltype((void*)Ns)..., auto* nth, auto*...) { - return *nth; - }(&args...); - } - (std::make_index_sequence{}); -} +// macros +$macro(...) ``` -template -constexpr auto invoke_impl(auto fn, auto... ts) -> R { - if constexpr (I >= Size) { - return {}; - } else { - constexpr auto N = [&](std::index_sequence) { - return ([&](std::index_sequence) { - return decltype(detail::invoke(fn, detail::nth(ts...)...)){}.first.value; - }.template operator()(std::make_index_sequence{}) + ...); - }(std::make_index_sequence{}); - - if constexpr (N > 0) { - constexpr auto N_ = N - 1; - return [&](std::index_sequence) { - return detail::invoke(fn, detail::nth(ts...)...).second; - }(std::make_index_sequence{}); - } else { - constexpr auto chunks = Size / Split; - return invoke_impl(fn, ts...); - } - } -} -} // namespace detail - -template -constexpr auto invoke(auto fn, auto... ts) -> R { - constexpr auto ids = [](std::index_sequence) { return std::array{Ns...}; }(std::make_index_sequence{}); - constexpr auto permutations = permute(ids); - constexpr auto max_params_without_chunking = 7; - constexpr auto split = 10; - - if constexpr (sizeof...(ts) < max_params_without_chunking) { - constexpr auto N = [&](std::index_sequence) { - return ([&](std::index_sequence) { - return decltype(detail::invoke(fn, detail::nth(ts...)...)){}.first.value; - }.template operator()(std::make_index_sequence{}) + ...); - }(std::make_index_sequence{}); - - if constexpr (N > 0) { - constexpr auto N_ = N - 1; - return [&](std::index_sequence) { - return detail::invoke(fn, detail::nth(ts...)...).second; - }(std::make_index_sequence{}); - } else { - return {}; - } - } else { - return detail::invoke_impl(fn, ts...); - } -} +// twitter +auto id = @krisjusiak; ``` -> https://godbolt.org/z/97ejzW4Px -