C++20 range from enum

Viewed 78

can an enum be used as (or turned into) a C++20 range?

I am thinking about following use case, cartesian_product() is C++23 unfortunatey:

#include <algorithm>
using namespace std::ranges;

enum Fruit{APPLE, STRAWBERRY, COCONUT};
enum Vegetable{CARROT,POTATOE};
    
for (auto [fruit, vegetable] : views::cartesian_product(Fruit, Vegetable))
{
...
}
1 Answers

You can do this, it's just that you need the help of a library to turn the enum into a range of enumerator names. One such library is Boost.Describe:

#include <array>
#include <boost/describe.hpp>
#include <fmt/ranges.h>

enum Fruit{APPLE, STRAWBERRY, COCONUT};
enum Vegetable{CARROT,POTATO};

BOOST_DESCRIBE_ENUM(Fruit, APPLE, STRAWBERRY, COCONUT);
BOOST_DESCRIBE_ENUM(Vegetable, CARROT, POTATO);

template<class E>
constexpr auto enum_names() {
    return []<template <class...> class L, class... T>(L<T...>)
        -> std::array<char const*, sizeof...(T)>
    {
        return {T::name...};
    }(boost::describe::describe_enumerators<E>());
}

int main() {
    // prints fruits=["APPLE", "STRAWBERRY", "COCONUT"] vegetables=["CARROT", "POTATO"]
    fmt::print("fruits={} vegetables={}\n", enum_names<Fruit>(), enum_names<Vegetable>());
}

Demo

Related