Skip to content

define_enum#263

Open
zebullax wants to merge 3 commits intop2996from
define_enum
Open

define_enum#263
zebullax wants to merge 3 commits intop2996from
define_enum

Conversation

@zebullax
Copy link

@zebullax zebullax commented Feb 26, 2026

Issue number of the reported bug or feature request: #
#260 Original suggestion by @frederick-vs-ja

Describe your changes
Support programmatically defining enum

Testing performed

#include <cstdint>
#include <optional>
#include <meta>

using namespace std::meta;
constexpr auto ctx = std::meta::access_context::unchecked();

// Example payload: only some readings are present; presence bitmap is the fast index.
struct Telemetry {
  std::optional<double>        temperature_c;
  std::optional<double>        humidity_pct;
  std::optional<double>        pressure_kpa;
  std::optional<std::uint32_t> battery_mv;
  bool fault = false;
};

// Each enumerator value is a bit *index* into a compact bitmap.
enum class Field : unsigned;

// Populate Field with members from Telemetry, using the same order as in the struct.
consteval {
  constexpr int N = nonstatic_data_members_of(^^Telemetry, ctx).size();
  auto members = std::meta::nonstatic_data_members_of(^^Telemetry, ctx);
  std::array<info, N> enumerators;
  for (int i = 0; i < N; ++i) {
    auto member_info = members[i];
    enumerators[i] = enum_member_spec(enum_member_properties{.name = std::define_static_string(identifier_of(member_info))});
  }

  define_enum(^^Field, enumerators);
}

consteval auto enum_named(std::string_view name) {
  auto ctx = std::meta::access_context::current();
  for (std::meta::info field : enumerators_of(^^Field)) {
    if (has_identifier(field) && identifier_of(field) == name)
      return field;
  }
  return std::meta::info{}; // not found
}

constexpr std::uint64_t bit(Field f) {
  return 1ull << static_cast<unsigned>(f);
}

struct Presence64 {
  std::uint64_t bits{0};

  constexpr void set(Field f)       { bits |=  bit(f); }
  constexpr void clear(Field f)     { bits &= ~bit(f); }
  constexpr bool has(Field f) const { return (bits & bit(f)) != 0; }
};


constexpr Presence64 encode_presence(Telemetry const& t) {
  Presence64 p{};
  template for (constexpr auto r : define_static_array(nonstatic_data_members_of(^^Telemetry, ctx))) {
    if (t.[: r :]) p.set([: enum_named(identifier_of(r)) :]);
  }
  return p;
}

constexpr Telemetry t2{ .humidity_pct = 55.0, .fault = true };
static_assert(encode_presence(t2).has(Field::humidity_pct));
static_assert(encode_presence(t2).has(Field::fault));
static_assert(!encode_presence(t2).has(Field::temperature_c));

Additional context

  • VERY Early POC
  • Paper to follow

Signed-off-by: zebullax <zebullax@gmail.com>
Signed-off-by: zebullax <zebullax@gmail.com>
@zebullax zebullax changed the title Add early POC for define_enum define_enum Feb 26, 2026
@zebullax zebullax added the p2996-ext A behavior not part of P2996, but proposed for a related paper label Feb 26, 2026
Signed-off-by: zebullax <zebullax@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

p2996-ext A behavior not part of P2996, but proposed for a related paper

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant