The Battle for Wesnoth  1.19.0-dev
enum_base.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2024
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #include <array>
18 #include <optional>
19 #include <string>
20 #include <string_view>
21 #include <tuple>
22 
23 namespace string_enums
24 {
25 /**
26  * The base template for associating string values with enum values.
27  * Implementing classes should not set custom int values for their enum.
28  * The number of enum values must match the number of elements in the @a values array.
29  * The values the @a values array must be unique.
30  */
31 template<typename Definition>
32 struct enum_base : public Definition
33 {
34  using enum_type = typename Definition::type;
35 
36  // check that all implementations of this are scoped enums
37  // TODO: C++23 std::is_scoped_enum
38  static_assert(std::is_enum_v<enum_type> && !std::is_convertible_v<enum_type, int>, "Enum is not a scoped enum");
39 
40  /**
41  * Converts a enum to its string equivalent.
42  *
43  * @param key The enum value to get the equivalent string for.
44  * @return The string value associated with the enum value.
45  */
46  static std::string get_string(enum_type key)
47  {
48  return std::string{Definition::values[static_cast<int>(key)]};
49  }
50 
51  /**
52  * Converts a string into its enum equivalent.
53  *
54  * @param value The string value to convert.
55  * @return The equivalent enum or std::nullopt.
56  */
57  static constexpr std::optional<enum_type> get_enum(const std::string_view value)
58  {
59  for(unsigned int i = 0; i < size(); i++) {
60  if(value == Definition::values[i]) {
61  return static_cast<enum_type>(i);
62  }
63  }
64  return std::nullopt;
65  }
66 
67  /**
68  * Converts an int into its enum equivalent.
69  *
70  * @param value The string value to convert.
71  * @return The equivalent enum or std::nullopt.
72  */
73  static constexpr std::optional<enum_type> get_enum(unsigned long value)
74  {
75  if(value < size()) {
76  return static_cast<enum_type>(value);
77  } else {
78  return std::nullopt;
79  }
80  }
81 
82  /**
83  * @return The size of the implementing class's @a values array.
84  */
85  static constexpr std::size_t size()
86  {
87  return Definition::values.size();
88  }
89 
90  /** Provide a alias template for an array of matching size. */
91  template<typename T>
92  using sized_array = std::array<T, size()>;
93 };
94 
95 #ifndef __MINGW64__
96 #define ENUM_AND_ARRAY(...) \
97  enum class type { __VA_ARGS__ }; \
98  static constexpr std::array values{__VA_ARGS__};
99 #else
100 #define ENUM_AND_ARRAY(...) \
101  enum class type { __VA_ARGS__ }; \
102  static constexpr std::array<std::string_view, std::tuple_size_v<decltype(std::make_tuple(__VA_ARGS__))>> \
103  values{__VA_ARGS__};
104 #endif
105 
106 } // namespace string_enums
std::size_t i
Definition: function.cpp:968
The base template for associating string values with enum values.
Definition: enum_base.hpp:33
static constexpr std::size_t size()
Definition: enum_base.hpp:85
static std::string get_string(enum_type key)
Converts a enum to its string equivalent.
Definition: enum_base.hpp:46
static constexpr std::optional< enum_type > get_enum(const std::string_view value)
Converts a string into its enum equivalent.
Definition: enum_base.hpp:57
static constexpr std::optional< enum_type > get_enum(unsigned long value)
Converts an int into its enum equivalent.
Definition: enum_base.hpp:73
typename Definition::type enum_type
Definition: enum_base.hpp:34
std::array< T, size()> sized_array
Provide a alias template for an array of matching size.
Definition: enum_base.hpp:92