272.md

September 5, 2022 ยท View on GitHub

Info

Example

int main() {
  assert(std::ranges::all_of (std::array{1, 1, 1}, [](const auto& value) { return value == 1; }));
  assert(std::ranges::any_of (std::array{1, 2, 3}, [](const auto& value) { return value == 2; }));
  assert(std::ranges::none_of(std::array{1, 2, 3}, [](const auto& value) { return value == 4; }));
}

https://godbolt.org/z/czv4q433f

Puzzle

  • Can you implement consteval equivalents of {all_of, any_of, none_of} algorithms?
template<auto... Values>
[[nodiscard]] consteval auto all_of(auto expr) -> bool; // TODO

template<auto... Values>
[[nodiscard]] consteval auto any_of(auto expr) -> bool; // TODO

template<auto... Values>
[[nodiscard]] consteval auto none_of(auto expr) -> bool; // TODO

static_assert(all_of([](auto v) { return v == 1; }));
static_assert(all_of<1, 1, 1>([](auto v) { return v == 1; }));
static_assert(all_of<1>([](auto v) { return v == 1; }));
static_assert(not all_of<1, 2, 1>([](auto v) { return v == 1; }));
static_assert(not all_of<1, 2>([](auto v) { return v == 1; }));
static_assert(not all_of<1, 2>([](auto v) { return v == 2; }));

static_assert(any_of<1, 2, 3>([](auto v) { return v == 1; }));
static_assert(any_of<1, 2, 3>([](auto v) { return v == 2; }));
static_assert(any_of<1, 2, 3>([](auto v) { return v == 3; }));
static_assert(any_of<1>([](auto v) { return v == 1; }));
static_assert(not any_of([](auto v) { return v == 1; }));
static_assert(not any_of<1, 2, 3>([](auto v) { return v == 0; }));
static_assert(not any_of<1, 2, 3>([](auto v) { return v == 4; }));

static_assert(none_of([](auto v) { return v == 1; }));
static_assert(none_of<1, 2, 3>([](auto v) { return v == 0; }));
static_assert(none_of<1, 2, 3>([](auto v) { return v == 4; }));
static_assert(none_of<1, 1, 1>([](auto v) { return v == 2; }));
static_assert(not none_of<1>([](auto v) { return v == 1; }));
static_assert(not none_of<1, 2, 3>([](auto v) { return v == 1; }));
static_assert(not none_of<1, 2, 3>([](auto v) { return v == 2; }));
static_assert(not none_of<1, 2, 3>([](auto v) { return v == 3; }));

https://godbolt.org/z/zdrsM6G1G

Solutions

template<auto... Values>
[[nodiscard]] consteval auto all_of(auto expr) -> bool {
   return (expr(Values) && ...);
}

template<auto... Values>
[[nodiscard]] consteval auto any_of(auto expr) -> bool {
   return (expr(Values) || ...);
}

template<auto... Values>
[[nodiscard]] consteval auto none_of(auto expr) -> bool {
   return !(expr(Values) || ...);
}

https://godbolt.org/z/fWzn1dE99

template<auto... Values>
[[nodiscard]] consteval auto all_of(auto expr) -> bool
{
    if constexpr (sizeof...(Values) > 0)
        return std::ranges::all_of(std::array{Values...}, expr);
    return true;
}


template<auto... Values>
[[nodiscard]] consteval auto any_of(auto expr) -> bool
{
    if constexpr (sizeof...(Values) > 0)
        return std::ranges::any_of(std::array{Values...}, expr);
    return false;
}

template<auto... Values>
[[nodiscard]] consteval auto none_of(auto expr) -> bool
{
    if constexpr (sizeof...(Values) > 0)   
        return std::ranges::none_of(std::array{Values...}, expr);
    return true;
}

https://godbolt.org/z/hYWW5nzbh

template<auto... Values>
[[nodiscard]] consteval auto all_of(auto expr) -> bool {
    return (expr(Values) and ...);
}
template<auto... Values>
[[nodiscard]] consteval auto any_of(auto expr) -> bool {
    return (expr(Values) or ...);
}
template<auto... Values>
[[nodiscard]] consteval auto none_of(auto expr) -> bool {
    return not (expr(Values) or ...);
}

