توفر مكتبة C++17 ذات الرأس فقط انعكاسًا ثابتًا للتعدادات، وتعمل مع أي نوع تعداد دون أي تعليمات برمجية ماكرو أو نموذجية.
إذا أعجبك هذا المشروع، يرجى التفكير في التبرع لأحد الصناديق التي تساعد ضحايا الحرب في أوكرانيا: https://u24.gov.ua.
أساسي
# include < magic_enum/magic_enum.hpp >
# include < iostream >
enum class Color : { RED = - 10 , BLUE = 0 , GREEN = 10 };
int main () {
Color c1 = Color::RED;
std::cout << magic_enum::enum_name (c1) << std::endl; // RED
return 0 ;
}
قيمة التعداد إلى السلسلة
Color color = Color::RED;
auto color_name = magic_enum::enum_name(color);
// color_name -> "RED"
سلسلة إلى قيمة التعداد
std::string color_name{ " GREEN " };
auto color = magic_enum::enum_cast<Color>(color_name);
if (color.has_value()) {
// color.value() -> Color::GREEN
}
// case insensitive enum_cast
auto color = magic_enum::enum_cast<Color>(value, magic_enum::case_insensitive);
// enum_cast with BinaryPredicate
auto color = magic_enum::enum_cast<Color>(value, []( char lhs, char rhs) { return std::tolower (lhs) == std::tolower (rhs); }
// enum_cast with default
auto color_or_default = magic_enum::enum_cast<Color>(value).value_or(Color::NONE);
عدد صحيح لقيمة التعداد
int color_integer = 2 ;
auto color = magic_enum::enum_cast<Color>(color_integer);
if (color.has_value()) {
// color.value() -> Color::BLUE
}
auto color_or_default = magic_enum::enum_cast<Color>(value).value_or(Color::NONE);
الوصول المفهرس إلى قيمة التعداد
std:: size_t i = 0 ;
Color color = magic_enum::enum_value<Color>(i);
// color -> Color::RED
تسلسل قيمة التعداد
constexpr auto colors = magic_enum::enum_values<Color>();
// colors -> {Color::RED, Color::BLUE, Color::GREEN}
// colors[0] -> Color::RED
عدد عناصر التعداد
constexpr std:: size_t color_count = magic_enum::enum_count<Color>();
// color_count -> 3
قيمة التعداد إلى عدد صحيح
Color color = Color::RED;
auto color_integer = magic_enum::enum_integer(color); // or magic_enum::enum_underlying(color);
// color_integer -> 1
تسلسل أسماء التعداد
constexpr auto color_names = magic_enum::enum_names<Color>();
// color_names -> {"RED", "BLUE", "GREEN"}
// color_names[0] -> "RED"
تسلسل إدخالات التعداد
constexpr auto color_entries = magic_enum::enum_entries<Color>();
// color_entries -> {{Color::RED, "RED"}, {Color::BLUE, "BLUE"}, {Color::GREEN, "GREEN"}}
// color_entries[0].first -> Color::RED
// color_entries[0].second -> "RED"
دمج التعداد لبيانات الحالة/المفاتيح متعددة المستويات
switch (magic_enum::enum_fuse(color, direction).value()) {
case magic_enum::enum_fuse (Color::RED, Directions::Up). value (): // ...
case magic_enum::enum_fuse (Color::BLUE, Directions::Down). value (): // ...
// ...
}
يقوم التعداد بتبديل قيمة وقت التشغيل كثابت constexpr
Color color = Color::RED;
magic_enum::enum_switch ([] ( auto val) {
constexpr Color c_color = val;
// ...
}, color);
يتكرر التعداد لكل تعداد كثابت constexpr
magic_enum::enum_for_each<Color>([] ( auto val) {
constexpr Color c_color = val;
// ...
});
تحقق مما إذا كان التعداد يحتوي على
magic_enum::enum_contains (Color::GREEN); // -> true
magic_enum::enum_contains<Color>( 2 ); // -> true
magic_enum::enum_contains<Color>( 123 ); // -> false
magic_enum::enum_contains<Color>( " GREEN " ); // -> true
magic_enum::enum_contains<Color>( " fda " ); // -> false
فهرس التعداد بالتسلسل
constexpr auto color_index = magic_enum::enum_index(Color::BLUE);
// color_index.value() -> 1
// color_index.has_value() -> true
وظائف للأعلام
enum Directions : std:: uint64_t {
Left = 1 ,
Down = 2 ,
Up = 4 ,
Right = 8 ,
};
template <>
struct magic_enum ::customize::enum_range<Directions> {
static constexpr bool is_flags = true ;
};
magic_enum::enum_flags_name (Directions::Up | Directions::Right); // -> "Directions::Up|Directions::Right"
magic_enum::enum_flags_contains (Directions::Up | Directions::Right); // -> true
magic_enum::enum_flags_cast ( 3 ); // -> "Directions::Left|Directions::Down"
اسم نوع التعداد
Color color = Color::RED;
auto type_name = magic_enum::enum_type_name<decltype(color)>();
// type_name -> "Color"
مشغل IOstream للتعداد
using magic_enum::iostream_operators:: operator <<; // out-of-the-box ostream operators for enums.
Color color = Color::BLUE;
std::cout << color << std::endl; // "BLUE"
using magic_enum::iostream_operators:: operator >>; // out-of-the-box istream operators for enums.
Color color;
std::cin >> color;
عامل Bitwise للتعداد
enum class Flags { A = 1 << 0 , B = 1 << 1 , C = 1 << 2 , D = 1 << 3 };
using namespace magic_enum ::bitwise_operators ; // out-of-the-box bitwise operators for enums.
// Support operators: ~, |, &, ^, |=, &=, ^=.
Flags flags = Flags::A | Flags::B & ~Flags::C;
التحقق مما إذا كان النوع عبارة عن تعداد غير محدد النطاق.
enum color { red, green, blue };
enum class direction { left, right };
magic_enum::is_unscoped_enum<color>::value -> true
magic_enum::is_unscoped_enum<direction>::value -> false
magic_enum::is_unscoped_enum< int >::value -> false
// Helper variable template.
magic_enum::is_unscoped_enum_v<color> -> true
التحقق مما إذا كان النوع عبارة عن تعداد محدد النطاق.
enum color { red, green, blue };
enum class direction { left, right };
magic_enum::is_scoped_enum<color>::value -> false
magic_enum::is_scoped_enum<direction>::value -> true
magic_enum::is_scoped_enum< int >::value -> false
// Helper variable template.
magic_enum::is_scoped_enum_v<direction> -> true
متغير تعداد التخزين الثابت إلى السلسلة. هذا الإصدار أخف بكثير في أوقات الترجمة ولا يقتصر على حدود enum_range.
constexpr Color color = Color::BLUE;
constexpr auto color_name = magic_enum::enum_name<color>();
// color_name -> "BLUE"
containers::array
حاوية صفيف للتعدادات.
magic_enum::containers::array<Color, RGB> color_rgb_array {};
color_rgb_array[Color::RED] = { 255 , 0 , 0 };
color_rgb_array[Color::GREEN] = { 0 , 255 , 0 };
color_rgb_array[Color::BLUE] = { 0 , 0 , 255 };
magic_enum::containers::get<Color::BLUE>(color_rgb_array) // -> RGB{0, 0, 255}
containers::bitset
للتعدادات.
constexpr magic_enum::containers::bitset<Color> color_bitset_red_green {Color::RED|Color::GREEN};
bool all = color_bitset_red_green.all();
// all -> false
// Color::BLUE is missing
bool test = color_bitset_red_green.test(Color::RED);
// test -> true
containers::set
مجموعة الحاويات للتعدادات.
auto color_set = magic_enum::containers::set<Color>();
bool empty = color_set.empty();
// empty -> true
color_set.insert(Color::GREEN);
color_set.insert(Color::BLUE);
color_set.insert(Color::RED);
std:: size_t size = color_set.size();
// size -> 3
تحسين النوع الأساسي "الصديق لـ SFINAE" الخالي من UB.
magic_enum::underlying_type<color>::type -> int
// Helper types.
magic_enum:: underlying_type_t <Direction> -> int
لا يتظاهر magic_enum
بأنه حل سحري للانعكاس في التعدادات، فقد تم تصميمه في الأصل للتعدادات الصغيرة.
قبل الاستخدام، اقرأ حدود الوظيفة.
يجب عليك إضافة الملف Magic_enum.hpp المطلوب، بالإضافة إلى الرؤوس الأخرى بشكل اختياري من include dir أو أرشيف الإصدار. وبدلاً من ذلك، يمكنك إنشاء المكتبة باستخدام CMake.
إذا كنت تستخدم vcpkg في مشروعك للتبعيات الخارجية، فيمكنك استخدام حزمة Magic-enum.
إذا كنت تستخدم Conan لإدارة تبعياتك، فما عليك سوى إضافة magic_enum/xyz
إلى متطلبات conan الخاصة بك، حيث xyz
هو إصدار الإصدار الذي تريد استخدامه.
إذا كنت تستخدم Build2 لإنشاء تبعياتك وإدارتها، فأضف depends: magic_enum ^xyz
إلى ملف البيان حيث xyz
هو إصدار الإصدار الذي تريد استخدامه. يمكنك بعد ذلك استيراد الهدف باستخدام magic_enum%lib{magic_enum}
.
وبدلاً من ذلك، يمكنك استخدام شيء مثل CPM الذي يعتمد على وحدة Fetch_Content
الخاصة بـ CMake.
CPMAddPackage(
NAME magic_enum
GITHUB_REPOSITORY Neargye/magic_enum
GIT_TAG x.y.z # Where `x.y.z` is the release version you want to use.
)
Bazel مدعوم أيضًا، ما عليك سوى إضافته إلى ملف WORKSPACE الخاص بك:
http_archive(
name = "magic_enum",
strip_prefix = "magic_enum-<commit>",
urls = ["https://github.com/Neargye/magic_enum/archive/<commit>.zip"],
)
لاستخدام bazel داخل المستودع، من الممكن القيام بما يلي:
bazel build //...
bazel test //...
bazel run //example
(لاحظ أنه يجب عليك استخدام مترجم مدعوم أو تحديده باستخدام export CC= <compiler>
.)
إذا كنت تستخدم Ros، فيمكنك تضمين هذه الحزمة عن طريق إضافة <depend>magic_enum</depend>
إلى package.xml الخاص بك وتضمين هذه الحزمة في مساحة العمل الخاصة بك. في ملف CMakeLists.txt، قم بإضافة ما يلي:
find_package (magic_enum CONFIG REQUIRED)
...
target_link_libraries (your_executable magic_enum::magic_enum)