The Battle for Wesnoth 1.21.0-dev
 
Loading...
Searching...
No Matches
enum_base.hpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2008 - 2025
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>
19#include <string>
20#include <string_view>
21#include <tuple>
22
23namespace 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 */
31template<typename Definition>
32struct 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 utils::nullopt.
56 */
57 static constexpr utils::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 utils::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 utils::nullopt.
72 */
73 static constexpr utils::optional<enum_type> get_enum(unsigned long value)
74 {
75 if(value < size()) {
76 return static_cast<enum_type>(value);
77 } else {
78 return utils::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::unique_ptr< MIX_Audio, decltype(&MIX_DestroyAudio)> value
Definition sound.cpp:139
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 utils::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
static constexpr utils::optional< enum_type > get_enum(const std::string_view value)
Converts a string into its enum equivalent.
Definition enum_base.hpp:57
#define i