The Battle for Wesnoth  1.17.4+dev
enum_base.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2008 - 2022
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 <optional>
18 #include <string>
19 #include <tuple>
20 
21 namespace string_enums
22 {
23 /**
24  * The base template for associating string values with enum values.
25  * Implementing classes should not set custom int values for their enum.
26  * The number of enum values must match the number of elements in the @a values array.
27  * The values the @a values array must be unique.
28  */
29 template<typename T>
30 struct enum_base : public T
31 {
32  // check that all implementations of this are scoped enums
33  static_assert(std::is_enum<typename T::type>::value && !std::is_convertible<typename T::type, int>::value, "Enum is not a scoped enum");
34 
35  /**
36  * Uses the int value of the provided enum to get the associated index of the @a values array in the implementing class.
37  *
38  * @param key The enum value to get the equivalent string for.
39  * @return The string value associated to the enum value.
40  */
41  static std::string get_string(typename T::type key)
42  {
43  return std::string{T::values[static_cast<int>(key)]};
44  }
45 
46  /**
47  * Convert a string into its enum equivalent.
48  *
49  * @param value The string value to convert.
50  * @return The equivalent enum or std::nullopt.
51  */
52  static std::optional<typename T::type> get_enum(const std::string value)
53  {
54  for(unsigned int i = 0; i < T::values.size(); i++) {
55  if(value == T::values[i]) {
56  return static_cast<typename T::type>(i);
57  }
58  }
59  return std::nullopt;
60  }
61 
62  /**
63  * Convert an int into its enum equivalent.
64  *
65  * @param value The string value to convert.
66  * @return The equivalent enum or std::nullopt.
67  */
68  static std::optional<typename T::type> get_enum(unsigned long value)
69  {
70  if(value < T::values.size()) {
71  return static_cast<typename T::type>(value);
72  }
73  return std::nullopt;
74  }
75 
76  /**
77  * @return The size of the implementing class's @a values array.
78  */
79  static constexpr std::size_t size()
80  {
81  return T::values.size();
82  }
83 };
84 
85 #define ENUM_AND_ARRAY(...) \
86  enum class type { __VA_ARGS__ }; \
87  \
88  /** Provide a alias template for an array of matching size. */ \
89  template<typename T> \
90  using sized_array = std::array<T, std::tuple_size<decltype(std::make_tuple(__VA_ARGS__))>::value>; \
91  \
92  static constexpr sized_array<const char*> values{__VA_ARGS__};
93 
94 } // namespace string_enums
static std::optional< typename T::type > get_enum(unsigned long value)
Convert an int into its enum equivalent.
Definition: enum_base.hpp:68
static constexpr std::size_t size()
Definition: enum_base.hpp:79
The base template for associating string values with enum values.
Definition: enum_base.hpp:30
std::size_t i
Definition: function.cpp:967
static std::string get_string(typename T::type key)
Uses the int value of the provided enum to get the associated index of the values array in the implem...
Definition: enum_base.hpp:41
static std::optional< typename T::type > get_enum(const std::string value)
Convert a string into its enum equivalent.
Definition: enum_base.hpp:52