### Example of Custom Configuration File Usage (C++) Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md This example demonstrates how to define ENCHANTUM_CONFIG_FILE to point to a custom header, which in turn can redefine other Enchantum macros like ENCHANTUM_OPTIONAL and ENCHANTUM_STRING. ```cpp #define ENCHANTUM_CONFIG_FILE "my_enchantum_config.hpp" #include ``` ```cpp #include "my_optional.hpp" #define ENCHANTUM_OPTIONAL template using optional = my_optional; #include "my_string.hpp" #define ENCHANTUM_STRING using string = my_string; ``` -------------------------------- ### Enchantum Installation Configuration Source: https://github.com/zxshady/enchantum/blob/main/CMakeLists.txt Configures the installation of the Enchantum library, including targets, headers, and CMake package configuration files. This ensures the library can be easily integrated into other projects. ```cmake install(TARGETS enchantum EXPORT enchantumTargets COMPONENT enchantum ) include(GNUInstallDirs) install(DIRECTORY ${INCDIR}/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT enchantum FILES_MATCHING PATTERN "*.hpp" ) install(EXPORT enchantumTargets NAMESPACE enchantum:: DESTINATION ${CMAKE_INSTALL_DATADIR}/enchantum/cmake COMPONENT enchantum ) include(CMakePackageConfigHelpers) write_basic_package_version_file( "${CMAKE_CURRENT_BINARY_DIR}/enchantumConfigVersion.cmake" VERSION ${PROJECT_VERSION} COMPATIBILITY AnyNewerVersion ) configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/enchantumConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/enchantumConfig.cmake" INSTALL_DESTINATION cmake ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/enchantumConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/enchantumConfigVersion.cmake" DESTINATION cmake COMPONENT enchantum ) export( TARGETS enchantum NAMESPACE enchantum:: FILE "${CMAKE_CURRENT_BINARY_DIR}/enchantumTargets.cmake" ) ``` -------------------------------- ### Enchantum CMake Project Setup Source: https://github.com/zxshady/enchantum/blob/main/CMakeLists.txt Initializes the CMake project, setting the minimum version, project name, version, homepage, and description. It also specifies the CXX language standard. ```cmake cmake_minimum_required(VERSION 3.22.0) project(enchantum VERSION 0.4.0 HOMEPAGE_URL "https://github.com/ZXShady/enchantum" DESCRIPTION "Fast macro-free enum reflection C++ library" LANGUAGES CXX) if(POLICY CMP0128) cmake_policy(SET CMP0128 NEW) endif() set(INCDIR "${CMAKE_CURRENT_SOURCE_DIR}/enchantum/include") file(GLOB_RECURSE INCS "${INCDIR}/*.hpp") add_library(enchantum INTERFACE ${INCS}) add_library(enchantum::enchantum ALIAS enchantum) target_compile_features(enchantum INTERFACE cxx_std_17) target_include_directories(enchantum INTERFACE $ $ ) ``` -------------------------------- ### Benchmark Executable Setup (CMake) Source: https://github.com/zxshady/enchantum/blob/main/benchmarks/CMakeLists.txt This CMake code defines an executable target named 'benchmarks'. It includes necessary directories for magic_enum, links against the enchantum library and Catch2 for testing, and sets platform-specific compiler options for enhanced code quality and portability. This is essential for building and running performance benchmarks. ```cmake add_executable(benchmarks) target_include_directories(benchmarks PRIVATE "${magic_enum_SOURCE_DIR}/include") target_link_libraries(benchmarks enchantum::enchantum Catch2::Catch2 Catch2::Catch2WithMain) ``` -------------------------------- ### Configuring Enum Range with Macros in C++ Source: https://github.com/zxshady/enchantum/blob/main/docs/limitations.md This example shows how to configure the minimum and maximum range for enum values reflected by Enchantum using preprocessor macros. It includes the necessary header and demonstrates setting custom ranges. ```cpp #define ENCHANTUM_MIN_RANGE 0 // if not defined it will be -512 #define ENCHANTUM_MAX_RANGE 512 #include ``` -------------------------------- ### Navigate Enum Values Sequentially with Enchantum (C++) Source: https://context7.com/zxshady/enchantum/llms.txt Demonstrates how to use enchantum::next_value and enchantum::prev_value for sequential navigation through enum members. It covers both standard behavior (returning nullopt at boundaries) and circular navigation using *_circular variants. The example also shows how to skip multiple enum values. ```cpp #include #include enum class Season { Spring, Summer, Autumn, Winter }; int main() { // Get next value std::optional next = enchantum::next_value(Season::Summer); if (next.has_value()) { std::cout << "After Summer: " << enchantum::to_string(*next) << std::endl; // Output: After Summer: Autumn } // Get previous value std::optional prev = enchantum::prev_value(Season::Summer); if (prev.has_value()) { std::cout << "Before Summer: " << enchantum::to_string(*prev) << std::endl; // Output: Before Summer: Spring } // Returns nullopt at boundaries std::optional after_winter = enchantum::next_value(Season::Winter); std::cout << "After Winter valid: " << after_winter.has_value() << std::endl; // Output: After Winter valid: 0 // Circular navigation wraps around Season circular_next = enchantum::next_value_circular(Season::Winter); std::cout << "Circular after Winter: " << enchantum::to_string(circular_next) << std::endl; // Output: Circular after Winter: Spring Season circular_prev = enchantum::prev_value_circular(Season::Spring); std::cout << "Circular before Spring: " << enchantum::to_string(circular_prev) << std::endl; // Output: Circular before Spring: Winter // Skip multiple values std::optional skip2 = enchantum::next_value(Season::Spring, 2); std::cout << "Spring + 2: " << enchantum::to_string(*skip2) << std::endl; // Output: Spring + 2: Autumn } ``` -------------------------------- ### Get Enum Entries (Name-Value Pairs) (C++) Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md Provides a sorted array of pairs, where each pair contains an enum value and its corresponding string name. This is useful for serialization, reflection, or display purposes. ```cpp // defined in header entries.hpp template,bool NullTerminated = true> inline constexpr std::array> entries; // Example Usage: enum class Color { Red, Green = -2, Blue }; for (const auto& [value,string] : enchantum::entries) { std::cout << static_cast(value) << " = " << name << std::endl; } // Outputs: // -2 = "Green" // -1 = "Blue" // 0 = "Red" ``` -------------------------------- ### Get Raw Type Name (C++) Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md Returns a string view representing the raw name of a given type, including namespaces. This is useful for precise type identification. ```cpp // defined in header `type_name.hpp` template constexpr inline std::string_view raw_type_name = /*implementation detail*/; // Example Usage: enum class Enum : std::uint8_t; native namespace NS { struct Type; } enchantum::raw_type_name; enchantum::raw_type_name; // Gives on ALL compilers: // "Enum" // "NS::Type" // Other output may be compiler dependant ``` -------------------------------- ### Workaround for Unscoped Enums in Clang Templates (C++) Source: https://github.com/zxshady/enchantum/blob/main/docs/limitations.md This example shows a common issue with unscoped enums within templates on Clang and provides a workaround by using a type alias that references an enumerator, ensuring proper reflection. ```cpp template struct ReallyClang_QuestionMark { enum Type { A,B,C }; }; enchantum::entries::Type>; // some long compiler error // Workaround: template struct GoodClang { enum Type_ { A,B,C }; using Type = decltype(Type_::A); }; enchantum::entries::Type>; // happy clang ``` -------------------------------- ### Get Maximum Enum Value (C++) Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md Retrieves the maximum value of an enum type. This utility is useful for determining the range or bounds of an enum. ```cpp template inline constexpr E max; // Example Usage: enum class Status { Ok = -1, Error = 1, Unknown = 53 }; auto maxValue = enchantum::max; // Status::Unknown std::cout << static_cast(maxValue) << std::endl; // Outputs: 53 ``` -------------------------------- ### Fetch and Configure Catch2 Testing Framework (CMake) Source: https://github.com/zxshady/enchantum/blob/main/tests/CMakeLists.txt This snippet demonstrates how to fetch the Catch2 testing framework using FetchContent, make it available, and configure it for use within the project. It sets the C++ standard to C++17 and enables optional string maker support for Catch2. ```cmake include(FetchContent) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG devel ) FetchContent_MakeAvailable(Catch2) target_compile_features(Catch2 PRIVATE cxx_std_17) target_compile_definitions(Catch2 PUBLIC CATCH_CONFIG_ENABLE_OPTIONAL_STRINGMAKER) ``` -------------------------------- ### Get Enum Values (C++) Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md Returns a sorted array containing all the enumerator values of an enum type. This is equivalent to extracting the values from the `entries` array. ```cpp // defined in header entries.hpp template constexpr std::array> values; // Example Usage: enum class Color { Red, Green, Blue }; for (auto value : enchantum::values) std::cout << static_cast(value) << std::endl; // Outputs: 0, 1, 2 (Red, Green, Blue) ``` -------------------------------- ### Aliased Enums Not Supported on NVC++ (C++) Source: https://github.com/zxshady/enchantum/blob/main/docs/limitations.md This example highlights that aliased enums (using 'using' to create a new name for an existing enum class) are not supported on the NVC++ compiler. ```cpp enum class A { a,b,c }; using B = A; enchantum::entries; // fails ``` -------------------------------- ### Get Type Name (C++) Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md Returns a string view representing the name of a given type. This utility is useful for debugging and introspection. It has limitations on function types and templated types. ```cpp // defined in header `type_name.hpp` template constexpr inline std::string_view type_name = /*implementation detail*/; // Example Usage: enum class Enum : std::uint8_t; native namespace NS { struct Type; } enchantum::type_name; enchantum::type_name; // ignores namespaces // Gives on ALL compilers: // "Enum" // "Type" // Other output may be compiler dependant ``` -------------------------------- ### Gather Source Files (CMake) Source: https://github.com/zxshady/enchantum/blob/main/benchmarks/CMakeLists.txt This CMake command uses `file(GLOB_RECURSE)` to find all `.cpp` and `.hpp` files recursively within the current directory and its subdirectories. These files are then added to the 'benchmarks' target using `target_sources`. This automates the inclusion of source code, simplifying the build process. ```cmake # Gather source files file(GLOB_RECURSE SRCS "*.cpp" "*.hpp") target_sources(benchmarks PRIVATE ${SRCS} ) ``` -------------------------------- ### Fetch and Make Magic Enum Available (CMake) Source: https://github.com/zxshady/enchantum/blob/main/benchmarks/CMakeLists.txt This snippet uses CMake's FetchContent module to download and make the magic_enum library available. It specifies the Git repository and tag to use, ensuring a consistent dependency. This is crucial for projects relying on magic_enum for enum reflection capabilities. ```cmake include(FetchContent) FetchContent_Declare(magic_enum GIT_REPOSITORY https://github.com/Neargye/magic_enum.git GIT_SHALLOW ON GIT_TAG master) FetchContent_MakeAvailable(magic_enum) ``` -------------------------------- ### Get Minimum Enum Value in C++ Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md Provides a compile-time constant `min` that holds the minimum value of a given enum type `E`. This is useful for determining the smallest possible value an enum can represent. ```cpp template inline constexpr E min; // Example Usage: // enum class Status { Ok = -1, Error = 1, Unknown = 2 }; // auto minValue = enchantum::min; // Status::Ok // std::cout << static_cast(minValue) << std::endl; // Outputs: -1 ``` -------------------------------- ### Include Custom Configuration File Macro (C++) Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md The ENCHANTUM_CONFIG_FILE macro allows for the inclusion of a custom configuration file in all Enchantum files. This enables users to override default settings and include project-specific configurations. ```cpp #ifdef ENCHANTUM_CONFIG_FILE #include ENCHANTUM_CONFIG_FILE #endif ``` -------------------------------- ### Add Enchantum Subdirectory and Link Library (CMake) Source: https://github.com/zxshady/enchantum/blob/main/README.md This snippet demonstrates how to add the Enchantum library as a subdirectory in your CMake project and then link the `enchantum::enchantum` target to your executable. This is the recommended approach for header-only libraries. ```cmake add_subdirectory("third_party/enchantum") target_link_libraries(your_executable enchantum::enchantum) ``` -------------------------------- ### Check for Contiguous Enum Type Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md Tests if an enum type E has contiguous underlying integer values. For example, an enum with values 0, 1, 2 is contiguous. This concept is useful for enums where sequential values are important. ```cpp template concept ContiguousEnum = Enum && is_contiguous; ``` -------------------------------- ### Map Enum to Index and Vice Versa in C++ Source: https://github.com/zxshady/enchantum/blob/main/README.md Demonstrates converting between enum values and their corresponding indices using enchantum's enum_to_index and index_to_enum functions. This allows for efficient lookups and mapping. ```cpp #include // index_to_enum and enum_to_index enum class Music { Rock, Jazz , Metal }; int main() { // case sensitive std::optional music = enchantum::index_to_enum(1); // Jazz is the second enum member if(music.has_value()) // check if index is not out of bounds { // *music == Music::Jazz std::optional index = enchantum::enum_to_index(*music); // *index == 1 } } ``` -------------------------------- ### Define and Configure Configuration Test Executable (CMake) Source: https://github.com/zxshady/enchantum/blob/main/tests/CMakeLists.txt This snippet defines a separate executable 'tests_config' for configuration-related tests. It sets the C++ standard to C++17, defines a specific configuration header, and links against Catch2 and the project library. ```cmake add_executable(tests_config) target_compile_features(tests_config PRIVATE cxx_std_17) target_compile_definitions(tests_config PRIVATE ENCHANTUM_CONFIG_FILE="config_test/config.hpp") target_sources(tests_config PRIVATE config_test/config.cpp config_test/config.hpp) target_include_directories(tests_config PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(tests_config Catch2::Catch2WithMain enchantum::enchantum) ``` -------------------------------- ### Get Enum Type Name String with type_name Source: https://context7.com/zxshady/enchantum/llms.txt Provides a utility to retrieve the string representation of an enum's type name at compile time. This is useful for debugging, logging, or dynamic introspection. It requires the `` header. The `raw_type_name` variant includes namespace information. ```cpp #include #include namespace MyApp { enum class ErrorCode { Success, Failure, Timeout }; } enum class GlobalEnum { A, B, C }; int main() { // Get type name (without namespace) std::cout << "Type: " << enchantum::type_name << std::endl; // Output: Type: ErrorCode std::cout << "Type: " << enchantum::type_name << std::endl; // Output: Type: GlobalEnum // raw_type_name includes namespace std::cout << "Raw: " << enchantum::raw_type_name << std::endl; // Output: Raw: MyApp::ErrorCode } ``` -------------------------------- ### Check for C++ Header Support (CMake) Source: https://github.com/zxshady/enchantum/blob/main/tests/CMakeLists.txt This snippet checks if the compiler supports the C++20 `` header by attempting to compile a small test program. If support is not found, it informs the user and removes related test source files from the build. ```cmake get_target_property(STD tests CXX_STANDARD) if(MSVC) set(CMAKE_REQUIRED_FLAGS "/std:c++${STD}") else() set(CMAKE_REQUIRED_FLAGS "-std=c++${STD}") endif() check_cxx_source_compiles(" #include int main() { auto s = std::format("{}",42); (void)s; return 0; }" HAS_STD_FORMAT ) if(NOT HAS_STD_FORMAT) message(STATUS "This compiler does not support header not running std_format.cpp tests") list(REMOVE_ITEM SRCS "${CMAKE_CURRENT_SOURCE_DIR}/std_format.cpp") endif() ``` -------------------------------- ### Enchantum Build Options Configuration Source: https://github.com/zxshady/enchantum/blob/main/CMakeLists.txt Configures build options for tests, MSVC speedup, and benchmarks using CMake's `option` command. These options control the inclusion of testing, benchmarking, and specific compiler optimizations. ```cmake option(ENCHANTUM_BUILD_TESTS "Enable tests for this `enchantum` library" OFF) option(ENCHANTUM_ENABLE_MSVC_SPEEDUP "Enable faster but not 100% accurate MSVC enum reflection." ON) option(ENCHANTUM_BUILD_BENCHMARKS "Enable compile time benchmarks `enchantum` library" OFF) target_compile_definitions(enchantum INTERFACE ENCHANTUM_ENABLE_MSVC_SPEEDUP=$) if(ENCHANTUM_BUILD_TESTS) enable_testing() add_subdirectory(tests) endif() if(ENCHANTUM_BUILD_BENCHMARKS) add_subdirectory(benchmarks) endif() ``` -------------------------------- ### Define and Configure Test Executable (CMake) Source: https://github.com/zxshady/enchantum/blob/main/tests/CMakeLists.txt This code defines the main test executable 'tests'. It specifies include directories, C++ standard, and links against the project's library ('enchantum::enchantum') and the Catch2 testing framework. It also includes conditional compilation for runtime tests and platform-specific compiler options. ```cmake add_executable(tests) target_include_directories(tests PRIVATE "third_party") target_compile_features(tests PRIVATE cxx_std_17) target_link_libraries(tests PRIVATE enchantum::enchantum Catch2::Catch2WithMain) if(ENCHANTUM_RUNTIME_TESTS) message(STATUS "enchantum tests are being ran at runtime") target_compile_definitions(tests PRIVATE CATCH_CONFIG_RUNTIME_STATIC_REQUIRE) endif() if(MSVC) target_compile_options(tests PRIVATE /Za /permissive-) target_compile_options(tests PRIVATE /WX /W4) else() target_compile_options(tests PRIVATE -Werror -Wall -Wextra -Wshadow -Wconversion -Wpedantic) endif() file(GLOB SRCS "*.cpp" "*.hpp") ``` -------------------------------- ### Compile-Time Enum Iteration with for_each Source: https://context7.com/zxshady/enchantum/llms.txt Demonstrates how to iterate over all enum values at compile time using `enchantum::for_each` with `std::integral_constant`. This enables compile-time optimizations and allows processing each enum member without runtime overhead. It requires the `` header. ```cpp #include #include #include enum class Operation { Add, Subtract, Multiply, Divide }; template int compute(int a, int b) { if constexpr (Op == Operation::Add) return a + b; else if constexpr (Op == Operation::Subtract) return a - b; else if constexpr (Op == Operation::Multiply) return a * b; else return a / b; } int main() { int a = 10, b = 5; // for_each receives std::integral_constant enchantum::for_each([&](auto constant) { constexpr Operation op = constant.value; int result = compute(a, b); std::cout << enchantum::to_string(op) << ": " << result << std::endl; }); // Output: // Add: 15 // Subtract: 5 // Multiply: 50 // Divide: 2 // Sum all enum underlying values std::underlying_type_t sum = 0; enchantum::for_each([&sum](auto constant) { sum += enchantum::to_underlying(constant.value); }); std::cout << "Sum of values: " << sum << std::endl; // Output: Sum of values: 6 } ``` -------------------------------- ### Iterate Enum Values, Names, and Entries with Enchantum Collections (C++) Source: https://context7.com/zxshady/enchantum/llms.txt Demonstrates how to use enchantum::values, enchantum::names, and enchantum::entries to iterate over all values, names, and value-name pairs of an enum. This requires including and . It provides compile-time arrays for efficient access. ```cpp #include #include #include enum class Priority { Low = 1, Medium = 5, High = 10, Critical = 100 }; int main() { // Iterate over all values std::cout << "Values: "; for (Priority p : enchantum::values) { std::cout << static_cast(p) << " "; } std::cout << std::endl; // Output: Values: 1 5 10 100 // Iterate over all names std::cout << "Names: "; for (std::string_view name : enchantum::names) { std::cout << name << " "; } std::cout << std::endl; // Output: Names: Low Medium High Critical // Iterate over entries (value-name pairs) std::cout << "Entries:" << std::endl; for (const auto& [value, name] : enchantum::entries) { std::cout << " " << name << " = " << static_cast(value) << std::endl; } // Output: // Low = 1 // Medium = 5 // High = 10 // Critical = 100 // Access count, min, max std::cout << "Count: " << enchantum::count << std::endl; // Output: Count: 4 std::cout << "Min: " << static_cast(enchantum::min) << std::endl; // Output: Min: 1 std::cout << "Max: " << static_cast(enchantum::max) << std::endl; // Output: Max: 100 } ``` -------------------------------- ### Platform-Specific Compiler Options (CMake) Source: https://github.com/zxshady/enchantum/blob/main/benchmarks/CMakeLists.txt This CMake snippet configures compiler options tailored for different platforms. For MSVC (Microsoft Visual C++), it enables stricter warnings and permissive mode. For other compilers (like GCC/Clang), it enables a comprehensive set of warnings to catch potential issues. This ensures robust code compilation across various development environments. ```cmake if(MSVC) target_compile_options(benchmarks PRIVATE /Za /permissive-) target_compile_options(benchmarks PRIVATE /W4) else() target_compile_options(benchmarks PRIVATE -Wall -Wextra -Wconversion -Wpedantic) endif() ``` -------------------------------- ### Enum-Indexed Bitset with enchantum::bitset Source: https://context7.com/zxshady/enchantum/llms.txt Illustrates the use of enchantum::bitset, a bitset container that leverages enum values for type-safe flag management. It supports setting, resetting, flipping, checking status, converting to string, and counting set bits. ```cpp #include #include enum class Feature { FeatureA, FeatureB, FeatureC, FeatureD }; int main() { // Create with initializer list enchantum::bitset features{Feature::FeatureA, Feature::FeatureC}; // Check if feature is enabled std::cout << "FeatureA: " << features[Feature::FeatureA] << std::endl; // Output: FeatureA: 1 std::cout << "FeatureB: " << features[Feature::FeatureB] << std::endl; // Output: FeatureB: 0 // Set and reset features features.set(Feature::FeatureB); features.reset(Feature::FeatureA); std::cout << "After changes - A: " << features[Feature::FeatureA] << ", B: " << features[Feature::FeatureB] << std::endl; // Output: After changes - A: 0, B: 1 // Flip a feature features.flip(Feature::FeatureC); std::cout << "FeatureC after flip: " << features[Feature::FeatureC] << std::endl; // Output: FeatureC after flip: 0 // Convert to string representation features.set(Feature::FeatureA); features.set(Feature::FeatureD); std::string str = features.to_string(); std::cout << "Enabled: " << str << std::endl; // Output: Enabled: FeatureA|FeatureB|FeatureD // Count set bits std::cout << "Count: " << features.count() << std::endl; // Output: Count: 3 } ``` -------------------------------- ### Enum Formatting Support (C++) Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md Enables formatting of enum values using `std::format` and `fmt::format`. This is achieved by providing `std::formatter` and `fmt::formatter` specializations for all enum types through dedicated headers. ```cpp #include // or #include // or fmt_format.hpp enum class Letters {a,b,c,e,d}; std::cout << std::format("{} then {} then {}",Letters::a,Letters::b,Letters::c); // a then b then c ``` -------------------------------- ### Discover Tests with Catch2 (CMake) Source: https://github.com/zxshady/enchantum/blob/main/tests/CMakeLists.txt This code includes the Catch2 CMake module and uses the 'catch_discover_tests' command to automatically discover and add tests defined in the 'tests' and 'tests_config' executables to CTest. ```cmake include(CTest) include(Catch) catch_discover_tests(tests) catch_discover_tests(tests_config) ``` -------------------------------- ### Custom Enum Reflection Ranges with enum_traits Source: https://context7.com/zxshady/enchantum/llms.txt Explains how to specialize enchantum::enum_traits to customize reflection behavior for enums, including defining custom value ranges (min/max) and stripping common prefixes from enum member names. ```cpp #include #include // Enum with values outside default range [-256, 256] enum class BigEnum : int { ValueA = 1000, ValueB = 2000, ValueC = 3000 }; // C-style enum with common prefix enum OldStyleEnum { OldStyleEnum_First = 0, OldStyleEnum_Second = 1, OldStyleEnum_Third = 2 }; // Specialize enum_traits for BigEnum template<> struct enchantum::enum_traits { static constexpr auto min = 1000; static constexpr auto max = 3000; }; // Specialize for prefix stripping template<> struct enchantum::enum_traits { static constexpr std::size_t prefix_length = sizeof("OldStyleEnum_") - 1; static constexpr auto min = 0; static constexpr auto max = 2; }; int main() { // BigEnum now works with reflection std::cout << "BigEnum count: " << enchantum::count << std::endl; // Output: BigEnum count: 3 std::cout << "ValueB: " << enchantum::to_string(BigEnum::ValueB) << std::endl; // Output: ValueB: ValueB for (auto [val, name] : enchantum::entries) { std::cout << name << " = " << static_cast(val) << std::endl; } // Output: // ValueA = 1000 // ValueB = 2000 // ValueC = 3000 // Prefix is stripped from names std::cout << "OldStyle names: "; for (auto name : enchantum::names) { std::cout << name << " "; } std::cout << std::endl; // Output: OldStyle names: First Second Third } ``` -------------------------------- ### Iterate Over Enum Members in C++ Source: https://github.com/zxshady/enchantum/blob/main/README.md Shows how to iterate over enum values, names, and entries (pairs of enum value and name) using enchantum's generator functions. This facilitates processing all members of an enum. ```cpp #include // entries,values and names enum class Music { Rock, Jazz , Metal }; int main() { // Iterate over values for(Music music : enchantum::values_generator) std::cout << static_cast(music) << " "; // Prints "0 1 2" // Iterate over names for(std::string_view name : enchantum::names_generator) std::cout << name << " "; // Prints "Rock Jazz Metal" // Iterate over both! for(const auto [music,name] : enchantum::entries_generator) std::cout << name << " = " << static_cast(music) << "\n"; // Prints // Rock = 0 // Jazz = 1 // Metal = 2 } ``` -------------------------------- ### Work with Bitflag Enums using Enchantum (C++) Source: https://context7.com/zxshady/enchantum/llms.txt Illustrates the use of Enchantum for bitflag enums, including converting bitflags to strings with custom separators, parsing strings into bitflags, and validating bitflag combinations. It requires the ENCHANTUM_DEFINE_BITWISE_FOR macro and standard bitwise operators to be defined for the enum. ```cpp #include #include #include #include #include enum class Permissions : std::uint8_t { None = 0, Read = 1 << 0, Write = 1 << 1, Execute = 1 << 2 }; ENCHANTUM_DEFINE_BITWISE_FOR(Permissions) int main() { Permissions perms = Permissions::Read | Permissions::Write; // Convert bitflag to string std::string str = enchantum::to_string_bitflag(perms); std::cout << "Permissions: " << str << std::endl; // Output: Permissions: Read|Write // Custom separator std::string comma_str = enchantum::to_string_bitflag(perms, ','); std::cout << "With comma: " << comma_str << std::endl; // Output: With comma: Read,Write // Parse string to bitflag std::optional parsed = enchantum::cast_bitflag("Read|Execute"); if (parsed.has_value()) { std::cout << "Parsed value: " << static_cast(*parsed) << std::endl; // Output: Parsed value: 5 } // Validate bitflag combination std::cout << "Valid combo: " << enchantum::contains_bitflag(perms) << std::endl; // Output: Valid combo: 1 std::cout << "Invalid combo: " << enchantum::contains_bitflag(Permissions(128)) << std::endl; // Output: Invalid combo: 0 // Check if string is valid bitflag std::cout << "String valid: " << enchantum::contains_bitflag("Read|Write") << std::endl; // Output: String valid: 1 // Get OR of all values Permissions all = enchantum::value_ors; std::cout << "All permissions: " << static_cast(all) << std::endl; // Output: All permissions: 7 } ``` -------------------------------- ### Navigate Enum Values Linearly and Circularly (C++) Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md Provides functionalities to navigate through enum values. `next_value` and `prev_value` move linearly, returning std::optional or std::nullopt if out of bounds. `next_value_circular` and `prev_value_circular` wrap around the enum range. ```cpp // defined in header next_value.hpp namespace details { struct NEXT_VALUE_FUNCTOR { template constexpr std::optional operator()(E value, std::ptrdiff_t n = 1) noexcept; }; struct NEXT_VALUE_CIRCULAR_FUNCTOR { template constexpr E operator()(E value, std::ptrdiff_t n = 1) noexcept; }; } inline constexpr details::NEXT_VALUE_FUNCTOR next_value; inline constexpr details::PREV_VALUE_FUNCTOR prev_value; inline constexpr details::NEXT_VALUE_CIRCULAR_FUNCTOR next_value_circular; inline constexpr details::PREV_VALUE_CIRCULAR_FUNCTOR prev_value_circular; // Example: #include enum class Direction { North, East, South, West }; std::optional next = enchantum::next_value(Direction::East); std::cout << (next.has_value() ? "Found next value" : "No next value") << std::endl; // Outputs: Found next value Direction nextCircular = enchantum::next_value_circular(Direction::West); std::cout << "Circular next value: " << static_cast(nextCircular) << std::endl; // Outputs: Circular next value: 0 (North) std::optional prev = enchantum::prev_value(Direction::South); std::cout << (prev.has_value() ? "Found previous value" : "No previous value") << std::endl; // Outputs: Found previous value Direction prevCircular = enchantum::prev_value_circular(Direction::North); std::cout << "Circular previous value: " << static_cast(prevCircular) << std::endl; // Outputs: Circular previous value: 3 (West) ``` -------------------------------- ### Enum Type Constraints with Concepts and Traits Source: https://context7.com/zxshady/enchantum/llms.txt Illustrates how to use C++20 concepts (`enchantum::Enum`, `enchantum::BitFlagEnum`, `enchantum::ContiguousEnum`) and C++17 traits (`enchantum::is_scoped_enum`, `enchantum::is_unscoped_enum`, `enchantum::is_bitflag`, `enchantum::is_contiguous`) to constrain template parameters to specific types of enums. This enhances type safety and allows for specialized template implementations. Requires ``, ``, and ``. ```cpp #include #include #include #include enum class SignedStatus : int { Negative = -1, Zero = 0, Positive = 1 }; enum class UnsignedFlags : unsigned { None = 0, Flag1 = 1, Flag2 = 2 }; ENCHANTUM_DEFINE_BITWISE_FOR(UnsignedFlags) enum UnscopedEnum { ValueA, ValueB }; // Function constrained to any enum template void print_enum(E e) { std::cout << "Enum: " << enchantum::to_string(e) << std::endl; } // Function constrained to bitflag enums template void print_flags(E e) { std::cout << "Flags: " << enchantum::to_string_bitflag(e) << std::endl; } // Function constrained to contiguous enums template void fast_lookup(E e) { // Can use O(1) lookup for contiguous enums std::cout << "Fast lookup: " << enchantum::to_string(e) << std::endl; } int main() { // Concept checks static_assert(enchantum::Enum); static_assert(enchantum::SignedEnum); static_assert(enchantum::UnsignedEnum); static_assert(enchantum::ScopedEnum); static_assert(enchantum::UnscopedEnum); static_assert(enchantum::BitFlagEnum); // Trait checks static_assert(enchantum::is_scoped_enum); static_assert(enchantum::is_unscoped_enum); static_assert(enchantum::is_bitflag); static_assert(enchantum::is_contiguous); print_enum(SignedStatus::Positive); // Output: Enum: Positive print_flags(UnsignedFlags::Flag1 | UnsignedFlags::Flag2); // Output: Flags: Flag1|Flag2 fast_lookup(SignedStatus::Zero); // Output: Fast lookup: Zero std::cout << "All checks passed!" << std::endl; } ``` -------------------------------- ### Lightweight Enum Iteration with Enchantum Generators (C++) Source: https://context7.com/zxshady/enchantum/llms.txt Utilizes enchantum::values_generator, enchantum::names_generator, and enchantum::entries_generator for on-the-fly enum iteration, reducing binary size compared to storing collections. Include and . Supports random access for names and entries. ```cpp #include #include #include enum class Fruit { Apple, Banana, Cherry, Date }; int main() { // Iterate values without storing them std::cout << "Values: "; for (Fruit f : enchantum::values_generator) { std::cout << static_cast(f) << " "; } std::cout << std::endl; // Output: Values: 0 1 2 3 // Iterate names without storing them std::cout << "Names: "; for (std::string_view name : enchantum::names_generator) { std::cout << name << " "; } std::cout << std::endl; // Output: Names: Apple Banana Cherry Date // Iterate entries without storing them for (auto [value, name] : enchantum::entries_generator) { std::cout << name << " -> " << static_cast(value) << std::endl; } // Random access is also supported std::cout << "Second fruit: " << enchantum::names_generator[1] << std::endl; // Output: Second fruit: Banana } ``` -------------------------------- ### std::format and fmt::format Support for Enums in C++ Source: https://context7.com/zxshady/enchantum/llms.txt Provides formatters for seamless integration with std::format (C++20) or the fmt::format library. This allows enums to be directly included in formatted strings. Requires including or . ```cpp #include // or for fmt #include #include enum class HttpStatus { Ok = 200, NotFound = 404, InternalError = 500 }; int main() { HttpStatus status = HttpStatus::NotFound; // Use with std::format std::string msg = std::format("Status: {}", status); std::cout << msg << std::endl; // Output: Status: NotFound // Multiple enums in format string std::string multi = std::format("{} -> {}", HttpStatus::Ok, HttpStatus::InternalError); std::cout << multi << std::endl; // Output: Ok -> InternalError } ``` -------------------------------- ### Enum to Index and Index to Enum Conversion with Enchantum (C++) Source: https://context7.com/zxshady/enchantum/llms.txt Provides enchantum::index_to_enum and enchantum::enum_to_index for converting between array indices and enum values, useful for serialization or enum-indexed data structures. Requires . Handles out-of-bounds indices and invalid enum values by returning std::optional. ```cpp #include #include enum class Weekday { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }; int main() { // Convert index to enum std::optional day = enchantum::index_to_enum(2); if (day.has_value()) { std::cout << "Index 2: " << enchantum::to_string(*day) << std::endl; // Output: Index 2: Wednesday } // Out of bounds returns nullopt std::optional invalid = enchantum::index_to_enum(10); std::cout << "Index 10 valid: " << invalid.has_value() << std::endl; // Output: Index 10 valid: 0 // Convert enum to index std::optional idx = enchantum::enum_to_index(Weekday::Friday); if (idx.has_value()) { std::cout << "Friday index: " << *idx << std::endl; // Output: Friday index: 4 } // Invalid enum value returns nullopt std::optional bad_idx = enchantum::enum_to_index(Weekday(99)); std::cout << "Invalid enum index: " << bad_idx.has_value() << std::endl; // Output: Invalid enum index: 0 // Use with enum-indexed array int data[enchantum::count] = {8, 8, 8, 8, 8, 0, 0}; // Work hours std::cout << "Friday hours: " << data[*enchantum::enum_to_index(Weekday::Friday)] << std::endl; // Output: Friday hours: 8 } ``` -------------------------------- ### Scoped Enum Utilities Source: https://github.com/zxshady/enchantum/blob/main/docs/features.md Provides scoped variants for common enum operations like casting, string conversion, and checking for containment. These functions operate within the `enchantum::scoped` namespace, offering a cleaner way to interact with enums and bitflags. ```APIDOC ## Scoped Functions (`enchantum::scoped`) ### Description Scoped variants for functions `cast`, `to_string`, `contains`, `cast_bitflag`, `to_string_bitflag`, `contains_bitflag`. They check or output the scope. ### Method Namespaced functions within `enchantum::scoped`. ### Examples ```cpp #include #include enum class InputModifiers { None = 0, Shift = 1 << 0, Control = 1 << 1, Alt = 1 << 2, }; ENCHANTUM_DEFINE_BITWISE_FOR(InputModifiers); int main() { // Outputs: "InputModifiers::Shift" std::cout << enchantum::scoped::to_string(InputModifiers::Shift); // Outputs: "InputModifiers::Control|InputModifiers::Alt" std::cout << enchantum::scoped::to_string_bitflag(InputModifiers::Control|InputModifiers::Alt); std::optional cast = enchantum::scoped::cast("InputModifiers::Shift"); // cast.value() == InputModifiers::Shift std::optional cast_bitflag = enchantum::scoped::cast_bitflags("InputModifiers::Control|InputModifiers::Alt"); // cast.value() == InputModifiers::Control|InputModifiers::Alt (7) } ``` ``` -------------------------------- ### iostream Support for Enums and Bitflags in C++ Source: https://context7.com/zxshady/enchantum/llms.txt Enables streaming of enum values (both regular and bitflags) using operator<< and operator>>. It simplifies input/output operations for enums, handling parsing and formatting automatically. Requires including and potentially for bitflags. ```cpp #include #include #include #include enum class LogLevel { Debug, Info, Warning, Error }; enum class Flags : unsigned { A = 1, B = 2, C = 4 }; ENCHANTUM_DEFINE_BITWISE_FOR(Flags) int main() { using namespace enchantum::iostream_operators; // Output enum to stream std::cout << LogLevel::Warning << std::endl; // Output: Warning // Input enum from stream std::istringstream iss("Error"); LogLevel level; if (iss >> level) { std::cout << "Read: " << level << std::endl; // Output: Read: Error } // Invalid input sets failbit std::istringstream bad_iss("invalid"); LogLevel bad_level; if (!(bad_iss >> bad_level)) { std::cout << "Failed to parse" << std::endl; // Output: Failed to parse } // Works with bitflags too Flags flags = Flags::A | Flags::C; std::cout << "Flags: " << flags << std::endl; // Output: Flags: A|C // Parse bitflag from stream std::istringstream flag_iss("A|B"); Flags parsed_flags; if (flag_iss >> parsed_flags) { std::cout << "Parsed flags: " << static_cast(parsed_flags) << std::endl; // Output: Parsed flags: 3 } } ```