diff --git a/Include/magic_enum/magic_enum.hpp b/Include/magic_enum/magic_enum.hpp index 6d6f1e75..158207ee 100644 --- a/Include/magic_enum/magic_enum.hpp +++ b/Include/magic_enum/magic_enum.hpp @@ -5,7 +5,7 @@ // | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| // |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| // __/ | https://github.com/Neargye/magic_enum -// |___/ version 0.9.6 +// |___/ version 0.9.7 // // Licensed under the MIT License . // SPDX-License-Identifier: MIT @@ -34,7 +34,7 @@ #define MAGIC_ENUM_VERSION_MAJOR 0 #define MAGIC_ENUM_VERSION_MINOR 9 -#define MAGIC_ENUM_VERSION_PATCH 6 +#define MAGIC_ENUM_VERSION_PATCH 7 #ifndef MAGIC_ENUM_USE_STD_MODULE #include diff --git a/Include/magic_enum/magic_enum_all.hpp b/Include/magic_enum/magic_enum_all.hpp deleted file mode 100644 index 8750ee73..00000000 --- a/Include/magic_enum/magic_enum_all.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// __ __ _ ______ _____ -// | \/ | (_) | ____| / ____|_ _ -// | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_ -// | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _| -// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| -// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| -// __/ | https://github.com/Neargye/magic_enum -// |___/ version 0.9.6 -// -// Licensed under the MIT License . -// SPDX-License-Identifier: MIT -// Copyright (c) 2019 - 2024 Daniil Goncharov . -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#ifndef NEARGYE_MAGIC_ENUM_ALL_HPP -#define NEARGYE_MAGIC_ENUM_ALL_HPP - -#include "magic_enum.hpp" -#include "magic_enum_containers.hpp" -#include "magic_enum_flags.hpp" -#include "magic_enum_format.hpp" -#include "magic_enum_fuse.hpp" -#include "magic_enum_iostream.hpp" -#include "magic_enum_switch.hpp" -#include "magic_enum_utility.hpp" - -#endif // NEARGYE_MAGIC_ENUM_ALL_HPP diff --git a/Include/magic_enum/magic_enum_containers.hpp b/Include/magic_enum/magic_enum_containers.hpp deleted file mode 100644 index 984b3830..00000000 --- a/Include/magic_enum/magic_enum_containers.hpp +++ /dev/null @@ -1,1174 +0,0 @@ -// __ __ _ ______ _____ -// | \/ | (_) | ____| / ____|_ _ -// | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_ -// | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _| -// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| -// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| -// __/ | https://github.com/Neargye/magic_enum -// |___/ version 0.9.6 -// -// Licensed under the MIT License . -// SPDX-License-Identifier: MIT -// Copyright (c) 2019 - 2024 Daniil Goncharov . -// Copyright (c) 2022 - 2023 Bela Schaum . -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#ifndef NEARGYE_MAGIC_ENUM_CONTAINERS_HPP -#define NEARGYE_MAGIC_ENUM_CONTAINERS_HPP - -#include "magic_enum.hpp" - -#if !defined(MAGIC_ENUM_NO_EXCEPTION) && (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) -#ifndef MAGIC_ENUM_USE_STD_MODULE -# include -#endif -# define MAGIC_ENUM_THROW(...) throw (__VA_ARGS__) -#else -#ifndef MAGIC_ENUM_USE_STD_MODULE -# include -#endif -# define MAGIC_ENUM_THROW(...) std::abort() -#endif - -namespace magic_enum::containers { - -namespace detail { - -template -static constexpr bool is_transparent_v{}; - -template -static constexpr bool is_transparent_v>{true}; - -template , typename T1, typename T2> -constexpr bool equal(T1&& t1, T2&& t2, Eq&& eq = {}) { - auto first1 = t1.begin(); - auto last1 = t1.end(); - auto first2 = t2.begin(); - auto last2 = t2.end(); - - for (; first1 != last1; ++first1, ++first2) { - if (first2 == last2 || !eq(*first1, *first2)) { - return false; - } - } - return first2 == last2; -} - -template , typename T1, typename T2> -constexpr bool lexicographical_compare(T1&& t1, T2&& t2, Cmp&& cmp = {}) noexcept { - auto first1 = t1.begin(); - auto last1 = t1.end(); - auto first2 = t2.begin(); - auto last2 = t2.end(); - - // copied from std::lexicographical_compare - for (; (first1 != last1) && (first2 != last2); ++first1, (void)++first2) { - if (cmp(*first1, *first2)) { - return true; - } - if (cmp(*first2, *first1)) { - return false; - } - } - return (first1 == last1) && (first2 != last2); -} - -template -constexpr std::size_t popcount(T x) noexcept { - std::size_t c = 0; - while (x > 0) { - c += x & 1; - x >>= 1; - } - return c; -} - -template , typename ForwardIt, typename E> -constexpr ForwardIt lower_bound(ForwardIt first, ForwardIt last, E&& e, Cmp&& comp = {}) { - auto count = std::distance(first, last); - for (auto it = first; count > 0;) { - auto step = count / 2; - std::advance(it, step); - if (comp(*it, e)) { - first = ++it; - count -= step + 1; - } else { - count = step; - } - } - return first; -} - -template , typename BidirIt, typename E> -constexpr auto equal_range(BidirIt begin, BidirIt end, E&& e, Cmp&& comp = {}) { - const auto first = lower_bound(begin, end, e, comp); - return std::pair{first, lower_bound(std::make_reverse_iterator(end), std::make_reverse_iterator(first), e, [&comp](auto&& lhs, auto&& rhs) { return comp(rhs, lhs); }).base()}; -} - -template , typename = void> -class indexing { - [[nodiscard]] static constexpr auto get_indices() noexcept { - // reverse result index mapping - std::array()> rev_res{}; - - // std::iota - for (std::size_t i = 0; i < enum_count(); ++i) { - rev_res[i] = i; - } - - constexpr auto orig_values = enum_values(); - constexpr Cmp cmp{}; - - // ~std::sort - for (std::size_t i = 0; i < enum_count(); ++i) { - for (std::size_t j = i + 1; j < enum_count(); ++j) { - if (cmp(orig_values[rev_res[j]], orig_values[rev_res[i]])) { - auto tmp = rev_res[i]; - rev_res[i] = rev_res[j]; - rev_res[j] = tmp; - } - } - } - - std::array()> sorted_values{}; - // reverse the sorted indices - std::array()> res{}; - for (std::size_t i = 0; i < enum_count(); ++i) { - res[rev_res[i]] = i; - sorted_values[i] = orig_values[rev_res[i]]; - } - - return std::pair{sorted_values, res}; - } - - static constexpr auto indices = get_indices(); - - public: - [[nodiscard]] static constexpr const E* begin() noexcept { return indices.first.data(); } - - [[nodiscard]] static constexpr const E* end() noexcept { return indices.first.data() + indices.first.size(); } - - [[nodiscard]] static constexpr const E* it(std::size_t i) noexcept { return indices.first.data() + i; } - - [[nodiscard]] static constexpr optional at(E val) noexcept { - if (auto i = enum_index(val)) { - return indices.second[*i]; - } - return {}; - } -}; - -template -class indexing> && (std::is_same_v> || std::is_same_v>)>> { - static constexpr auto& values = enum_values(); - - public: - [[nodiscard]] static constexpr const E* begin() noexcept { return values.data(); } - - [[nodiscard]] static constexpr const E* end() noexcept { return values.data() + values.size(); } - - [[nodiscard]] static constexpr const E* it(std::size_t i) noexcept { return values.data() + i; } - - [[nodiscard]] static constexpr optional at(E val) noexcept { return enum_index(val); } -}; - -template -struct indexing { - using is_transparent = std::true_type; - - template - [[nodiscard]] static constexpr optional at(E val) noexcept { - return indexing::at(val); - } -}; - -template , typename = void> -struct name_sort_impl { - [[nodiscard]] constexpr bool operator()(E e1, E e2) const noexcept { return Cmp{}(enum_name(e1), enum_name(e2)); } -}; - -template -struct name_sort_impl { - using is_transparent = std::true_type; - - template - struct FullCmp : C {}; - - template - struct FullCmp && std::is_invocable_v>> { - [[nodiscard]] constexpr bool operator()(string_view s1, string_view s2) const noexcept { return lexicographical_compare(s1, s2); } - }; - - template - [[nodiscard]] constexpr std::enable_if_t< - // at least one of need to be an enum type - (std::is_enum_v> || std::is_enum_v>) && - // if both is enum, only accept if the same enum - (!std::is_enum_v> || !std::is_enum_v> || std::is_same_v) && - // is invocable with comparator - (std::is_invocable_r_v, std::conditional_t>, string_view, E1>, std::conditional_t>, string_view, E2>>), - bool> - operator()(E1 e1, E2 e2) const noexcept { - using D1 = std::decay_t; - using D2 = std::decay_t; - constexpr FullCmp<> cmp{}; - - if constexpr (std::is_enum_v && std::is_enum_v) { - return cmp(enum_name(e1), enum_name(e2)); - } else if constexpr (std::is_enum_v) { - return cmp(enum_name(e1), e2); - } else /* if constexpr (std::is_enum_v) */ { - return cmp(e1, enum_name(e2)); - } - } -}; - -struct raw_access_t {}; - -template -struct FilteredIterator { - Parent parent; - Iterator first; - Iterator last; - Iterator current; - Getter getter; - Predicate predicate; - - using iterator_category = std::bidirectional_iterator_tag; - using value_type = std::remove_reference_t>; - using difference_type = std::ptrdiff_t; - using pointer = value_type*; - using reference = value_type&; - - constexpr FilteredIterator() noexcept = default; - constexpr FilteredIterator(const FilteredIterator&) = default; - constexpr FilteredIterator& operator=(const FilteredIterator&) = default; - constexpr FilteredIterator(FilteredIterator&&) noexcept = default; - constexpr FilteredIterator& operator=(FilteredIterator&&) noexcept = default; - - template && std::is_convertible_v>*> - constexpr explicit FilteredIterator(const FilteredIterator& other) - : parent(other.parent), first(other.first), last(other.last), current(other.current), getter(other.getter), predicate(other.predicate) {} - - constexpr FilteredIterator(Parent p, Iterator begin, Iterator end, Iterator curr, Getter get = {}, Predicate pred = {}) - : parent(p), first(std::move(begin)), last(std::move(end)), current(std::move(curr)), getter{std::move(get)}, predicate{std::move(pred)} { - if (current == first && !predicate(parent, current)) { - ++*this; - } - } - - [[nodiscard]] constexpr reference operator*() const { return getter(parent, current); } - - [[nodiscard]] constexpr pointer operator->() const { return std::addressof(**this); } - - constexpr FilteredIterator& operator++() { - do { - ++current; - } while (current != last && !predicate(parent, current)); - return *this; - } - - [[nodiscard]] constexpr FilteredIterator operator++(int) { - FilteredIterator cp = *this; - ++*this; - return cp; - } - - constexpr FilteredIterator& operator--() { - do { - --current; - } while (current != first && !predicate(parent, current)); - return *this; - } - - [[nodiscard]] constexpr FilteredIterator operator--(int) { - FilteredIterator cp = *this; - --*this; - return cp; - } - - [[nodiscard]] friend constexpr bool operator==(const FilteredIterator& lhs, const FilteredIterator& rhs) { return lhs.current == rhs.current; } - - [[nodiscard]] friend constexpr bool operator!=(const FilteredIterator& lhs, const FilteredIterator& rhs) { return lhs.current != rhs.current; } -}; - -} // namespace detail - -template -using name_less = detail::name_sort_impl; - -template -using name_greater = detail::name_sort_impl>; - -using name_less_case_insensitive = detail::name_sort_impl>>; - -using name_greater_case_insensitive = detail::name_sort_impl>>; - -template -using default_indexing = detail::indexing; - -template > -using comparator_indexing = detail::indexing; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// ARRAY // -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template > -struct array { - static_assert(std::is_enum_v); - static_assert(std::is_trivially_constructible_v); - static_assert(enum_count() > 0 && Index::at(enum_values().front())); - - using index_type = Index; - using container_type = std::array()>; - - using value_type = typename container_type::value_type; - using size_type = typename container_type::size_type; - using difference_type = typename container_type::difference_type; - using reference = typename container_type::reference; - using const_reference = typename container_type::const_reference; - using pointer = typename container_type::pointer; - using const_pointer = typename container_type::const_pointer; - using iterator = typename container_type::iterator; - using const_iterator = typename container_type::const_iterator; - using reverse_iterator = typename container_type::reverse_iterator; - using const_reverse_iterator = typename container_type::const_reverse_iterator; - - constexpr reference at(E pos) { - if (auto index = index_type::at(pos)) { - return a[*index]; - } - MAGIC_ENUM_THROW(std::out_of_range("magic_enum::containers::array::at Unrecognized position")); - } - - constexpr const_reference at(E pos) const { - if (auto index = index_type::at(pos)) { - return a[*index]; - } - MAGIC_ENUM_THROW(std::out_of_range("magic_enum::containers::array::at: Unrecognized position")); - } - - [[nodiscard]] constexpr reference operator[](E pos) { - auto i = index_type::at(pos); - return MAGIC_ENUM_ASSERT(i), a[*i]; - } - - [[nodiscard]] constexpr const_reference operator[](E pos) const { - auto i = index_type::at(pos); - return MAGIC_ENUM_ASSERT(i), a[*i]; - } - - [[nodiscard]] constexpr reference front() noexcept { return a.front(); } - - [[nodiscard]] constexpr const_reference front() const noexcept { return a.front(); } - - [[nodiscard]] constexpr reference back() noexcept { return a.back(); } - - [[nodiscard]] constexpr const_reference back() const noexcept { return a.back(); } - - [[nodiscard]] constexpr pointer data() noexcept { return a.data(); } - - [[nodiscard]] constexpr const_pointer data() const noexcept { return a.data(); } - - [[nodiscard]] constexpr iterator begin() noexcept { return a.begin(); } - - [[nodiscard]] constexpr const_iterator begin() const noexcept { return a.begin(); } - - [[nodiscard]] constexpr const_iterator cbegin() const noexcept { return a.cbegin(); } - - [[nodiscard]] constexpr iterator end() noexcept { return a.end(); } - - [[nodiscard]] constexpr const_iterator end() const noexcept { return a.end(); } - - [[nodiscard]] constexpr const_iterator cend() const noexcept { return a.cend(); } - - [[nodiscard]] constexpr iterator rbegin() noexcept { return a.rbegin(); } - - [[nodiscard]] constexpr const_iterator rbegin() const noexcept { return a.rbegin(); } - - [[nodiscard]] constexpr const_iterator crbegin() const noexcept { return a.crbegin(); } - - [[nodiscard]] constexpr iterator rend() noexcept { return a.rend(); } - - [[nodiscard]] constexpr const_iterator rend() const noexcept { return a.rend(); } - - [[nodiscard]] constexpr const_iterator crend() const noexcept { return a.crend(); } - - [[nodiscard]] constexpr bool empty() const noexcept { return a.empty(); } - - [[nodiscard]] constexpr size_type size() const noexcept { return a.size(); } - - [[nodiscard]] constexpr size_type max_size() const noexcept { return a.max_size(); } - - constexpr void fill(const V& value) { - for (auto& v : a) { - v = value; - } - } - - constexpr void swap(array& other) noexcept(std::is_nothrow_swappable_v) { - for (std::size_t i = 0; i < a.size(); ++i) { - auto v = std::move(other.a[i]); - other.a[i] = std::move(a[i]); - a[i] = std::move(v); - } - } - - [[nodiscard]] friend constexpr bool operator==(const array& a1, const array& a2) { return detail::equal(a1, a2); } - - [[nodiscard]] friend constexpr bool operator!=(const array& a1, const array& a2) { return !detail::equal(a1, a2); } - - [[nodiscard]] friend constexpr bool operator<(const array& a1, const array& a2) { return detail::lexicographical_compare(a1, a2); } - - [[nodiscard]] friend constexpr bool operator<=(const array& a1, const array& a2) { return !detail::lexicographical_compare(a2, a1); } - - [[nodiscard]] friend constexpr bool operator>(const array& a1, const array& a2) { return detail::lexicographical_compare(a2, a1); } - - [[nodiscard]] friend constexpr bool operator>=(const array& a1, const array& a2) { return !detail::lexicographical_compare(a1, a2); } - - container_type a; -}; - -namespace detail { - -template -constexpr array> to_array_impl(T (&a)[N], std::index_sequence) { - return {{a[I]...}}; -} - -template -constexpr array> to_array_impl(T(&&a)[N], std::index_sequence) { - return {{std::move(a[I])...}}; -} - -} // namespace detail - -template -constexpr std::enable_if_t<(enum_count() == N), array>> to_array(T (&a)[N]) { - return detail::to_array_impl(a, std::make_index_sequence{}); -} - -template -constexpr std::enable_if_t<(enum_count() == N), array>> to_array(T(&&a)[N]) { - return detail::to_array_impl(std::move(a), std::make_index_sequence{}); -} - -template -constexpr std::enable_if_t<(enum_count() == sizeof...(Ts)), array>>> make_array(Ts&&... ts) { - return {{std::forward(ts)...}}; -} - -inline constexpr detail::raw_access_t raw_access{}; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// BITSET // -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template > -class bitset { - static_assert(std::is_enum_v); - static_assert(std::is_trivially_constructible_v); - static_assert(enum_count() > 0 && Index::at(enum_values().front())); - - using base_type = std::conditional_t() <= 8, std::uint_least8_t, - std::conditional_t() <= 16, std::uint_least16_t, - std::conditional_t() <= 32, std::uint_least32_t, - std::uint_least64_t>>>; - - static constexpr std::size_t bits_per_base = sizeof(base_type) * 8; - static constexpr std::size_t base_type_count = (enum_count() > 0 ? (enum_count() - 1) / bits_per_base + 1 : 0); - static constexpr std::size_t not_interested = base_type_count * bits_per_base - enum_count(); - static constexpr base_type last_value_max = (base_type{1} << (bits_per_base - not_interested)) - 1; - - template - class reference_impl { - friend class bitset; - - parent_t parent; - std::size_t num_index; - base_type bit_index; - - constexpr reference_impl(parent_t p, std::size_t i) noexcept : reference_impl(p, std::pair{i / bits_per_base, base_type{1} << (i % bits_per_base)}) {} - - constexpr reference_impl(parent_t p, std::pair i) noexcept : parent(p), num_index(std::get<0>(i)), bit_index(std::get<1>(i)) {} - - public: - constexpr reference_impl& operator=(bool v) noexcept { - if (v) { - parent->a[num_index] |= bit_index; - } else { - parent->a[num_index] &= ~bit_index; - } - return *this; - } - - constexpr reference_impl& operator=(const reference_impl& v) noexcept { - if (this == &v) { - return *this; - } - *this = static_cast(v); - return *this; - } - - [[nodiscard]] constexpr operator bool() const noexcept { return (parent->a[num_index] & bit_index) > 0; } - - [[nodiscard]] constexpr bool operator~() const noexcept { return !static_cast(*this); } - - constexpr reference_impl& flip() noexcept { - *this = ~*this; - return *this; - } - }; - - template - [[nodiscard]] constexpr T to_(detail::raw_access_t) const { - T res{}; - T flag{1}; - for (std::size_t i = 0; i < size(); ++i, flag <<= 1) { - if (const_reference{this, i}) { - if (i >= sizeof(T) * 8) { - MAGIC_ENUM_THROW(std::overflow_error("magic_enum::containers::bitset::to: Cannot represent enum in this type")); - } - res |= flag; - } - } - return res; - } - - public: - using index_type = Index; - using container_type = std::array; - using reference = reference_impl<>; - using const_reference = reference_impl; - - constexpr explicit bitset(detail::raw_access_t = raw_access) noexcept : a{{}} {} - - constexpr explicit bitset(detail::raw_access_t, unsigned long long val) : a{{}} { - unsigned long long bit{1}; - for (std::size_t i = 0; i < (sizeof(val) * 8); ++i, bit <<= 1) { - if ((val & bit) > 0) { - if (i >= enum_count()) { - MAGIC_ENUM_THROW(std::out_of_range("magic_enum::containers::bitset::constructor: Upper bit set in raw number")); - } - - reference{this, i} = true; - } - } - } - - constexpr explicit bitset(detail::raw_access_t, string_view sv, string_view::size_type pos = 0, string_view::size_type n = string_view::npos, char_type zero = static_cast('0'), char_type one = static_cast('1')) - : a{{}} { - std::size_t i = 0; - for (auto c : sv.substr(pos, n)) { - if (c == one) { - if (i >= enum_count()) { - MAGIC_ENUM_THROW(std::out_of_range("magic_enum::containers::bitset::constructor: Upper bit set in raw string")); - } - reference{this, i} = true; - } else if (c != zero) { - MAGIC_ENUM_THROW(std::invalid_argument("magic_enum::containers::bitset::constructor: Unrecognized character in raw string")); - } - ++i; - } - } - - constexpr explicit bitset(detail::raw_access_t, const char_type* str, std::size_t n = ~std::size_t{0}, char_type zero = static_cast('0'), char_type one = static_cast('1')) - : bitset(string_view{str, (std::min)(std::char_traits::length(str), n)}, 0, n, zero, one) {} - - constexpr bitset(std::initializer_list starters) : a{{}} { - if constexpr (magic_enum::detail::subtype_v == magic_enum::detail::enum_subtype::flags) { - for (auto& f : starters) { - *this |= bitset(f); - } - } else { - for (auto& f : starters) { - set(f); - } - } - } - template && magic_enum::detail::subtype_v == magic_enum::detail::enum_subtype::flags, int> = 0> - constexpr explicit bitset(V starter) : a{{}} { - auto u = enum_underlying(starter); - for (E v : enum_values()) { - if (auto ul = enum_underlying(v); (ul & u) != 0) { - u &= ~ul; - (*this)[v] = true; - } - } - if (u != 0) { - MAGIC_ENUM_THROW(std::invalid_argument("magic_enum::containers::bitset::constructor: Unrecognized enum value in flag")); - } - } - - template > - constexpr explicit bitset(string_view sv, Cmp&& cmp = {}, char_type sep = static_cast('|')) { - for (std::size_t to = 0; (to = magic_enum::detail::find(sv, sep)) != string_view::npos; sv.remove_prefix(to + 1)) { - if (auto v = enum_cast(sv.substr(0, to), cmp)) { - set(*v); - } else { - MAGIC_ENUM_THROW(std::invalid_argument("magic_enum::containers::bitset::constructor: Unrecognized enum value in string")); - } - } - if (!sv.empty()) { - if (auto v = enum_cast(sv, cmp)) { - set(*v); - } else { - MAGIC_ENUM_THROW(std::invalid_argument("magic_enum::containers::bitset::constructor: Unrecognized enum value in string")); - } - } - } - - [[nodiscard]] friend constexpr bool operator==(const bitset& lhs, const bitset& rhs) noexcept { return detail::equal(lhs.a, rhs.a); } - - [[nodiscard]] friend constexpr bool operator!=(const bitset& lhs, const bitset& rhs) noexcept { return !detail::equal(lhs.a, rhs.a); } - - [[nodiscard]] constexpr bool operator[](E pos) const { - auto i = index_type::at(pos); - return MAGIC_ENUM_ASSERT(i), static_cast(const_reference(this, *i)); - } - - [[nodiscard]] constexpr reference operator[](E pos) { - auto i = index_type::at(pos); - return MAGIC_ENUM_ASSERT(i), reference{this, *i}; - } - - constexpr bool test(E pos) const { - if (auto i = index_type::at(pos)) { - return static_cast(const_reference(this, *i)); - } - MAGIC_ENUM_THROW(std::out_of_range("magic_enum::containers::bitset::test: Unrecognized position")); - } - - [[nodiscard]] constexpr bool all() const noexcept { - if constexpr (base_type_count == 0) { - return true; - } - - for (std::size_t i = 0; i < base_type_count - (not_interested > 0); ++i) { - auto check = ~a[i]; - if (check) { - return false; - } - } - - if constexpr (not_interested > 0) { - return a[base_type_count - 1] == last_value_max; - } - } - - [[nodiscard]] constexpr bool any() const noexcept { - for (auto& v : a) { - if (v > 0) { - return true; - } - } - return false; - } - - [[nodiscard]] constexpr bool none() const noexcept { return !any(); } - - [[nodiscard]] constexpr std::size_t count() const noexcept { - std::size_t c = 0; - for (auto& v : a) { - c += detail::popcount(v); - } - return c; - } - - [[nodiscard]] constexpr std::size_t size() const noexcept { return enum_count(); } - - [[nodiscard]] constexpr std::size_t max_size() const noexcept { return enum_count(); } - - constexpr bitset& operator&=(const bitset& other) noexcept { - for (std::size_t i = 0; i < base_type_count; ++i) { - a[i] &= other.a[i]; - } - return *this; - } - - constexpr bitset& operator|=(const bitset& other) noexcept { - for (std::size_t i = 0; i < base_type_count; ++i) { - a[i] |= other.a[i]; - } - return *this; - } - - constexpr bitset& operator^=(const bitset& other) noexcept { - for (std::size_t i = 0; i < base_type_count; ++i) { - a[i] ^= other.a[i]; - } - return *this; - } - - [[nodiscard]] constexpr bitset operator~() const noexcept { - bitset res; - for (std::size_t i = 0; i < base_type_count - (not_interested > 0); ++i) { - res.a[i] = ~a[i]; - } - - if constexpr (not_interested > 0) { - res.a[base_type_count - 1] = ~a[base_type_count - 1] & last_value_max; - } - return res; - } - - constexpr bitset& set() noexcept { - for (std::size_t i = 0; i < base_type_count - (not_interested > 0); ++i) { - a[i] = ~base_type{0}; - } - - if constexpr (not_interested > 0) { - a[base_type_count - 1] = last_value_max; - } - return *this; - } - - constexpr bitset& set(E pos, bool value = true) { - if (auto i = index_type::at(pos)) { - reference{this, *i} = value; - return *this; - } - MAGIC_ENUM_THROW(std::out_of_range("magic_enum::containers::bitset::set: Unrecognized position")); - } - - constexpr bitset& reset() noexcept { return *this = bitset{}; } - - constexpr bitset& reset(E pos) { - if (auto i = index_type::at(pos)) { - reference{this, *i} = false; - return *this; - } - MAGIC_ENUM_THROW(std::out_of_range("magic_enum::containers::bitset::reset: Unrecognized position")); - } - - constexpr bitset& flip() noexcept { return *this = ~*this; } - - [[nodiscard]] friend constexpr bitset operator&(const bitset& lhs, const bitset& rhs) noexcept { - bitset cp = lhs; - cp &= rhs; - return cp; - } - - [[nodiscard]] friend constexpr bitset operator|(const bitset& lhs, const bitset& rhs) noexcept { - bitset cp = lhs; - cp |= rhs; - return cp; - } - - [[nodiscard]] friend constexpr bitset operator^(const bitset& lhs, const bitset& rhs) noexcept { - bitset cp = lhs; - cp ^= rhs; - return cp; - } - - template - [[nodiscard]] constexpr explicit operator std::enable_if_t == magic_enum::detail::enum_subtype::flags, E>() const { - E res{}; - for (const auto& e : enum_values()) { - if (test(e)) { - res |= e; - } - } - return res; - } - - [[nodiscard]] string to_string(char_type sep = static_cast('|')) const { - string name; - - for (const auto& e : enum_values()) { - if (test(e)) { - if (!name.empty()) { - name.append(1, sep); - } - auto n = enum_name(e); - name.append(n.data(), n.size()); - } - } - return name; - } - - [[nodiscard]] string to_string(detail::raw_access_t, char_type zero = static_cast('0'), char_type one = static_cast('1')) const { - string name; - name.reserve(size()); - for (std::size_t i = 0; i < size(); ++i) { - name.append(1, const_reference{this, i} ? one : zero); - } - return name; - } - - [[nodiscard]] constexpr unsigned long long to_ullong(detail::raw_access_t raw) const { return to_(raw); } - - [[nodiscard]] constexpr unsigned long long to_ulong(detail::raw_access_t raw) const { return to_(raw); } - - friend std::ostream& operator<<(std::ostream& o, const bitset& bs) { return o << bs.to_string(); } - - friend std::istream& operator>>(std::istream& i, bitset& bs) { - string s; - if (i >> s; !s.empty()) { - bs = bitset(string_view{s}); - } - return i; - } - - private: - container_type a; -}; - -template -explicit bitset(V starter) -> bitset; - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// SET // -/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -template > -class set { - using index_type = detail::indexing; - struct Getter { - constexpr const E& operator()(const set*, const E* p) const noexcept { return *p; } - }; - struct Predicate { - constexpr bool operator()(const set* h, const E* e) const noexcept { return h->a[*e]; } - }; - - public: - using container_type = bitset; - using key_type = E; - using value_type = E; - using size_type = std::size_t; - using difference_type = std::ptrdiff_t; - using key_compare = Cmp; - using value_compare = Cmp; - using reference = value_type&; - using const_reference = const value_type&; - using pointer = value_type*; - using const_pointer = const value_type*; - using iterator = detail::FilteredIterator; - using const_iterator = detail::FilteredIterator; - using reverse_iterator = std::reverse_iterator; - using const_reverse_iterator = std::reverse_iterator; - - constexpr set() noexcept = default; - - template - constexpr set(InputIt first, InputIt last) { - while (first != last) { - insert(*first++); - } - } - - constexpr set(std::initializer_list ilist) { - for (auto e : ilist) { - insert(e); - } - } - template && magic_enum::detail::subtype_v == magic_enum::detail::enum_subtype::flags, int> = 0> - constexpr explicit set(V starter) { - auto u = enum_underlying(starter); - for (E v : enum_values()) { - if ((enum_underlying(v) & u) != 0) { - insert(v); - } - } - } - - constexpr set(const set&) noexcept = default; - constexpr set(set&&) noexcept = default; - - constexpr set& operator=(const set&) noexcept = default; - constexpr set& operator=(set&&) noexcept = default; - constexpr set& operator=(std::initializer_list ilist) { - for (auto e : ilist) { - insert(e); - } - } - - constexpr const_iterator begin() const noexcept { - return const_iterator{this, index_type::begin(), index_type::end(), index_type::begin()}; - } - - constexpr const_iterator end() const noexcept { - return const_iterator{this, index_type::begin(), index_type::end(), index_type::end()}; - } - - constexpr const_iterator cbegin() const noexcept { return begin(); } - - constexpr const_iterator cend() const noexcept { return end(); } - - constexpr const_reverse_iterator rbegin() const noexcept { return {end()}; } - - constexpr const_reverse_iterator rend() const noexcept { return {begin()}; } - - constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); } - - constexpr const_reverse_iterator crend() const noexcept { return rend(); } - - [[nodiscard]] constexpr bool empty() const noexcept { return s == 0; } - - [[nodiscard]] constexpr size_type size() const noexcept { return s; } - - [[nodiscard]] constexpr size_type max_size() const noexcept { return a.max_size(); } - - constexpr void clear() noexcept { - a.reset(); - s = 0; - } - - constexpr std::pair insert(const value_type& value) noexcept { - if (auto i = index_type::at(value)) { - typename container_type::reference ref = a[value]; - bool r = !ref; - if (r) { - ref = true; - ++s; - } - - return {iterator{this, index_type::begin(), index_type::end(), index_type::it(*i)}, r}; - } - return {end(), false}; - } - - constexpr std::pair insert(value_type&& value) noexcept { return insert(value); } - - constexpr iterator insert(const_iterator, const value_type& value) noexcept { return insert(value).first; } - - constexpr iterator insert(const_iterator hint, value_type&& value) noexcept { return insert(hint, value); } - - template - constexpr void insert(InputIt first, InputIt last) noexcept { - while (first != last) { - insert(*first++); - } - } - - constexpr void insert(std::initializer_list ilist) noexcept { - for (auto v : ilist) { - insert(v); - } - } - - template - constexpr std::pair emplace(Args&&... args) noexcept { - return insert({std::forward(args)...}); - } - - template - constexpr iterator emplace_hint(const_iterator, Args&&... args) noexcept { - return emplace(std::forward(args)...).first; - } - - constexpr iterator erase(const_iterator pos) noexcept { - erase(*pos++); - return pos; - } - - constexpr iterator erase(const_iterator first, const_iterator last) noexcept { - while ((first = erase(first)) != last) { - } - return first; - } - - constexpr size_type erase(const key_type& key) noexcept { - typename container_type::reference ref = a[key]; - bool res = ref; - if (res) { - --s; - } - ref = false; - return res; - } - - template - constexpr std::enable_if_t, size_type> erase(K&& x) noexcept { - size_type c = 0; - for (auto [first, last] = detail::equal_range(index_type::begin(), index_type::end(), x, key_compare{}); first != last;) { - c += erase(*first++); - } - return c; - } - - void swap(set& other) noexcept { - set cp = *this; - *this = other; - other = cp; - } - - [[nodiscard]] constexpr size_type count(const key_type& key) const noexcept { return index_type::at(key) && a[key]; } - - template - [[nodiscard]] constexpr std::enable_if_t, size_type> count(const K& x) const { - size_type c = 0; - for (auto [first, last] = detail::equal_range(index_type::begin(), index_type::end(), x, key_compare{}); first != last; ++first) { - c += count(*first); - } - return c; - } - - [[nodiscard]] constexpr const_iterator find(const key_type& key) const noexcept { - if (auto i = index_type::at(key); i && a.test(key)) { - return const_iterator{this, index_type::begin(), index_type::end(), index_type::it(*i)}; - } - return end(); - } - - template - [[nodiscard]] constexpr std::enable_if_t, const_iterator> find(const K& x) const { - for (auto [first, last] = detail::equal_range(index_type::begin(), index_type::end(), x, key_compare{}); first != last; ++first) { - if (a.test(*first)) { - return find(*first); - } - } - return end(); - } - - [[nodiscard]] constexpr bool contains(const key_type& key) const noexcept { return count(key); } - - template - [[nodiscard]] constexpr std::enable_if_t, bool> contains(const K& x) const noexcept { - return count(x) > 0; - } - - [[nodiscard]] constexpr std::pair equal_range(const key_type& key) const noexcept { return {lower_bound(key), upper_bound(key)}; } - - template - [[nodiscard]] constexpr std::enable_if_t, std::pair> equal_range(const K& x) const noexcept { - return {lower_bound(x), upper_bound(x)}; - } - - [[nodiscard]] constexpr const_iterator lower_bound(const key_type& key) const noexcept { - if (auto i = index_type::at(key)) { - auto it = const_iterator{this, index_type::begin(), index_type::end(), index_type::it(*i)}; - return a.test(key) ? it : std::next(it); - } - return end(); - } - - template - [[nodiscard]] constexpr std::enable_if_t, const_iterator> lower_bound(const K& x) const noexcept { - auto [first, last] = detail::equal_range(index_type::begin(), index_type::end(), x, key_compare{}); - return first != last ? lower_bound(*first) : end(); - } - - [[nodiscard]] constexpr const_iterator upper_bound(const key_type& key) const noexcept { - if (auto i = index_type::at(key)) { - return std::next(const_iterator{this, index_type::begin(), index_type::end(), index_type::it(*i)}); - } - return end(); - } - - template - [[nodiscard]] constexpr std::enable_if_t, const_iterator> upper_bound(const K& x) const noexcept { - auto [first, last] = detail::equal_range(index_type::begin(), index_type::end(), x, key_compare{}); - return first != last ? upper_bound(*std::prev(last)) : end(); - } - - [[nodiscard]] constexpr key_compare key_comp() const { return {}; } - - [[nodiscard]] constexpr value_compare value_comp() const { return {}; } - - [[nodiscard]] constexpr friend bool operator==(const set& lhs, const set& rhs) noexcept { return lhs.a == rhs.a; } - - [[nodiscard]] constexpr friend bool operator!=(const set& lhs, const set& rhs) noexcept { return lhs.a != rhs.a; } - - [[nodiscard]] constexpr friend bool operator<(const set& lhs, const set& rhs) noexcept { - if (lhs.s < rhs.s) { - return true; - } - if (rhs.s < lhs.s) { - return false; - } - - for (auto it = index_type::begin(); it != index_type::end(); ++it) { - if (auto c = rhs.contains(*it); c != lhs.contains(*it)) { - return c; - } - } - return false; - } - - [[nodiscard]] constexpr friend bool operator<=(const set& lhs, const set& rhs) noexcept { return !(rhs < lhs); } - - [[nodiscard]] constexpr friend bool operator>(const set& lhs, const set& rhs) noexcept { return rhs < lhs; } - - [[nodiscard]] constexpr friend bool operator>=(const set& lhs, const set& rhs) noexcept { return !(lhs < rhs); } - - template - size_type erase_if(Pred pred) { - auto old_size = size(); - for (auto i = begin(), last = end(); i != last;) { - if (pred(*i)) { - i = erase(i); - } else { - ++i; - } - } - return old_size - size(); - } - - private: - container_type a; - std::size_t s = 0; -}; - -template -explicit set(V starter) -> set; - -template -constexpr std::enable_if_t<(std::is_integral_v && I < enum_count()), V&> get(array& a) noexcept { - return a.a[I]; -} - -template -constexpr std::enable_if_t<(std::is_integral_v && I < enum_count()), V&&> get(array&& a) noexcept { - return std::move(a.a[I]); -} - -template -constexpr std::enable_if_t<(std::is_integral_v && I < enum_count()), const V&> get(const array& a) noexcept { - return a.a[I]; -} - -template -constexpr std::enable_if_t<(std::is_integral_v && I < enum_count()), const V&&> get(const array&& a) noexcept { - return std::move(a.a[I]); -} - -template -constexpr std::enable_if_t && enum_contains(Enum), V&> get(array& a) { - return a[Enum]; -} - -template -constexpr std::enable_if_t && enum_contains(Enum), V&&> get(array&& a) { - return std::move(a[Enum]); -} - -template -constexpr std::enable_if_t && enum_contains(Enum), const V&> get(const array& a) { - return a[Enum]; -} - -template -constexpr std::enable_if_t && enum_contains(Enum), const V&&> get(const array&& a) { - return std::move(a[Enum]); -} - -} // namespace magic_enum::containers - -#endif // NEARGYE_MAGIC_ENUM_CONTAINERS_HPP diff --git a/Include/magic_enum/magic_enum_flags.hpp b/Include/magic_enum/magic_enum_flags.hpp deleted file mode 100644 index 18d03ec6..00000000 --- a/Include/magic_enum/magic_enum_flags.hpp +++ /dev/null @@ -1,222 +0,0 @@ -// __ __ _ ______ _____ -// | \/ | (_) | ____| / ____|_ _ -// | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_ -// | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _| -// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| -// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| -// __/ | https://github.com/Neargye/magic_enum -// |___/ version 0.9.6 -// -// Licensed under the MIT License . -// SPDX-License-Identifier: MIT -// Copyright (c) 2019 - 2024 Daniil Goncharov . -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#ifndef NEARGYE_MAGIC_ENUM_FLAGS_HPP -#define NEARGYE_MAGIC_ENUM_FLAGS_HPP - -#include "magic_enum.hpp" - -#if defined(__clang__) -# pragma clang diagnostic push -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // May be used uninitialized 'return {};'. -#elif defined(_MSC_VER) -# pragma warning(push) -#endif - -namespace magic_enum { - -namespace detail { - -template > -constexpr U values_ors() noexcept { - static_assert(S == enum_subtype::flags, "magic_enum::detail::values_ors requires valid subtype."); - - auto ors = U{0}; - for (std::size_t i = 0; i < count_v; ++i) { - ors |= static_cast(values_v[i]); - } - - return ors; -} - -} // namespace magic_enum::detail - -// Returns name from enum-flags value. -// If enum-flags value does not have name or value out of range, returns empty string. -template -[[nodiscard]] auto enum_flags_name(E value, char_type sep = static_cast('|')) -> detail::enable_if_t { - using D = std::decay_t; - using U = underlying_type_t; - constexpr auto S = detail::enum_subtype::flags; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - string name; - auto check_value = U{0}; - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (const auto v = static_cast(enum_value(i)); (static_cast(value) & v) != 0) { - if (const auto n = detail::names_v[i]; !n.empty()) { - check_value |= v; - if (!name.empty()) { - name.append(1, sep); - } - name.append(n.data(), n.size()); - } else { - return {}; // Value out of range. - } - } - } - - if (check_value != 0 && check_value == static_cast(value)) { - return name; - } - return {}; // Invalid value or out of range. -} - -// Obtains enum-flags value from integer value. -// Returns optional with enum-flags value. -template -[[nodiscard]] constexpr auto enum_flags_cast(underlying_type_t value) noexcept -> detail::enable_if_t>> { - using D = std::decay_t; - using U = underlying_type_t; - constexpr auto S = detail::enum_subtype::flags; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - if constexpr (detail::count_v == 0) { - static_cast(value); - return {}; // Empty enum. - } else { - if constexpr (detail::is_sparse_v) { - auto check_value = U{0}; - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (const auto v = static_cast(enum_value(i)); (value & v) != 0) { - check_value |= v; - } - } - - if (check_value != 0 && check_value == value) { - return static_cast(value); - } - } else { - constexpr auto min = detail::min_v; - constexpr auto max = detail::values_ors(); - - if (value >= min && value <= max) { - return static_cast(value); - } - } - return {}; // Invalid value or out of range. - } -} - -// Obtains enum-flags value from name. -// Returns optional with enum-flags value. -template > -[[nodiscard]] constexpr auto enum_flags_cast(string_view value, [[maybe_unused]] BinaryPredicate p = {}) noexcept(detail::is_nothrow_invocable()) -> detail::enable_if_t>, BinaryPredicate> { - using D = std::decay_t; - using U = underlying_type_t; - constexpr auto S = detail::enum_subtype::flags; - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - - if constexpr (detail::count_v == 0) { - static_cast(value); - return {}; // Empty enum. - } else { - auto result = U{0}; - while (!value.empty()) { - const auto d = detail::find(value, '|'); - const auto s = (d == string_view::npos) ? value : value.substr(0, d); - auto f = U{0}; - for (std::size_t i = 0; i < detail::count_v; ++i) { - if (detail::cmp_equal(s, detail::names_v[i], p)) { - f = static_cast(enum_value(i)); - result |= f; - break; - } - } - if (f == U{0}) { - return {}; // Invalid value or out of range. - } - value.remove_prefix((d == string_view::npos) ? value.size() : d + 1); - } - - if (result != U{0}) { - return static_cast(result); - } - return {}; // Invalid value or out of range. - } -} - -// Checks whether enum-flags contains value with such value. -template -[[nodiscard]] constexpr auto enum_flags_contains(E value) noexcept -> detail::enable_if_t { - using D = std::decay_t; - using U = underlying_type_t; - - return static_cast(enum_flags_cast(static_cast(value))); -} - -// Checks whether enum-flags contains value with such integer value. -template -[[nodiscard]] constexpr auto enum_flags_contains(underlying_type_t value) noexcept -> detail::enable_if_t { - using D = std::decay_t; - - return static_cast(enum_flags_cast(value)); -} - -// Checks whether enum-flags contains enumerator with such name. -template > -[[nodiscard]] constexpr auto enum_flags_contains(string_view value, BinaryPredicate p = {}) noexcept(detail::is_nothrow_invocable()) -> detail::enable_if_t { - using D = std::decay_t; - - return static_cast(enum_flags_cast(value, std::move(p))); -} - -// Checks whether `flags set` contains `flag`. -// Note: If `flag` equals 0, it returns false, as 0 is not a flag. -template -constexpr auto enum_flags_test(E flags, E flag) noexcept -> detail::enable_if_t { - using U = underlying_type_t; - - return static_cast(flag) && ((static_cast(flags) & static_cast(flag)) == static_cast(flag)); -} - -// Checks whether `lhs flags set` and `rhs flags set` have common flags. -// Note: If `lhs flags set` or `rhs flags set` equals 0, it returns false, as 0 is not a flag, and therfore cannot have any matching flag. -template -constexpr auto enum_flags_test_any(E lhs, E rhs) noexcept -> detail::enable_if_t { - using U = underlying_type_t; - - return (static_cast(lhs) & static_cast(rhs)) != 0; -} - -} // namespace magic_enum - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#elif defined(_MSC_VER) -# pragma warning(pop) -#endif - -#endif // NEARGYE_MAGIC_ENUM_FLAGS_HPP diff --git a/Include/magic_enum/magic_enum_format.hpp b/Include/magic_enum/magic_enum_format.hpp deleted file mode 100644 index e25f1527..00000000 --- a/Include/magic_enum/magic_enum_format.hpp +++ /dev/null @@ -1,114 +0,0 @@ -// __ __ _ ______ _____ -// | \/ | (_) | ____| / ____|_ _ -// | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_ -// | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _| -// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| -// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| -// __/ | https://github.com/Neargye/magic_enum -// |___/ version 0.9.6 -// -// Licensed under the MIT License . -// SPDX-License-Identifier: MIT -// Copyright (c) 2019 - 2024 Daniil Goncharov . -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#ifndef NEARGYE_MAGIC_ENUM_FORMAT_HPP -#define NEARGYE_MAGIC_ENUM_FORMAT_HPP - -#include "magic_enum.hpp" -#include "magic_enum_flags.hpp" - -#if !defined(MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT) -# define MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT 1 -# define MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE -#endif - -namespace magic_enum::customize { - // customize enum to enable/disable automatic std::format - template - constexpr bool enum_format_enabled() noexcept { - return MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT; - } -} // magic_enum::customize - -#if defined(__cpp_lib_format) - -#ifndef MAGIC_ENUM_USE_STD_MODULE -#include -#endif - -template -struct std::formatter> && magic_enum::customize::enum_format_enabled(), char>> : std::formatter { - template - auto format(E e, FormatContext& ctx) const { - static_assert(std::is_same_v, "formatter requires string_view::value_type type same as char."); - using D = std::decay_t; - - if constexpr (magic_enum::detail::supported::value) { - if constexpr (magic_enum::detail::subtype_v == magic_enum::detail::enum_subtype::flags) { - if (const auto name = magic_enum::enum_flags_name(e); !name.empty()) { - return formatter::format(std::string_view{name.data(), name.size()}, ctx); - } - } else { - if (const auto name = magic_enum::enum_name(e); !name.empty()) { - return formatter::format(std::string_view{name.data(), name.size()}, ctx); - } - } - } - return formatter::format(std::to_string(magic_enum::enum_integer(e)), ctx); - } -}; - -#endif - -#if defined(FMT_VERSION) - -#include - -template -struct fmt::formatter> && magic_enum::customize::enum_format_enabled(), char>> : fmt::formatter { - template - auto format(E e, FormatContext& ctx) const { - static_assert(std::is_same_v, "formatter requires string_view::value_type type same as char."); - using D = std::decay_t; - - if constexpr (magic_enum::detail::supported::value) { - if constexpr (magic_enum::detail::subtype_v == magic_enum::detail::enum_subtype::flags) { - if (const auto name = magic_enum::enum_flags_name(e); !name.empty()) { - return formatter::format(std::string_view{name.data(), name.size()}, ctx); - } - } else { - if (const auto name = magic_enum::enum_name(e); !name.empty()) { - return formatter::format(std::string_view{name.data(), name.size()}, ctx); - } - } - } - return formatter::format(std::to_string(magic_enum::enum_integer(e)), ctx); - } -}; - -#endif - -#if defined(MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE) -# undef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT -# undef MAGIC_ENUM_DEFAULT_ENABLE_ENUM_FORMAT_AUTO_DEFINE -#endif - -#endif // NEARGYE_MAGIC_ENUM_FORMAT_HPP diff --git a/Include/magic_enum/magic_enum_fuse.hpp b/Include/magic_enum/magic_enum_fuse.hpp deleted file mode 100644 index 73c876e1..00000000 --- a/Include/magic_enum/magic_enum_fuse.hpp +++ /dev/null @@ -1,89 +0,0 @@ -// __ __ _ ______ _____ -// | \/ | (_) | ____| / ____|_ _ -// | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_ -// | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _| -// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| -// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| -// __/ | https://github.com/Neargye/magic_enum -// |___/ version 0.9.6 -// -// Licensed under the MIT License . -// SPDX-License-Identifier: MIT -// Copyright (c) 2019 - 2024 Daniil Goncharov . -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#ifndef NEARGYE_MAGIC_ENUM_FUSE_HPP -#define NEARGYE_MAGIC_ENUM_FUSE_HPP - -#include "magic_enum.hpp" - -namespace magic_enum { - -namespace detail { - -template -constexpr optional fuse_one_enum(optional hash, E value) noexcept { - if (hash) { - if (const auto index = enum_index(value)) { - return (*hash << log2(enum_count() + 1)) | *index; - } - } - return {}; -} - -template -constexpr optional fuse_enum(E value) noexcept { - return fuse_one_enum(0, value); -} - -template -constexpr optional fuse_enum(E head, Es... tail) noexcept { - return fuse_one_enum(fuse_enum(tail...), head); -} - -template -constexpr auto typesafe_fuse_enum(Es... values) noexcept { - enum class enum_fuse_t : std::uintmax_t; - const auto fuse = fuse_enum(values...); - if (fuse) { - return optional{static_cast(*fuse)}; - } - return optional{}; -} - -} // namespace magic_enum::detail - -// Returns a bijective mix of several enum values. This can be used to emulate 2D switch/case statements. -template -[[nodiscard]] constexpr auto enum_fuse(Es... values) noexcept { - static_assert((std::is_enum_v> && ...), "magic_enum::enum_fuse requires enum type."); - static_assert(sizeof...(Es) >= 2, "magic_enum::enum_fuse requires at least 2 values."); - static_assert((detail::log2(enum_count>() + 1) + ...) <= (sizeof(std::uintmax_t) * 8), "magic_enum::enum_fuse does not work for large enums"); -#if defined(MAGIC_ENUM_NO_TYPESAFE_ENUM_FUSE) - const auto fuse = detail::fuse_enum...>(values...); -#else - const auto fuse = detail::typesafe_fuse_enum...>(values...); -#endif - return MAGIC_ENUM_ASSERT(fuse), fuse; -} - -} // namespace magic_enum - -#endif // NEARGYE_MAGIC_ENUM_FUSE_HPP diff --git a/Include/magic_enum/magic_enum_iostream.hpp b/Include/magic_enum/magic_enum_iostream.hpp deleted file mode 100644 index 23d92bfb..00000000 --- a/Include/magic_enum/magic_enum_iostream.hpp +++ /dev/null @@ -1,117 +0,0 @@ -// __ __ _ ______ _____ -// | \/ | (_) | ____| / ____|_ _ -// | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_ -// | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _| -// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| -// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| -// __/ | https://github.com/Neargye/magic_enum -// |___/ version 0.9.6 -// -// Licensed under the MIT License . -// SPDX-License-Identifier: MIT -// Copyright (c) 2019 - 2024 Daniil Goncharov . -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#ifndef NEARGYE_MAGIC_ENUM_IOSTREAM_HPP -#define NEARGYE_MAGIC_ENUM_IOSTREAM_HPP - -#include "magic_enum.hpp" -#include "magic_enum_flags.hpp" - -#ifndef MAGIC_ENUM_USE_STD_MODULE -#include -#endif - -namespace magic_enum { - -namespace ostream_operators { - -template = 0> -std::basic_ostream& operator<<(std::basic_ostream& os, E value) { - using D = std::decay_t; - using U = underlying_type_t; - - if constexpr (detail::supported::value) { - if constexpr (detail::subtype_v == detail::enum_subtype::flags) { - if (const auto name = enum_flags_name(value); !name.empty()) { - for (const auto c : name) { - os.put(c); - } - return os; - } - } else { - if (const auto name = enum_name(value); !name.empty()) { - for (const auto c : name) { - os.put(c); - } - return os; - } - } - } - return (os << static_cast(value)); -} - -template = 0> -std::basic_ostream& operator<<(std::basic_ostream& os, optional value) { - return value ? (os << *value) : os; -} - -} // namespace magic_enum::ostream_operators - -namespace istream_operators { - -template = 0> -std::basic_istream& operator>>(std::basic_istream& is, E& value) { - using D = std::decay_t; - - std::basic_string s; - is >> s; - if constexpr (detail::supported::value) { - if constexpr (detail::subtype_v == detail::enum_subtype::flags) { - if (const auto v = enum_flags_cast(s)) { - value = *v; - } else { - is.setstate(std::basic_ios::failbit); - } - } else { - if (const auto v = enum_cast(s)) { - value = *v; - } else { - is.setstate(std::basic_ios::failbit); - } - } - } else { - is.setstate(std::basic_ios::failbit); - } - return is; -} - -} // namespace magic_enum::istream_operators - -namespace iostream_operators { - -using magic_enum::ostream_operators::operator<<; -using magic_enum::istream_operators::operator>>; - -} // namespace magic_enum::iostream_operators - -} // namespace magic_enum - -#endif // NEARGYE_MAGIC_ENUM_IOSTREAM_HPP diff --git a/Include/magic_enum/magic_enum_switch.hpp b/Include/magic_enum/magic_enum_switch.hpp deleted file mode 100644 index beceefbc..00000000 --- a/Include/magic_enum/magic_enum_switch.hpp +++ /dev/null @@ -1,195 +0,0 @@ -// __ __ _ ______ _____ -// | \/ | (_) | ____| / ____|_ _ -// | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_ -// | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _| -// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| -// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| -// __/ | https://github.com/Neargye/magic_enum -// |___/ version 0.9.6 -// -// Licensed under the MIT License . -// SPDX-License-Identifier: MIT -// Copyright (c) 2019 - 2024 Daniil Goncharov . -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#ifndef NEARGYE_MAGIC_ENUM_SWITCH_HPP -#define NEARGYE_MAGIC_ENUM_SWITCH_HPP - -#include "magic_enum.hpp" - -namespace magic_enum { - -namespace detail { - -struct default_result_type {}; - -template -struct identity { - using type = T; -}; - -struct nonesuch {}; - -template > -struct invoke_result : identity {}; - -template -struct invoke_result : std::invoke_result {}; - -template -using invoke_result_t = typename invoke_result::type; - -template -constexpr auto common_invocable(std::index_sequence) noexcept { - static_assert(std::is_enum_v, "magic_enum::detail::invocable_index requires enum type."); - - if constexpr (count_v == 0) { - return identity{}; - } else { - return std::common_type[I]>>...>{}; - } -} - -template -constexpr auto result_type() noexcept { - static_assert(std::is_enum_v, "magic_enum::detail::result_type requires enum type."); - - constexpr auto seq = std::make_index_sequence>{}; - using R = typename decltype(common_invocable(seq))::type; - if constexpr (std::is_same_v) { - if constexpr (std::is_same_v) { - return identity{}; - } else { - return identity{}; - } - } else { - if constexpr (std::is_convertible_v) { - return identity{}; - } else if constexpr (std::is_convertible_v) { - return identity{}; - } else { - return identity{}; - } - } -} - -template , typename R = typename decltype(result_type())::type> -using result_t = std::enable_if_t && !std::is_same_v, R>; - -#if !defined(MAGIC_ENUM_ENABLE_HASH) && !defined(MAGIC_ENUM_ENABLE_HASH_SWITCH) - -template -inline constexpr auto default_result_type_lambda = []() noexcept(std::is_nothrow_default_constructible_v) { return T{}; }; - -template <> -inline constexpr auto default_result_type_lambda = []() noexcept {}; - -template -constexpr decltype(auto) constexpr_switch_impl(F&& f, E value, Def&& def) { - if constexpr(I < End) { - constexpr auto v = enum_constant()>{}; - if (value == v) { - if constexpr (std::is_invocable_r_v) { - return static_cast(std::forward(f)(v)); - } else { - return def(); - } - } else { - return constexpr_switch_impl(std::forward(f), value, std::forward(def)); - } - } else { - return def(); - } -} - -template -constexpr decltype(auto) constexpr_switch(F&& f, E value, Def&& def) { - static_assert(is_enum_v, "magic_enum::detail::constexpr_switch requires enum type."); - - if constexpr (count_v == 0) { - return def(); - } else { - return constexpr_switch_impl<0, count_v, R, E, S>(std::forward(f), value, std::forward(def)); - } -} -#endif - -} // namespace magic_enum::detail - -template , typename F, typename R = detail::result_t> -constexpr decltype(auto) enum_switch(F&& f, E value) { - using D = std::decay_t; - static_assert(std::is_enum_v, "magic_enum::enum_switch requires enum type."); - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - -#if defined(MAGIC_ENUM_ENABLE_HASH) || defined(MAGIC_ENUM_ENABLE_HASH_SWITCH) - return detail::constexpr_switch<&detail::values_v, detail::case_call_t::value>( - std::forward(f), - value, - detail::default_result_type_lambda); -#else - return detail::constexpr_switch( - std::forward(f), - value, - detail::default_result_type_lambda); -#endif -} - -template > -constexpr decltype(auto) enum_switch(F&& f, E value) { - return enum_switch(std::forward(f), value); -} - -template , typename F, typename R = detail::result_t> -constexpr decltype(auto) enum_switch(F&& f, E value, Result&& result) { - using D = std::decay_t; - static_assert(std::is_enum_v, "magic_enum::enum_switch requires enum type."); - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - -#if defined(MAGIC_ENUM_ENABLE_HASH) || defined(MAGIC_ENUM_ENABLE_HASH_SWITCH) - return detail::constexpr_switch<&detail::values_v, detail::case_call_t::value>( - std::forward(f), - value, - [&result]() -> R { return std::forward(result); }); -#else - return detail::constexpr_switch( - std::forward(f), - value, - [&result]() -> R { return std::forward(result); }); -#endif -} - -template > -constexpr decltype(auto) enum_switch(F&& f, E value, Result&& result) { - return enum_switch(std::forward(f), value, std::forward(result)); -} - -} // namespace magic_enum - -template <> -struct std::common_type : magic_enum::detail::identity {}; - -template -struct std::common_type : magic_enum::detail::identity {}; - -template -struct std::common_type : magic_enum::detail::identity {}; - -#endif // NEARGYE_MAGIC_ENUM_SWITCH_HPP diff --git a/Include/magic_enum/magic_enum_utility.hpp b/Include/magic_enum/magic_enum_utility.hpp deleted file mode 100644 index 2504ef4a..00000000 --- a/Include/magic_enum/magic_enum_utility.hpp +++ /dev/null @@ -1,138 +0,0 @@ -// __ __ _ ______ _____ -// | \/ | (_) | ____| / ____|_ _ -// | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_ -// | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _| -// | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_| -// |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____| -// __/ | https://github.com/Neargye/magic_enum -// |___/ version 0.9.6 -// -// Licensed under the MIT License . -// SPDX-License-Identifier: MIT -// Copyright (c) 2019 - 2024 Daniil Goncharov . -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -#ifndef NEARGYE_MAGIC_ENUM_UTILITY_HPP -#define NEARGYE_MAGIC_ENUM_UTILITY_HPP - -#include "magic_enum.hpp" - -namespace magic_enum { - -namespace detail { - -template -constexpr auto for_each(F&& f, std::index_sequence) { - constexpr bool has_void_return = (std::is_void_v[I]>>> || ...); - constexpr bool all_same_return = (std::is_same_v[0]>>, std::invoke_result_t[I]>>> && ...); - - if constexpr (has_void_return) { - (f(enum_constant[I]>{}), ...); - } else if constexpr (all_same_return) { - return std::array{f(enum_constant[I]>{})...}; - } else { - return std::tuple{f(enum_constant[I]>{})...}; - } -} - -template -constexpr bool all_invocable(std::index_sequence) { - if constexpr (count_v == 0) { - return false; - } else { - return (std::is_invocable_v[I]>> && ...); - } -} - -} // namespace magic_enum::detail - -template , typename F, detail::enable_if_t = 0> -constexpr auto enum_for_each(F&& f) { - using D = std::decay_t; - static_assert(std::is_enum_v, "magic_enum::enum_for_each requires enum type."); - static_assert(detail::is_reflected_v, "magic_enum requires enum implementation and valid max and min."); - constexpr auto sep = std::make_index_sequence>{}; - - if constexpr (detail::all_invocable(sep)) { - return detail::for_each(std::forward(f), sep); - } else { - static_assert(detail::always_false_v, "magic_enum::enum_for_each requires invocable of all enum value."); - } -} - -template > -[[nodiscard]] constexpr auto enum_next_value(E value, std::ptrdiff_t n = 1) noexcept -> detail::enable_if_t>> { - using D = std::decay_t; - constexpr std::ptrdiff_t count = detail::count_v; - - if (const auto i = enum_index(value)) { - const std::ptrdiff_t index = (static_cast(*i) + n); - if (index >= 0 && index < count) { - return enum_value(static_cast(index)); - } - } - return {}; -} - -template > -[[nodiscard]] constexpr auto enum_next_value_circular(E value, std::ptrdiff_t n = 1) noexcept -> detail::enable_if_t> { - using D = std::decay_t; - constexpr std::ptrdiff_t count = detail::count_v; - - if (const auto i = enum_index(value)) { - const std::ptrdiff_t index = ((((static_cast(*i) + n) % count) + count) % count); - if (index >= 0 && index < count) { - return enum_value(static_cast(index)); - } - } - return MAGIC_ENUM_ASSERT(false), value; -} - -template > -[[nodiscard]] constexpr auto enum_prev_value(E value, std::ptrdiff_t n = 1) noexcept -> detail::enable_if_t>> { - using D = std::decay_t; - constexpr std::ptrdiff_t count = detail::count_v; - - if (const auto i = enum_index(value)) { - const std::ptrdiff_t index = (static_cast(*i) - n); - if (index >= 0 && index < count) { - return enum_value(static_cast(index)); - } - } - return {}; -} - -template > -[[nodiscard]] constexpr auto enum_prev_value_circular(E value, std::ptrdiff_t n = 1) noexcept -> detail::enable_if_t> { - using D = std::decay_t; - constexpr std::ptrdiff_t count = detail::count_v; - - if (const auto i = enum_index(value)) { - const std::ptrdiff_t index = ((((static_cast(*i) - n) % count) + count) % count); - if (index >= 0 && index < count) { - return enum_value(static_cast(index)); - } - } - return MAGIC_ENUM_ASSERT(false), value; -} - -} // namespace magic_enum - -#endif // NEARGYE_MAGIC_ENUM_UTILITY_HPP diff --git a/README.md b/README.md index 58698e88..0a8d5c3b 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,12 @@ [![license](https://img.shields.io/github/license/TLCFEM/suanPan.svg?color=44cc11)](https://www.gnu.org/licenses/gpl-3.0) [![documentation](https://readthedocs.org/projects/suanpan-manual/badge/?version=latest)](https://suanpan-manual.readthedocs.io/?badge=latest) [![release](https://img.shields.io/github/release-pre/TLCFEM/suanPan.svg?color=44cc11)](https://github.com/TLCFEM/suanPan/releases) -[![docker](https://img.shields.io/docker/image-size/tlcfem/suanpan/latest?label=docker&color=44cc11)](https://hub.docker.com/r/tlcfem/suanpan/tags) [![suanpan](https://snapcraft.io//suanpan/badge.svg)](https://snapcraft.io/suanpan) [![choco](https://img.shields.io/chocolatey/v/suanpan?color=44cc11)](https://chocolatey.org/packages/suanpan) [![choco](https://img.shields.io/chocolatey/dt/suanpan?color=44cc11&label=choco%20install)](https://chocolatey.org/packages/suanpan) [![flathub](https://img.shields.io/flathub/downloads/io.github.tlcfem.suanPan?label=flathub%20install)](https://flathub.org/apps/io.github.tlcfem.suanPan) [![github](https://img.shields.io/github/downloads/TLCFEM/suanPan/total.svg?color=44cc11&label=github%20download)](https://github.com/TLCFEM/suanPan/releases) +[![docker](https://img.shields.io/docker/pulls/tlcfem/suanpan?color=44cc11)](https://hub.docker.com/r/tlcfem/suanpan/tags) [![dev](https://github.com/TLCFEM/suanPan/actions/workflows/dev-all.yml/badge.svg?branch=dev)](https://github.com/TLCFEM/suanPan/actions/workflows/dev-all.yml) [![codecov](https://codecov.io/gh/TLCFEM/suanPan/branch/dev/graph/badge.svg?token=65BF9DF697)](https://codecov.io/gh/TLCFEM/suanPan) [![codacy](https://app.codacy.com/project/badge/Grade/1ea08c43edf342a8b00b21e585e63503)](https://app.codacy.com/gh/TLCFEM/suanPan/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) @@ -302,6 +302,7 @@ Additional libraries used in **suanPan** are listed as follows. - [**fmt**](https://github.com/fmtlib/fmt) version 10.2.1 - [**whereami**](https://github.com/gpakosz/whereami) - [**exprtk**](https://github.com/ArashPartow/exprtk) +- [**magic_enum**](https://github.com/Neargye/magic_enum) version 0.9.7 - **thread_pool** abridged version of [`thread-pool`](https://github.com/bshoshany/thread-pool) Those libraries may depend on other libraries such as [zlib](https://zlib.net/) diff --git a/Recorder/OutputType.cpp b/Recorder/OutputType.cpp index bd4bd852..45b38fa6 100644 --- a/Recorder/OutputType.cpp +++ b/Recorder/OutputType.cpp @@ -16,10 +16,6 @@ ******************************************************************************/ #include "OutputType.h" -#include - - -OutputType to_token(const std::string& L) { return to_token(L.c_str()); } int to_index(const OutputType config) { if(config == OutputType::S11) return 0; diff --git a/Recorder/OutputType.h b/Recorder/OutputType.h index 1dc0851c..c43460a7 100644 --- a/Recorder/OutputType.h +++ b/Recorder/OutputType.h @@ -18,7 +18,6 @@ #ifndef OUTPUTTYPE_H #define OUTPUTTYPE_H -#include #include enum class OutputType { @@ -259,7 +258,7 @@ enum class OutputType { // amplitude AMP, - NL = 256 + NL }; template<> struct magic_enum::customize::enum_range { @@ -267,9 +266,9 @@ template<> struct magic_enum::customize::enum_range { static constexpr int max = 512; }; -constexpr std::string_view to_name(OutputType L) { return magic_enum::enum_name(L);} -constexpr OutputType to_token(const char* L) { return magic_enum::enum_cast(L).value_or(OutputType::NL);} -OutputType to_token(const std::string&); +constexpr std::string_view to_name(const OutputType L) { return magic_enum::enum_name(L); } + +constexpr OutputType to_token(const std::string_view L) { return magic_enum::enum_cast(L).value_or(OutputType::NL); } const char* to_category(OutputType); int to_index(OutputType);