https://godbolt.org/z/a1hWKjKb9

template <auto... Values>
[[nodiscard]] consteval auto all_of(auto expr) -> bool {
    return (... and expr(Values));
}

template <auto... Values>
[[nodiscard]] consteval auto any_of(auto expr) -> bool {
    return (... or expr(Values));
}

template <auto... Values>
[[nodiscard]] consteval auto none_of(auto expr) -> bool {
    return not any_of<Values...>(expr);
}

https://godbolt.org/z/xsP5MeE9v

template<auto... Values>
[[nodiscard]] consteval auto all_of(auto expr) -> bool {
  return (expr(Values) and ...);
}

template<auto... Values>
[[nodiscard]] consteval auto any_of(auto expr) -> bool {
  return (expr(Values) or ...);
}

template<auto... Values>
[[nodiscard]] consteval auto none_of(auto expr) -> bool {
  return not any_of<Values...>(expr);
}

https://godbolt.org/z/YG5jroEGY

template <auto... Values>
[[nodiscard]] consteval auto all_of(auto expr) -> bool {
    return (... and expr(Values));
}

template <auto... Values>
[[nodiscard]] consteval auto any_of(auto expr) -> bool {
    return (... or expr(Values));
}

template <auto... Values>
[[nodiscard]] consteval auto none_of(auto expr) -> bool {
    return not any_of<Values...>(expr);
}

https://godbolt.org/z/8411orvcE

template<auto... Values>
[[nodiscard]] consteval auto all_of(auto expr) -> bool {
    if constexpr(sizeof...(Values)) return std::ranges::all_of(std::array{Values...}, expr);
    return true;
}

template<auto... Values>
[[nodiscard]] consteval auto any_of(auto expr) -> bool {
    if constexpr (sizeof...(Values)) return std::ranges::any_of(std::array{Values...}, expr);
    return false;
}

template<auto... Values>
[[nodiscard]] consteval auto none_of(auto expr) -> bool {
    if constexpr(sizeof...(Values)) return std::ranges::none_of(std::array{Values...}, expr);
    return true;
}

https://godbolt.org/z/K9ecvxvjo

template<auto... Values>
[[nodiscard]] consteval auto all_of(auto expr) -> bool {
    return std::ranges::all_of(std::array<int, sizeof...(Values)>{Values...}, expr);
}

template<auto... Values>
[[nodiscard]] consteval auto any_of(auto expr) -> bool {
    return std::ranges::any_of(std::array<int, sizeof...(Values)>{Values...}, expr);
}

template<auto... Values>
[[nodiscard]] consteval auto none_of(auto expr) -> bool {
    return std::ranges::none_of(std::array<int, sizeof...(Values)>{Values...}, expr);
}

https://godbolt.org/z/dvYW9qdsG

template<auto... Values>
[[nodiscard]] consteval auto all_of(auto expr) -> bool{
    if constexpr (sizeof...(Values) == 0) return true;
    else
        return std::ranges::all_of(std::array<std::common_type_t<decltype(Values)...>, sizeof...(Values)>{{Values...}}, expr);
}

template<auto... Values>
[[nodiscard]] consteval auto any_of(auto expr) -> bool{
    if constexpr (sizeof...(Values) == 0) return false;
    else
        return std::ranges::any_of(std::array<std::common_type_t<decltype(Values)...>, sizeof...(Values)>{{Values...}}, expr);
}

template<auto... Values>
[[nodiscard]] consteval auto none_of(auto expr) -> bool{
    if constexpr (sizeof...(Values) == 0) return true;
    else
        return std::ranges::none_of(std::array<std::common_type_t<decltype(Values)...>, sizeof...(Values)>{{Values...}}, expr);
}

https://godbolt.org/z/aos37bd8W

template<auto... Values>
[[nodiscard]] consteval auto all_of(auto expr) -> bool {
    return (expr(Values) & ... & true) ;
}

template<auto... Values>
[[nodiscard]] consteval auto any_of(auto expr) -> bool {
    return (expr(Values) || ... || false);
}

template<auto... Values>
[[nodiscard]] consteval auto none_of(auto expr) -> bool {
    return ( (not expr(Values)) & ... & true);
}

https://godbolt.org/z/edKfKvcxr