Pustaka C++17 khusus header menyediakan refleksi statis untuk enum, bekerja dengan tipe enum apa pun tanpa kode makro atau boilerplate apa pun.
Jika Anda menyukai proyek ini, mohon pertimbangkan untuk menyumbang ke salah satu dana yang membantu korban perang di Ukraina: https://u24.gov.ua.
Dasar
# 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 ;
}
Nilai enum ke string
Color color = Color::RED;
auto color_name = magic_enum::enum_name(color);
// color_name -> "RED"
String ke nilai enum
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);
Nilai integer ke enum
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);
Akses yang diindeks ke nilai enum
std:: size_t i = 0 ;
Color color = magic_enum::enum_value<Color>(i);
// color -> Color::RED
Urutan nilai enum
constexpr auto colors = magic_enum::enum_values<Color>();
// colors -> {Color::RED, Color::BLUE, Color::GREEN}
// colors[0] -> Color::RED
Jumlah elemen enum
constexpr std:: size_t color_count = magic_enum::enum_count<Color>();
// color_count -> 3
Nilai enum ke bilangan bulat
Color color = Color::RED;
auto color_integer = magic_enum::enum_integer(color); // or magic_enum::enum_underlying(color);
// color_integer -> 1
Urutan nama enum
constexpr auto color_names = magic_enum::enum_names<Color>();
// color_names -> {"RED", "BLUE", "GREEN"}
// color_names[0] -> "RED"
Urutan entri enum
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"
Penggabungan enum untuk pernyataan sakelar/kasus multi-level
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 (): // ...
// ...
}
Enum mengganti nilai runtime sebagai konstanta constexpr
Color color = Color::RED;
magic_enum::enum_switch ([] ( auto val) {
constexpr Color c_color = val;
// ...
}, color);
Enum iterasi untuk setiap enum sebagai konstanta constexpr
magic_enum::enum_for_each<Color>([] ( auto val) {
constexpr Color c_color = val;
// ...
});
Periksa apakah enum berisi
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
Indeks enum secara berurutan
constexpr auto color_index = magic_enum::enum_index(Color::BLUE);
// color_index.value() -> 1
// color_index.has_value() -> true
Fungsi untuk bendera
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"
Nama tipe enum
Color color = Color::RED;
auto type_name = magic_enum::enum_type_name<decltype(color)>();
// type_name -> "Color"
Operator IOstream untuk enum
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;
Operator bitwise untuk enum
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;
Memeriksa apakah tipenya merupakan enumerasi tanpa cakupan.
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
Memeriksa apakah tipenya merupakan enumerasi tercakup.
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
Variabel enum penyimpanan statis ke string Versi ini jauh lebih ringan pada waktu kompilasi dan tidak dibatasi pada batasan enum_range.
constexpr Color color = Color::BLUE;
constexpr auto color_name = magic_enum::enum_name<color>();
// color_name -> "BLUE"
containers::array
untuk enum.
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
wadah bitset untuk enum.
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
setel wadah untuk enum.
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
Underlying_type "ramah SFINAE" bebas UB yang ditingkatkan.
magic_enum::underlying_type<color>::type -> int
// Helper types.
magic_enum:: underlying_type_t <Direction> -> int
magic_enum
tidak berpura-pura menjadi solusi terbaik untuk refleksi enum, ini pada awalnya dirancang untuk enum kecil.
Sebelum digunakan, baca batasan fungsionalitas.
Anda harus menambahkan file yang diperlukan magic_enum.hpp, dan opsional header lain dari direktori include atau arsip rilis. Alternatifnya, Anda dapat membangun perpustakaan dengan CMake.
Jika Anda menggunakan vcpkg pada proyek Anda untuk dependensi eksternal, Anda dapat menggunakan paket magic-enum.
Jika Anda menggunakan Conan untuk mengelola dependensi Anda, cukup tambahkan magic_enum/xyz
ke kebutuhan conan Anda, dengan xyz
adalah versi rilis yang ingin Anda gunakan.
Jika Anda menggunakan Build2 untuk membangun dan mengelola dependensi Anda, tambahkan depends: magic_enum ^xyz
ke file manifes dengan xyz
adalah versi rilis yang ingin Anda gunakan. Anda kemudian dapat mengimpor target menggunakan magic_enum%lib{magic_enum}
.
Alternatifnya, Anda dapat menggunakan sesuatu seperti CPM yang didasarkan pada modul 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 juga didukung, cukup tambahkan ke file WORKSPACE Anda:
http_archive(
name = "magic_enum",
strip_prefix = "magic_enum-<commit>",
urls = ["https://github.com/Neargye/magic_enum/archive/<commit>.zip"],
)
Untuk menggunakan bazel di dalam repositori, Anda dapat melakukan:
bazel build //...
bazel test //...
bazel run //example
(Perhatikan bahwa Anda harus menggunakan kompiler yang didukung atau menentukannya dengan export CC= <compiler>
.)
Jika Anda menggunakan Ros, Anda dapat menyertakan paket ini dengan menambahkan <depend>magic_enum</depend>
ke package.xml Anda dan menyertakan paket ini di ruang kerja Anda. Di CMakeLists.txt Anda, tambahkan yang berikut:
find_package (magic_enum CONFIG REQUIRED)
...
target_link_libraries (your_executable magic_enum::magic_enum)