-
Notifications
You must be signed in to change notification settings - Fork 130
Add enchantum
as an enum reflection backend
#441
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello @ZXShady, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
Summary of Changes
As gemini-code-assist, I've reviewed this pull request from ZXShady. The core intent of this PR is to replace the existing internal enum reflection implementation within reflect-cpp
with an external library called enchantum
. The author, who is also the author of enchantum
, states that this change aims to reduce compile times, decrease maintenance burden on reflect-cpp
for enum reflection, and provide more customization options through enchantum::enum_traits
(like removing prefixes). The changes involve integrating the enchantum
header and refactoring the internal enum handling logic to delegate to the new library.
Highlights
- Enum Reflection Backend Replacement: The primary change is the complete replacement of
reflect-cpp
's custom enum reflection code with theenchantum
library. - Integration of
enchantum
: Theenchantum
library is added as a third-party header file and integrated into the internal enum handling components. - Simplified Internal Logic: The internal code for getting enum names, converting between enums and strings, and determining enum properties (like being a flag enum) is significantly simplified by leveraging
enchantum
's functionalities. - Enum Range Configuration: The existing
RFL_ENUM_RANGE_MIN
andRFL_ENUM_RANGE_MAX
macros are now used to configure the corresponding range macros within theenchantum
library.
Changelog
Click here to see the changelog
- include/rfl/internal/enums/Names.hpp
- Moved and redefined
RFL_ENUM_RANGE_MIN
andRFL_ENUM_RANGE_MAX
macros (lines 4-18). - Mapped
RFL_ENUM_RANGE_MIN
andRFL_ENUM_RANGE_MAX
toENCHANTUM_MIN_RANGE
andENCHANTUM_MAX_RANGE
(lines 20-28). - Removed old definitions of
RFL_ENUM_RANGE_MIN
andRFL_ENUM_RANGE_MAX
(lines 44-45). - Changed the type of
enums_
member toauto
for potential type deduction improvements (line 87).
- Moved and redefined
- include/rfl/internal/enums/StringConverter.hpp
- Included the new
enchantum.hpp
header (line 13). - Replaced the manual loop for
enum_to_single_string
with a call toenchantum::to_string
(lines 73-76). - Replaced the custom string-to-enum conversion logic in
single_string_to_enum
with a call toenchantum::cast
(lines 87-95).
- Included the new
- include/rfl/internal/enums/get_enum_names.hpp
- Included the new
enchantum.hpp
header (line 13). - Removed the old compiler-specific
get_enum_name_str_view
andget_enum_name
functions (lines 44-79). - Removed the complex
NamesCombiner
andCombineNames
machinery (lines 108-160, 162-181). - Refactored
get_enum_names
to useenchantum::entries
and convert the result to the internalNames
structure (lines 74-109). - Removed include for
is_scoped_enum.hpp
(line 16).
- Included the new
- include/rfl/internal/enums/is_flag_enum.hpp
- Included the new
enchantum.hpp
header (line 7). - Added a template specialization for
enchantum::is_bitflag
based on the presence of bitwise operators (lines 8-12). - Updated the
is_flag_enum
concept to useenchantum::BitFlagEnum
(lines 18-20).
- Included the new
- include/rfl/internal/enums/is_scoped_enum.hpp
- Included the new
enchantum.hpp
header (line 6). - Updated the
is_scoped_enum
concept to useenchantum::ScopedEnum
(line 13).
- Included the new
- include/rfl/thirdparty/enchantum.hpp
- Added the complete
enchantum
library header file (lines 1-1495).
- Added the complete
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command>
or @gemini-code-assist <command>
. Below is a summary of the supported commands.
Feature | Command | Description |
---|---|---|
Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/
folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Enums stand so tall,
Names reflected, answering the call.
Code shrinks, compile times fall.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request introduces enchantum
as a new backend for enum reflection, which is a significant change. The goals of reducing compile times, decreasing maintenance burden on rfl
's enum reflection, and enabling more customization are well-aligned with improving the library. The integration of enchantum
, especially the way rfl
communicates its flag enum definition via enchantum::is_bitflag
specialization, appears thoughtfully done.
However, there are a few points to address, primarily concerning a potentially breaking change in default enum ranges and associated documentation updates. Additionally, some code cleanup in the integration and a minor point in the vendored enchantum.hpp
are suggested.
Please also note that docs/enums.md
(line 44) will need an update to reflect the new default enum range [-256, 256]
instead of [0, 127]
. Since this file is not part of the PR, this is just a reminder for a follow-up or inclusion in this PR.
Overall, this is a promising direction for enum reflection in rfl
.
Summary of Findings
- Default Enum Range Change: The default values for
RFL_ENUM_RANGE_MIN
andRFL_ENUM_RANGE_MAX
have been changed. This is a potentially breaking change and the accompanying comments are outdated. - Code Cleanup: Commented-out code from a previous implementation exists in
get_enum_names.hpp
and could be removed. - Macro Definition in
enchantum.hpp
: TheENCHANTUM_ASSERT
macro in the vendoredenchantum.hpp
declares variadic arguments that are not used in its expansion. - Documentation Update Needed (Outside PR Scope): The main
docs/enums.md
file needs to be updated to reflect the new default enum ranges. (Noted as not commented due to settings, but mentioned in general feedback).
Merge Readiness
This pull request makes a significant and largely positive change by integrating enchantum
for enum reflection. However, due to the potentially breaking change in default enum ranges and the outdated documentation for these macros, I recommend addressing these points before merging. The other suggestions are for improving code clarity and correctness within the newly added/modified files.
As an AI, I am not authorized to approve pull requests. Please ensure further review and approval from authorized maintainers after addressing the feedback.
include/rfl/thirdparty/enchantum.hpp
Outdated
#ifndef ENCHANTUM_ASSERT | ||
#include <cassert> | ||
// clang-format off | ||
#define ENCHANTUM_ASSERT(cond, msg, ...) assert(cond && msg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ENCHANTUM_ASSERT
macro is defined as assert(cond && msg)
, but it takes a variadic argument ...
that isn't used in the expansion.
If the ...
is intended for future enhancements (e.g., formatted messages), perhaps a comment could clarify this. Otherwise, if it's not planned to be used, would simplifying the macro to #define ENCHANTUM_ASSERT(cond, msg) assert(cond && msg)
be more straightforward?
cf254d3
to
0832143
Compare
include/rfl/internal/enums/Names.hpp
Outdated
// To change the default minimum range for all enum types, redefine the macro | ||
// RFL_ENUM_RANGE_MIN. | ||
#if !defined(RFL_ENUM_RANGE_MIN) | ||
#define RFL_ENUM_RANGE_MIN -256 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggestion: The range (-256, 256)
strikes me as rather odd, since it doesn't match the previous implementation, and also goes over the one-byte "boundary" of an underlying type. I haven't looked at your enchantum
internals yet, but I suspect that this new > 9-bit enum range may have some performance implications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my library clamps the enum ranges so it doesn't matter.
I did a small test with magic enum, mine, and rfl in this gist
https://gist.github.com/ZXShady/74ebfe7d14ddcfeee6b0577a9ee4a396
time to compile
magic enum : 9 seconds
enchantum : 2.5 seconds
rfl : 19 seconds
and by performance you mean what exactly? compile time or runtime?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both compile time and also memory, but I suppose that would be driven by the underlying type more than the enum range?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both compile time and also memory, but I suppose that would be driven by the underlying type more than the enum range?
no the enum range determines the compile times. see my library readme
but if enum range exceeds underlying type min max it clamps the range.
the compile time are faster (see gist above) and memory usage should be the same, memory usage while compiling though is heavily reduced just like compile times
Unless the tests reveal some compiler/OS-specific problems we haven't discovered so far (unlikely), this is ready to be merged, IMO. @ZXShady , do you agree? @ZXShady , I have one more request: When you upload enchantum to vcpkg and Conan, please notify me. The maintainers of these package managers want to avoid us including thirdparty libraries that they also ship. If people have two different versions of the same library in their code and don't even know about it that can cause all sort of problems... |
I was thinking about using the split headers instead of the big one since I always keep forgetting to update it and it bloats compile times what do you think? I don't think you should merge now I think I will update the header file again since I am releasing version 0.1.0 today that removes some overloads.
I am thinking of writing a vcpkg port. |
@ZXShady , there appears to be one more issue on macOS:
I am not entirely sure why this happening, because you are clearly including I am totally fine with splitting up the single header file. By the way, if you keep on forgetting to update it, you can write a simple Python script that does it for you and then have a GitHub Actions step automatically file a PR. |
@ZXShady , by the way, I am also taking a closer look at the build pipelines, specifically why they suddenly take so long. The issue appears to be that GitHub Actions fails to connect to the binary cache and then tries to do so over and over again. |
Github sctions seems to be failing for me as well right now. been waiting and no runner been picked up I split the headers and used the latest release you are free to merge if the tests succeed |
currently overriding enum_range doesn't allow prefix_length to be overriden as well. I think it would be better to also add a recommendation to instead override |
@ZXShady what exactly does the prefix length do? I think it can be easily added to the configurations... |
it removes N characters from the start of enum name. example in docs #include <enchantum/enchantum.hpp>
#include <enchantum/bitwise_operators.hpp>
// this is a bug enum it is outside of default range [-256,256] and it has this annoying prefix
enum BigEnumOutsideOfDefault : std::uint16_t {
BigEnumOutsideOfDefault_A =0,BigEnumOutsideOfDefault_B = 4096
};
template<>
struct enchantum::enum_traits<BigEnumOutsideOfDefault> {
constexpr static auto prefix_length = sizeof("BigEnumOutsideOfDefault_")-1;
constexpr static auto min = 0;
constexpr static auto max = 4096;
};
// prefix removed
static_assert(enchantum::names<BigEnumOutsideOfDefault>[0] == "A");
static_assert(enchantum::names<BigEnumOutsideOfDefault>[1] == "B"); I anm myself against making aliases for existing things. if the user needs this he should just specialize enchantum's instead. |
@ZXShady I See. I suppose that is something we can always add later. |
@ZXShady the tests have finally succeeded. I don't why they take do long these days. But I am merging. Thank you so much for this great contribution. If you really manage to extend the range to -32,000 to 32,000, please open another PR. I would be very interested. |
The extended range will just require updating the header files btw. (I have actually implemented it currently for clang, it is still local though on my machine though, results are very promising) Thanks for accepting my contribution! |
Disclaimer I am the author of enchantum.
This PR replaces reflect-cpp own enum reflection with enchantum's
enchantum::enum_traits
(except unnamed unscoped enums) and not just scoped enums.