based

Opinionated utility library
git clone git://git.dimitrijedobrota.com/based.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit 05763d080235789aa97f9247f2a30c542eaeb2de
parent f92e7681dde7fca63aa0ef1fb992253afa2e94a1
author Dimitrije Dobrota < mail@dimitrijedobrota.com >
date Sun, 4 May 2025 23:28:34 +0200

Clenup enum names, constructors are explicit

Diffstat:
M include/based/enum.hpp | ++++++++++++++++++++++++++++++++ ------------------------------
M include/based/instrumentation.hpp | + -
M test/source/enum_test.cpp | + -

3 files changed, 34 insertions(+), 32 deletions(-)


diff --git a/ include/based/enum.hpp b/ include/based/enum.hpp

@@ -11,36 +11,45 @@


#define BASED_LIST_STR(...) BASED_FOREACH(BASED_LIST_ELEM_STR, __VA_ARGS__)

#define BASED_DECLARE_ENUM_VAL(Name, Index) static const type Name;
// NOLINTNEXTLINE(*macro-parentheses*)
#define BASED_SET(var, val) decltype(var) var = decltype(var) {val};

#define BASED_DECLARE_ENUM_CASE(Qualifier, Name, Index) \
#define BASED_DETAIL_ENUM_DECLARE_VAL(Name, Index) static const type Name;

#define BASED_DETAIL_ENUM_DECLARE_CASE(Qualifier, Name, Index) \
case Qualifier::Name.value: \
return Name;

#define BASED_DEFINE_ENUM_VAL(Qualifier, Name, Index) \
inline constexpr Qualifier::type Qualifier::Name = { \
Qualifier::type::size - (Index) - 1 \
};
#define BASED_DETAIL_ENUM_DEFINE_VAL(Qualifier, Name, Index) \
inline constexpr BASED_SET( \
Qualifier::Name, Qualifier::type::size - (Index) - 1 \
)

#define BASED_DEFINE_ENUM_VALS(Qualifier, ...) \
BASED_FOREACH_1(Qualifier, BASED_DEFINE_ENUM_VAL, __VA_ARGS__)
#define BASED_DETAIL_ENUM_DEFINE_VALS(Qualifier, ...) \
BASED_FOREACH_1(Qualifier, BASED_DETAIL_ENUM_DEFINE_VAL, __VA_ARGS__)

#define BASED_DEFINE_ENUM_NAMES(Qualifier, ...) \
inline constexpr Qualifier::type::array<const char*> \
Qualifier::type::names = {BASED_LIST_STR(__VA_ARGS__)};
#define BASED_DETAIL_ENUM_DEFINE_NAMES(Qualifier, ...) \
inline constexpr BASED_SET( \
Qualifier::type::names, BASED_LIST_STR(__VA_ARGS__) \
)

#define BASED_DEFINE_ENUM_GET(Qualifier, Type, ...) \
#define BASED_DETAIL_ENUM_DEFINE_GET(Qualifier, Type, ...) \
inline const Qualifier::type& Qualifier::type::get(Type idx) \
{ \
switch (idx) { \
BASED_FOREACH_1(Qualifier, BASED_DECLARE_ENUM_CASE, __VA_ARGS__) \
BASED_FOREACH_1(Qualifier, BASED_DETAIL_ENUM_DECLARE_CASE, __VA_ARGS__) \
default: \
break; \
} \
assert(0); /* NOLINT(*assert*,cert-dcl03-c) */ \
assert(0); /* NOLINT(*assert*,cert-dcl03-c) */ \
}

#define BASED_DEFINE_ENUM_ARRAY(Name) \
#define BASED_DETAIL_ENUM_DEFINE(Qualifier, Type, ...) \
BASED_DETAIL_ENUM_DEFINE_VALS(Qualifier, __VA_ARGS__) \
BASED_DETAIL_ENUM_DEFINE_NAMES(Qualifier, __VA_ARGS__) \
BASED_DETAIL_ENUM_DEFINE_GET(Qualifier, Type, __VA_ARGS__)

#define BASED_ENUM_DEFINE_ARRAY(Name) \
template<typename T> \
class array : public std::array<T, Name::type::size> \
{ \

@@ -49,14 +58,12 @@

public: \
constexpr array() = default; \
\
/* NOLINTBEGIN(*explicit*,*decay*)*/ \
template<class... Args> \
requires(sizeof...(Args) == Name::type::size) \
constexpr array(Args&&... args) \
constexpr explicit array(Args&&... args) /* NOLINTNEXTLINE(*decay*) */ \
: std::array<T, Name::type::size>({std::forward<Args>(args)...}) \
{ \
} \
/* NOLINTEND(*explicit*,*decay*)*/ \
\
const T& operator[](Name::type val) const \
{ \

@@ -69,15 +76,14 @@

} \
};

#define BASED_DECLARE_ENUM(Name, Type, ...) \
#define BASED_ENUM_DECLARE(Name, Type, ...) \
struct Name \
{ \
class type \
{ \
friend Name; \
\
/* NOLINTNEXTLINE(*explicit*) */ \
constexpr type(Type enum_value) \
constexpr explicit type(Type enum_value) \
: value(enum_value) \
{ \
} \

@@ -87,7 +93,7 @@

static constexpr size_t size = \
BASED_NUMARGS(BASED_LIST_STR(__VA_ARGS__)); \
\
BASED_DEFINE_ENUM_ARRAY(Name) \
BASED_ENUM_DEFINE_ARRAY(Name) \
static const array<const char*> names; \
\
static const type& get(Type idx); \

@@ -95,17 +101,13 @@

Type value; \
}; \
\
BASED_FOREACH(BASED_DECLARE_ENUM_VAL, __VA_ARGS__) \
BASED_FOREACH(BASED_DETAIL_ENUM_DECLARE_VAL, __VA_ARGS__) \
};

#define BASED_DEFINE_ENUM(Name, Type, ...) \
BASED_DEFINE_ENUM_VALS(Name, __VA_ARGS__) \
BASED_DEFINE_ENUM_NAMES(Name, __VA_ARGS__) \
BASED_DEFINE_ENUM_GET(Name, __VA_ARGS__)
#define BASED_ENUM_DEFINE(Name, Type, ...) \
BASED_DETAIL_ENUM_DEFINE(Name, Type, __VA_ARGS__)

#define BASED_DEFINE_CLASS_ENUM(Class, Name, Type, ...) \
BASED_DEFINE_ENUM_VALS(Class::Name, __VA_ARGS__) \
BASED_DEFINE_ENUM_NAMES(Class::Name, __VA_ARGS__) \
BASED_DEFINE_ENUM_GET(Class::Name, Type, __VA_ARGS__)
BASED_DETAIL_ENUM_DEFINE(Class::Name, Type, __VA_ARGS__)

// NOLINTEND(*macro-usage*)

diff --git a/ include/based/instrumentation.hpp b/ include/based/instrumentation.hpp

@@ -74,7 +74,7 @@ inline auto normalize_nlogn1(double x, double n)


struct instrumented_base
{
BASED_DECLARE_ENUM(
BASED_ENUM_DECLARE(
op,
std::uint8_t,
n,

diff --git a/ test/source/enum_test.cpp b/ test/source/enum_test.cpp

@@ -6,7 +6,7 @@


struct test
{
BASED_DECLARE_ENUM(var, std::uint8_t, a, b, c)
BASED_ENUM_DECLARE(var, std::uint8_t, a, b, c)

[[nodiscard]] int get_var(var::type req) const;