magic_enum_fuse.hpp
Go to the documentation of this file.
1 // __ __ _ ______ _____
2 // | \/ | (_) | ____| / ____|_ _
3 // | \ / | __ _ __ _ _ ___ | |__ _ __ _ _ _ __ ___ | | _| |_ _| |_
4 // | |\/| |/ _` |/ _` | |/ __| | __| | '_ \| | | | '_ ` _ \ | | |_ _|_ _|
5 // | | | | (_| | (_| | | (__ | |____| | | | |_| | | | | | | | |____|_| |_|
6 // |_| |_|\__,_|\__, |_|\___| |______|_| |_|\__,_|_| |_| |_| \_____|
7 // __/ | https://github.com/Neargye/magic_enum
8 // |___/ version 0.9.7
9 //
10 // Licensed under the MIT License <http://opensource.org/licenses/MIT>.
11 // SPDX-License-Identifier: MIT
12 // Copyright (c) 2019 - 2024 Daniil Goncharov <neargye@gmail.com>.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to deal
16 // in the Software without restriction, including without limitation the rights
17 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 // copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included in all
22 // copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 
32 #ifndef NEARGYE_MAGIC_ENUM_FUSE_HPP
33 #define NEARGYE_MAGIC_ENUM_FUSE_HPP
34 
35 #include "magic_enum.hpp"
36 
37 namespace magic_enum {
38 
39 namespace detail {
40 
41 template <typename E>
42 constexpr optional<std::uintmax_t> fuse_one_enum(optional<std::uintmax_t> hash, E value) noexcept {
43  if (hash) {
44  if (const auto index = enum_index(value)) {
45  return (*hash << log2((enum_count<E>() << 1) - 1)) | *index;
46  }
47  }
48  return {};
49 }
50 
51 template <typename E>
52 constexpr optional<std::uintmax_t> fuse_enum(E value) noexcept {
53  return fuse_one_enum(0, value);
54 }
55 
56 template <typename E, typename... Es>
57 constexpr optional<std::uintmax_t> fuse_enum(E head, Es... tail) noexcept {
58  return fuse_one_enum(fuse_enum(tail...), head);
59 }
60 
61 template <typename... Es>
62 constexpr auto typesafe_fuse_enum(Es... values) noexcept {
63  enum class enum_fuse_t : std::uintmax_t;
64  const auto fuse = fuse_enum(values...);
65  if (fuse) {
66  return optional<enum_fuse_t>{static_cast<enum_fuse_t>(*fuse)};
67  }
68  return optional<enum_fuse_t>{};
69 }
70 
71 } // namespace magic_enum::detail
72 
73 // Returns a bijective mix of several enum values. This can be used to emulate 2D switch/case statements.
74 template <typename... Es>
75 [[nodiscard]] constexpr auto enum_fuse(Es... values) noexcept {
76  static_assert((std::is_enum_v<std::decay_t<Es>> && ...), "magic_enum::enum_fuse requires enum type.");
77  static_assert(sizeof...(Es) >= 2, "magic_enum::enum_fuse requires at least 2 values.");
78  static_assert((detail::log2(enum_count<std::decay_t<Es>>() + 1) + ...) <= (sizeof(std::uintmax_t) * 8), "magic_enum::enum_fuse does not work for large enums");
79 #if defined(MAGIC_ENUM_NO_TYPESAFE_ENUM_FUSE)
80  const auto fuse = detail::fuse_enum<std::decay_t<Es>...>(values...);
81 #else
82  const auto fuse = detail::typesafe_fuse_enum<std::decay_t<Es>...>(values...);
83 #endif
84  return MAGIC_ENUM_ASSERT(fuse), fuse;
85 }
86 
87 } // namespace magic_enum
88 
89 #endif // NEARGYE_MAGIC_ENUM_FUSE_HPP
magic_enum.hpp
magic_enum::detail::is_enum_v
constexpr bool is_enum_v
Definition: magic_enum.hpp:418
magic_enum::detail::value
constexpr E value(std::size_t i) noexcept
Definition: magic_enum.hpp:679
magic_enum::enum_count
constexpr auto enum_count() noexcept -> detail::enable_if_t< E, std::size_t >
Definition: magic_enum.hpp:1184
magic_enum::enum_fuse
constexpr auto enum_fuse(Es... values) noexcept
Definition: magic_enum_fuse.hpp:75
magic_enum::detail::log2
constexpr I log2(I value) noexcept
Definition: magic_enum.hpp:395
magic_enum::detail::typesafe_fuse_enum
constexpr auto typesafe_fuse_enum(Es... values) noexcept
Definition: magic_enum_fuse.hpp:62
magic_enum::detail::values
constexpr auto values() noexcept
Definition: magic_enum.hpp:757
magic_enum::enum_index
constexpr auto enum_index(E value) noexcept -> detail::enable_if_t< E, optional< std::size_t >>
Definition: magic_enum.hpp:1238
MAGIC_ENUM_ASSERT
#define MAGIC_ENUM_ASSERT(...)
Definition: magic_enum.hpp:69
magic_enum::detail::fuse_one_enum
constexpr optional< std::uintmax_t > fuse_one_enum(optional< std::uintmax_t > hash, E value) noexcept
Definition: magic_enum_fuse.hpp:42
magic_enum::detail::fuse_enum
constexpr optional< std::uintmax_t > fuse_enum(E value) noexcept
Definition: magic_enum_fuse.hpp:52
magic_enum
Definition: magic_enum.hpp:126


magic_enum
Author(s):
autogenerated on Fri Feb 21 2025 03:20:19