Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .cppcheck.suppress
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
unusedFunction
duplInheritedMember
duplInheritedMember
useStlAlgorithm
normalCheckLevelMaxBranches
knownConditionTrueFalse:test/*
31 changes: 30 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,33 @@
"stack": "cpp",
"ranges": "cpp"
},
}
"workbench.colorCustomizations": {
"activityBar.activeBackground": "#65c89b",
"activityBar.activeBorder": "#15202b",
"activityBar.background": "#65c89b",
"activityBar.foreground": "#15202b",
"activityBar.inactiveForeground": "#15202b99",
"activityBarBadge.background": "#945bc4",
"activityBarBadge.foreground": "#e7e7e7",
"activityBarTop.activeBackground": "#65c89b",
"activityBarTop.activeBorder": "#15202b",
"activityBarTop.background": "#65c89b",
"activityBarTop.foreground": "#15202b",
"activityBarTop.inactiveForeground": "#15202b99",
"commandCenter.border": "#15202b99",
"commandCenter.foreground": "#15202b",
"sash.hoverBorder": "#65c89b",
"statusBar.background": "#42b883",
"statusBar.debuggingBackground": "#42b883",
"statusBar.debuggingForeground": "#15202b",
"statusBar.foreground": "#15202b",
"statusBarItem.hoverBackground": "#359268",
"statusBarItem.remoteBackground": "#f0e8f7",
"statusBarItem.remoteForeground": "#15202b",
"titleBar.activeBackground": "#42b883",
"titleBar.activeForeground": "#15202b",
"titleBar.inactiveBackground": "#42b88399",
"titleBar.inactiveForeground": "#15202b99"
},
"peacock.remoteColor": "#42b883",
}
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.

## Next Release

### Enum

- split `enum.hpp` into `enum/enum.hpp`, `enum/enum_bit_flags.hpp` (renamed from `enum_bit_flage.hpp`) and `enum/enum_string.hpp`, with `mstd/enum.hpp` now re-exporting all three
- move `EnumFromString`/`EnumToString` into namespace `mstd`, fixing a compile error in `from_string` which referenced `mstd::EnumFromString` on an undefined name
- add extensive unit test coverage for `MSTD_ENUM` and `MSTD_ENUM_BITFLAG`

<!-- insertion marker -->
## [0.3.0](https://github.com/repo/owner/releases/tag/0.3.0) - 2026-09-26

Expand Down
173 changes: 2 additions & 171 deletions include/mstd/enum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,176 +23,7 @@
#ifndef __MSTD__ENUM_HPP__
#define __MSTD__ENUM_HPP__

#include <array> // IWYU pragma: keep
#include <cstddef> // IWYU pragma: keep
#include <optional> // IWYU pragma: keep
#include <span> // IWYU pragma: keep
#include <string> // IWYU pragma: keep
#include <string_view> // IWYU pragma: keep
#include <type_traits> // IWYU pragma: keep

#include "mstd/type_traits/enum_traits.hpp" // IWYU pragma: keep
#include "mstd/type_traits/string.hpp" // IWYU pragma: keep

//
// Element expanders
//
// X(Name) -> Name,
// X(Name, 42) -> Name = 42,
#define MSTD_ENUM_MAKE_ENUM(name, ...) name __VA_OPT__(= __VA_ARGS__),

// X(Name) or X(Name, 42) -> EnumName::Name,
#define MSTD_ENUM_MAKE_VALUE(name, ...) name,

// X(Name) -> "Name",
#define MSTD_ENUM_MAKE_STRING(name, ...) #name,

// ------------------------------------------------------------
// Main macro
// ------------------------------------------------------------
#ifndef Q_MOC_RUN
#define MSTD_ENUM(EnumName, Underlying, LIST) \
enum class EnumName : Underlying \
{ \
LIST(MSTD_ENUM_MAKE_ENUM) \
}; \
\
struct EnumName##Meta \
{ \
using type = EnumName; \
using underlying_type = Underlying; \
using enum EnumName; \
static constexpr std::string_view EnumNameStr = #EnumName; \
\
static constexpr auto values = \
std::to_array<EnumName>({LIST(MSTD_ENUM_MAKE_VALUE)}); \
\
static constexpr std::span<const EnumName> values_view() \
{ \
return values; \
} \
\
static constexpr auto names = \
std::to_array<std::string_view>({LIST(MSTD_ENUM_MAKE_STRING)}); \
\
static constexpr std::size_t size = values.size(); \
\
static constexpr auto begin() { return values.begin(); } \
static constexpr auto end() { return values.end(); } \
\
static constexpr std::string_view name(EnumName enum_) \
{ \
for (std::size_t i = 0; i < size; ++i) \
if (values.at(i) == enum_) \
return names.at(i); \
return {}; \
} \
\
static constexpr std::string toString(EnumName enum_) \
{ \
for (std::size_t i = 0; i < size; ++i) \
if (values.at(i) == enum_) \
return std::string(names.at(i)); \
return {}; \
} \
\
static constexpr std::optional<EnumName> from_string( \
std::string_view str \
) \
{ \
for (std::size_t i = 0; i < size; ++i) \
if (names.at(i) == str) \
return values.at(i); \
return std::nullopt; \
} \
\
static constexpr std::optional<EnumName> from_stringCaseInsensitive( \
std::string_view str \
) \
{ \
static_assert( \
!mstd::hasCaseInsensitiveCollision<(size)>(names), \
"from_stringCaseInsensitive is ambiguous: this enum has " \
"enumerator names that differ only by case" \
); \
\
for (std::size_t i = 0; i < names.size(); ++i) \
if (mstd::iequals(names.at(i), str)) \
return values.at(i); \
return std::nullopt; \
} \
\
static constexpr underlying_type to_underlying(EnumName enum_) \
{ \
return static_cast<underlying_type>(enum_); \
} \
\
static constexpr std::optional<std::size_t> index(EnumName enum_) \
{ \
for (std::size_t i = 0; i < size; ++i) \
if (values.at(i) == enum_) \
return i; \
return std::nullopt; \
} \
}; \
\
inline constexpr EnumName##Meta enum_meta(EnumName) { return {}; }

#else
#define MSTD_ENUM(EnumName, Underlying, LIST) enum class EnumName : Underlying;
#endif

#define MSTD_ENUM_BITFLAG(EnumName, Underlying, LIST) \
MSTD_ENUM(EnumName, Underlying, LIST) \
\
inline constexpr EnumName operator|(EnumName lhs, EnumName rhs) \
{ \
return static_cast<EnumName>( \
static_cast<Underlying>(lhs) | static_cast<Underlying>(rhs) \
); \
} \
\
inline constexpr EnumName& operator|=(EnumName& lhs, EnumName rhs) \
{ \
lhs = lhs | rhs; \
return lhs; \
} \
\
inline constexpr EnumName operator~(EnumName value) \
{ \
return static_cast<EnumName>(~static_cast<Underlying>(value)); \
} \
\
struct EnumName##FlagTest \
{ \
Underlying value; \
constexpr operator EnumName() const noexcept \
{ \
return static_cast<EnumName>(value); \
} \
\
constexpr explicit operator bool() const noexcept \
{ \
return value != Underlying{0}; \
} \
}; \
\
inline constexpr EnumName##FlagTest operator&(EnumName lhs, EnumName rhs) \
{ \
return EnumName##FlagTest{static_cast<Underlying>( \
static_cast<Underlying>(lhs) & static_cast<Underlying>(rhs) \
)}; \
} \
\
inline constexpr EnumName& operator&=(EnumName& lhs, EnumName rhs) \
{ \
lhs = lhs & rhs; \
return lhs; \
} \
\
inline constexpr bool operator!(EnumName lhs) \
{ \
return !static_cast<Underlying>(lhs); \
}
#include "enum/enum.hpp" // IWYU pragma: export
#include "enum/enum_bit_flags.hpp" // IWYU pragma: export

#endif // __MSTD__ENUM_HPP__
Loading
Loading