1
0
Fork 0
mirror of https://github.com/Neargye/magic_enum.git synced 2026-01-09 23:34:23 +00:00

update doc

This commit is contained in:
Daniil Goncharov 2023-05-26 17:33:03 +04:00 committed by GitHub
parent 8f6c9905fd
commit 6304edd7f6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 118 additions and 85 deletions

102
README.md
View file

@ -24,46 +24,13 @@
Header-only C++17 library provides static reflection for enums, work with any enum type without any macro or boilerplate code. Header-only C++17 library provides static reflection for enums, work with any enum type without any macro or boilerplate code.
* `enum_cast` obtains enum value from string or integer.
* `enum_value` returns enum value at specified index.
* `enum_values` obtains enum value sequence.
* `enum_count` returns number of enum values.
* `enum_integer` obtains integer value from enum value.
* `enum_name` returns name from enum value.
* `enum_names` obtains string enum name sequence.
* `enum_entries` obtains pair (value enum, string enum name) sequence.
* `enum_index` obtains index in enum value sequence from enum value.
* `enum_contains` checks whether enum contains enumerator with such value.
* `enum_type_name` returns name of enum type.
* `enum_fuse` allows multidimensional switch/cases.
* `enum_switch` allows runtime enum value transformation to constexpr context.
* `enum_for_each` calls a function with all enum constexpr value.
* `is_unscoped_enum` checks whether type is an [Unscoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Unscoped_enumeration).
* `is_scoped_enum` checks whether type is an [Scoped enumeration](https://en.cppreference.com/w/cpp/language/enum#Scoped_enumerations).
* `underlying_type` improved UB-free "SFINAE-friendly" [underlying_type](https://en.cppreference.com/w/cpp/types/underlying_type).
* `ostream_operators` ostream operators for enums.
* `bitwise_operators` bitwise operators for enums.
* `containers::array` array container for enums.
* `containers::bitset` bitset container for enums.
* `containers::set` set container for enums.
## Documentation ## Documentation
* [Reference](doc/reference.md) * [Reference](doc/reference.md)
* [Limitations](doc/limitations.md) * [Limitations](doc/limitations.md)
* [Integration](#Integration) * [Integration](#Integration)
## Features ## [Examples](example/)
* C++17
* Header-only
* Dependency-free
* Compile-time
* Enum to string
* String to enum
* Iterating over enum
## [Examples](example/example.cpp)
* Enum value to string * Enum value to string
@ -124,8 +91,8 @@ Header-only C++17 library provides static reflection for enums, work with any en
```cpp ```cpp
Color color = Color::RED; Color color = Color::RED;
auto color_integer = magic_enum::enum_integer(color); auto color_integer = magic_enum::enum_integer(color); // or magic_enum::enum_underlying(color);
// color -> 1 // color_integer -> 1
``` ```
* Enum names sequence * Enum names sequence
@ -154,7 +121,7 @@ Header-only C++17 library provides static reflection for enums, work with any en
// ... // ...
} }
``` ```
* Enum switch runtime value as constexpr constant * Enum switch runtime value as constexpr constant
```cpp ```cpp
Color color = Color::RED; Color color = Color::RED;
@ -172,9 +139,58 @@ Header-only C++17 library provides static reflection for enums, work with any en
}); });
``` ```
* Ostream operator for enum * Check if enum contains
```cpp ```cpp
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
```
* Enum index in sequence
```cpp
constexpr auto color_index = magic_enum::enum_index(Color::BLUE);
// color_index.value() -> 1
// color_index.has_value() -> true
```
* Functions for flags
```cpp
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_name -> "Directions::Up|Directions::Right"
magic_enum::enum_flags_contains(Directions::Up | Directions::Right); // -> true
magic_enum::enum_flags_cast(3); // -> "Directions::Left|Directions::Down"
```
* Enum type name
```cpp
Color color = Color::RED;
auto type_name = magic_enum::enum_type_name<decltype(color)>();
// type_name -> "Color"
```
* IOstream operator for enum
```cpp
using namespace magic_enum::ostream_operators; // out-of-the-box ostream operators for enums.
Color color = Color::BLUE;
std::cout << color << std::endl; // "BLUE"
using namespace magic_enum::ostream_operators; // out-of-the-box ostream operators for enums. using namespace magic_enum::ostream_operators; // out-of-the-box ostream operators for enums.
Color color = Color::BLUE; Color color = Color::BLUE;
std::cout << color << std::endl; // "BLUE" std::cout << color << std::endl; // "BLUE"
@ -260,6 +276,14 @@ Header-only C++17 library provides static reflection for enums, work with any en
// size -> 3 // size -> 3
``` ```
* Improved UB-free "SFINAE-friendly" [underlying_type](https://en.cppreference.com/w/cpp/types/underlying_type).
```cpp
magic_enum::underlying_type<color>::type -> int
// Helper types.
magic_enum::underlying_type_t<Direction> -> int
```
## Remarks ## Remarks
* `magic_enum` does not pretend to be a silver bullet for reflection for enums, it was originally designed for small enum. * `magic_enum` does not pretend to be a silver bullet for reflection for enums, it was originally designed for small enum.
@ -315,7 +339,7 @@ Header-only C++17 library provides static reflection for enums, work with any en
## Compiler compatibility ## Compiler compatibility
* Clang/LLVM >= 6 * Clang/LLVM >= 5
* MSVC++ >= 14.11 / Visual Studio >= 2017 * MSVC++ >= 14.11 / Visual Studio >= 2017
* Xcode >= 10 * Xcode >= 10
* GCC >= 9 * GCC >= 9

View file

@ -14,7 +14,7 @@
* [`enum_fuse` returns a bijective mix of enum values.](#enum_fuse) * [`enum_fuse` returns a bijective mix of enum values.](#enum_fuse)
* [`enum_switch` allows runtime enum value transformation to constexpr context.](#enum_switch) * [`enum_switch` allows runtime enum value transformation to constexpr context.](#enum_switch)
* [`enum_for_each` calls a function with all enum constexpr value.](#enum_for_each) * [`enum_for_each` calls a function with all enum constexpr value.](#enum_for_each)
* [`enum_flags` API from enum-flags.](#enum_flags) * [`enum_flags_*` functions for flags.](#enum_flags)
* [`is_unscoped_enum` checks whether type is an Unscoped enumeration.](#is_unscoped_enum) * [`is_unscoped_enum` checks whether type is an Unscoped enumeration.](#is_unscoped_enum)
* [`is_scoped_enum` checks whether type is an Scoped enumeration.](#is_scoped_enum) * [`is_scoped_enum` checks whether type is an Scoped enumeration.](#is_scoped_enum)
* [`underlying_type` improved UB-free "SFINAE-friendly" underlying_type.](#underlying_type) * [`underlying_type` improved UB-free "SFINAE-friendly" underlying_type.](#underlying_type)
@ -34,7 +34,7 @@
* To add custom enum or type names see the [example](../example/example_custom_name.cpp). * To add custom enum or type names see the [example](../example/example_custom_name.cpp).
* To change the type of strings or ortional, use special macros: * To change the type of strings or optional, use special macros:
```cpp ```cpp
#include <my_lib/string.hpp> #include <my_lib/string.hpp>
@ -292,7 +292,7 @@ template <typename E>
constexpr bool enum_contains(string_view value) noexcept; constexpr bool enum_contains(string_view value) noexcept;
template <typename E, typename BinaryPredicate> template <typename E, typename BinaryPredicate>
constexpr optional<E> enum_contains(string_view value, BinaryPredicate p) noexcept(is_nothrow_invocable_v<BinaryPredicate>); constexpr bool enum_contains(string_view value, BinaryPredicate p) noexcept(is_nothrow_invocable_v<BinaryPredicate>);
``` ```
* Checks whether enum contains enumerator with such value. * Checks whether enum contains enumerator with such value.
@ -330,7 +330,7 @@ constexpr string_view enum_type_name() noexcept;
```cpp ```cpp
template <typename... Es> template <typename... Es>
[[nodiscard]] constexpr optional<enum_fuse_t> enum_fuse(Es... values) noexcept; constexpr optional<enum_fuse_t> enum_fuse(Es... values) noexcept;
``` ```
* You should add the required file `<magic_enum_fuse.hpp>`. * You should add the required file `<magic_enum_fuse.hpp>`.
@ -387,9 +387,10 @@ constexpr auto enum_for_each(Lambda&& lambda);
* Examples * Examples
```cpp ```cpp
magic_enum::enum_for_each<Color>([] (auto val) { underlying_type_t<Color> sum{};
constexpr Color c_color = val; enum_for_each<Color>([&sum](auto val) {
// ... constexpr underlying_type_t<Color> v = enum_integer(val());
sum += v;
}); });
``` ```
@ -418,16 +419,27 @@ template <typename E>
constexpr bool enum_flags_contains(string_view value) noexcept; constexpr bool enum_flags_contains(string_view value) noexcept;
template <typename E, typename BinaryPredicate> template <typename E, typename BinaryPredicate>
constexpr optional<E> enum_flags_contains(string_view value, BinaryPredicate p) noexcept(is_nothrow_invocable_v<BinaryPredicate>); constexpr bool enum_flags_contains(string_view value, BinaryPredicate p) noexcept(is_nothrow_invocable_v<BinaryPredicate>);
``` ```
* Examples * Examples
```cpp ```cpp
auto directions_name = magic_enum::enum_flags_name(Directions::Up | Directions::Right); enum Directions : std::uint64_t {
// directions_name -> "Directions::Up|Directions::Right" 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_name -> "Directions::Up|Directions::Right"
magic_enum::enum_flags_contains(Directions::Up | Directions::Right); // -> true
magic_enum::enum_flags_cast(3); // -> "Directions::Left|Directions::Down"
```
## `is_unscoped_enum` ## `is_unscoped_enum`
@ -584,7 +596,7 @@ constexpr E& operator^=(E& lhs, E rhs) noexcept;
## `containers::array` ## `containers::array`
```cpp ```cpp
template<typename E, typename V, typename Index = default_indexing<E>> template <typename E, typename V, typename Index = default_indexing<E>>
struct array { struct array {
constexpr reference at(E pos); constexpr reference at(E pos);
@ -637,7 +649,7 @@ struct array {
constexpr size_type max_size() const noexcept; constexpr size_type max_size() const noexcept;
constexpr void fill( const V& value ); constexpr void fill(const V& value);
constexpr void swap(array& other) noexcept(std::is_nothrow_swappable_v<V>); constexpr void swap(array& other) noexcept(std::is_nothrow_swappable_v<V>);
@ -674,7 +686,7 @@ struct array {
## `containers::bitset` ## `containers::bitset`
```cpp ```cpp
template<typename E, typename Index = default_indexing<E>> template <typename E, typename Index = default_indexing<E>>
class bitset { class bitset {
constexpr explicit bitset(detail::raw_access_t = raw_access) noexcept; constexpr explicit bitset(detail::raw_access_t = raw_access) noexcept;
@ -685,28 +697,27 @@ class bitset {
string_view sv, string_view sv,
string_view::size_type pos = 0, string_view::size_type pos = 0,
string_view::size_type n = string_view::npos, string_view::size_type n = string_view::npos,
char zero = '0', char_type zero = '0',
char one = '1'); char_type one = '1');
constexpr explicit bitset(detail::raw_access_t, constexpr explicit bitset(detail::raw_access_t,
const char* str, const char_type* str,
std::size_t n = ~std::size_t{}, std::size_t n = ~std::size_t{},
char zero = '0', char_type zero = '0',
char one = '1'); char_type one = '1');
constexpr bitset(std::initializer_list<E> starters); constexpr bitset(std::initializer_list<E> starters);
template<typename V = E> constexpr explicit bitset(E starter);
constexpr explicit bitset(std::enable_if_t<magic_enum::detail::is_flags_v<V>, E> starter);
template<typename Cmp = std::equal_to<>> template <typename Cmp = std::equal_to<>>
constexpr explicit bitset(string_view sv, constexpr explicit bitset(string_view sv,
Cmp&& cmp = {}, Cmp&& cmp = {},
char sep = '|'); char_type sep = '|');
friend constexpr bool operator==( const bitset& lhs, const bitset& rhs ) noexcept; friend constexpr bool operator==(const bitset& lhs, const bitset& rhs) noexcept;
friend constexpr bool operator!=( const bitset& lhs, const bitset& rhs ) noexcept; friend constexpr bool operator!=(const bitset& lhs, const bitset& rhs) noexcept;
constexpr bool operator[](E pos) const noexcept; constexpr bool operator[](E pos) const noexcept;
@ -750,14 +761,13 @@ class bitset {
friend constexpr bitset operator^(const bitset& lhs, const bitset& rhs) noexcept; friend constexpr bitset operator^(const bitset& lhs, const bitset& rhs) noexcept;
template<typename V = E> constexpr explicit operator E() const;
constexpr explicit operator std::enable_if_t<magic_enum::detail::is_flags_v<V>, E>() const;
string to_string(char sep = '|') const; string to_string(char_type sep = '|') const;
string to_string(detail::raw_access_t, string to_string(detail::raw_access_t,
char zero = '0', char_type zero = '0',
char one = '1') const; char_type one = '1') const;
constexpr unsigned long long to_ullong(detail::raw_access_t raw) const; constexpr unsigned long long to_ullong(detail::raw_access_t raw) const;
@ -793,18 +803,17 @@ class bitset {
## `containers::set` ## `containers::set`
```cpp ```cpp
template<typename E, typename CExprLess = std::less<E>> template <typename E, typename CExprLess = std::less<E>>
class set { class set {
constexpr set() noexcept = default; constexpr set() noexcept = default;
template<typename InputIt> template <typename InputIt>
constexpr set(InputIt first, InputIt last); constexpr set(InputIt first, InputIt last);
constexpr set(std::initializer_list<E> ilist); constexpr set(std::initializer_list<E> ilist);
template<typename V = E> constexpr explicit set(E starter);
constexpr explicit set(std::enable_if_t<magic_enum::detail::is_flags_v<V>, E> starter);
constexpr set(const set&) noexcept = default; constexpr set(const set&) noexcept = default;
@ -848,15 +857,15 @@ class set {
constexpr iterator insert(const_iterator hint, value_type&& value) noexcept; constexpr iterator insert(const_iterator hint, value_type&& value) noexcept;
template< class InputIt > template <typename InputIt>
constexpr void insert(InputIt first, InputIt last) noexcept; constexpr void insert(InputIt first, InputIt last) noexcept;
constexpr void insert(std::initializer_list<value_type> ilist) noexcept; constexpr void insert(std::initializer_list<value_type> ilist) noexcept;
template<class... Args> template <typename... Args>
constexpr std::pair<iterator,bool> emplace(Args&&... args) noexcept; constexpr std::pair<iterator, bool> emplace(Args&&... args) noexcept;
template<class... Args> template <typename... Args>
constexpr iterator emplace_hint(const_iterator, Args&&... args) noexcept; constexpr iterator emplace_hint(const_iterator, Args&&... args) noexcept;
constexpr iterator erase(const_iterator pos) noexcept; constexpr iterator erase(const_iterator pos) noexcept;
@ -865,39 +874,39 @@ class set {
constexpr size_type erase(const key_type& key) noexcept; constexpr size_type erase(const key_type& key) noexcept;
template<class K, typename KC = key_compare> template <typename K, typename KC = key_compare>
constexpr std::enable_if_t<detail::is_transparent_v<KC>, size_type> erase(K&& x) noexcept; constexpr std::enable_if_t<detail::is_transparent_v<KC>, size_type> erase(K&& x) noexcept;
void swap(set& other) noexcept; void swap(set& other) noexcept;
constexpr size_type count(const key_type& key) const noexcept; constexpr size_type count(const key_type& key) const noexcept;
template<typename K, typename KC = key_compare> template <typename K, typename KC = key_compare>
constexpr std::enable_if_t<detail::is_transparent_v<KC>, size_type> count(const K& x) const; constexpr std::enable_if_t<detail::is_transparent_v<KC>, size_type> count(const K& x) const;
constexpr const_iterator find(const key_type & key) const noexcept; constexpr const_iterator find(const key_type & key) const noexcept;
template<class K, typename KC = key_compare> template <typename K, typename KC = key_compare>
constexpr std::enable_if_t<detail::is_transparent_v<KC>, const_iterator> find(const K& x) const; constexpr std::enable_if_t<detail::is_transparent_v<KC>, const_iterator> find(const K& x) const;
constexpr bool contains(const key_type& key) const noexcept; constexpr bool contains(const key_type& key) const noexcept;
template<typename K, typename KC = key_compare> template <typename K, typename KC = key_compare>
constexpr std::enable_if_t<detail::is_transparent_v<KC>, bool> contains(const K& x) const noexcept; constexpr std::enable_if_t<detail::is_transparent_v<KC>, bool> contains(const K& x) const noexcept;
constexpr std::pair<const_iterator,const_iterator> equal_range(const key_type& key) const noexcept; constexpr std::pair<const_iterator,const_iterator> equal_range(const key_type& key) const noexcept;
template<typename K, typename KC = key_compare> template <typename K, typename KC = key_compare>
constexpr std::enable_if_t<detail::is_transparent_v<KC>, std::pair<const_iterator,const_iterator>> equal_range(const K& x) const noexcept; constexpr std::enable_if_t<detail::is_transparent_v<KC>, std::pair<const_iterator,const_iterator>> equal_range(const K& x) const noexcept;
constexpr const_iterator lower_bound(const key_type& key) const noexcept; constexpr const_iterator lower_bound(const key_type& key) const noexcept;
template<typename K, typename KC = key_compare> template <typename K, typename KC = key_compare>
constexpr std::enable_if_t<detail::is_transparent_v<KC>, const_iterator> lower_bound(const K& x) const noexcept; constexpr std::enable_if_t<detail::is_transparent_v<KC>, const_iterator> lower_bound(const K& x) const noexcept;
constexpr const_iterator upper_bound(const key_type& key) const noexcept; constexpr const_iterator upper_bound(const key_type& key) const noexcept;
template<typename K, typename KC = key_compare> template <typename K, typename KC = key_compare>
constexpr std::enable_if_t<detail::is_transparent_v<KC>, const_iterator> upper_bound(const K& x) const noexcept; constexpr std::enable_if_t<detail::is_transparent_v<KC>, const_iterator> upper_bound(const K& x) const noexcept;
constexpr key_compare key_comp() const; constexpr key_compare key_comp() const;
@ -916,7 +925,7 @@ class set {
constexpr friend bool operator>=(const set& lhs, const set& rhs) noexcept; constexpr friend bool operator>=(const set& lhs, const set& rhs) noexcept;
template<typename Pred> template <typename Pred>
size_type erase_if(Pred pred); size_type erase_if(Pred pred);
} }
``` ```