ARTS 2.5.4 (git: bcd8c674)
enums.h
Go to the documentation of this file.
1#ifndef enums_h
2#define enums_h
3
4#include <algorithm>
5#include <array>
6#include <iostream>
7#include <sstream>
8#include <string>
9#include <string_view>
10
11#include "debug.h"
12#include "nonstd.h"
13
21template <typename EnumType>
22constexpr bool good_enum(EnumType x) noexcept {
23 return std::size_t(x) < std::size_t(EnumType::FINAL);
24}
25
34template <typename EnumType> constexpr
35std::array<std::string_view, size_t(EnumType::FINAL)> enum_strarray(
36 const std::string_view strchars) noexcept {
37 std::array<std::string_view, size_t(EnumType::FINAL)> out;
38
39 // Find the start
40 std::string_view::size_type N0 = 0;
41
42 // Set all the values
43 for (auto& str: out) {
44 // Find a comma but never look beyond the end of the string
45 const std::string_view::size_type N1 =
46 std::min(strchars.find(',', N0), strchars.size());
47
48 // Set the string between start and the length of the string
49 str = strchars.substr(N0, N1 - N0);
50
51 // Remove spaces at the beginning and at the end of the string
52 while (nonstd::isspace(str.front())) str.remove_prefix(1);
53 while (nonstd::isspace(str.back())) str.remove_suffix(1);
54
55 // Set the new start for the next iteration
56 N0 = N1 + 1;
57 }
58
59 return out;
60}
61
68template <typename EnumType> constexpr
69std::array<EnumType, size_t(EnumType::FINAL)> enum_typarray() noexcept {
70 std::array<EnumType, size_t(EnumType::FINAL)> out{};
71 for (size_t i = 0; i < size_t(EnumType::FINAL); i++)
72 out[i] = EnumType(i);
73 return out;
74}
75
82template <typename EnumType, typename ... Messages> constexpr
83void check_enum_error(EnumType type, Messages ... args) {
84 ARTS_USER_ERROR_IF (not good_enum(type), args...)
85}
86
135#define ENUMCLASS(ENUMTYPE, TYPE, ...) \
136 enum class ENUMTYPE : TYPE { __VA_ARGS__, FINAL }; \
137 \
138 namespace enumstrs { \
139 constexpr auto ENUMTYPE##Names = enum_strarray<ENUMTYPE>(#__VA_ARGS__); \
140 } \
141 \
142 namespace enumtyps { \
143 [[maybe_unused]] \
144 constexpr auto ENUMTYPE##Types = enum_typarray<ENUMTYPE>(); \
145 } \
146 \
147 constexpr std::string_view toString(ENUMTYPE x) noexcept { \
148 if (good_enum(x)) \
149 return enumstrs::ENUMTYPE##Names[(TYPE)x]; \
150 return "BAD " #ENUMTYPE; \
151 } \
152 \
153 constexpr ENUMTYPE to##ENUMTYPE(const std::string_view x) noexcept { \
154 for (TYPE i = 0; i < (TYPE)ENUMTYPE::FINAL; i++) \
155 if (enumstrs::ENUMTYPE##Names[i] == x) return ENUMTYPE(i); \
156 return ENUMTYPE::FINAL; \
157 } \
158 \
159 constexpr ENUMTYPE to##ENUMTYPE##OrThrow(const std::string_view x) { \
160 ENUMTYPE out = to##ENUMTYPE(x); \
161 check_enum_error(out, "Cannot understand argument: \"", x, "\"\n" \
162 "Valid " #ENUMTYPE " options are: [" \
163 #__VA_ARGS__ "]"); \
164 return out; \
165 } \
166 \
167 inline std::ostream &operator<<(std::ostream &os, const ENUMTYPE x) { \
168 return os << toString(x); \
169 } \
170 \
171 inline std::istream &operator>>(std::istream &is, ENUMTYPE &x) { \
172 std::string val; \
173 is >> val; \
174 x = to##ENUMTYPE##OrThrow(val); \
175 return is; \
176 }
177
178#endif // enums_h
179
Helper macros for debugging.
#define ARTS_USER_ERROR_IF(condition,...)
Definition: debug.h:134
constexpr std::array< EnumType, size_t(EnumType::FINAL)> enum_typarray() noexcept
A list of all enum types by index-conversion.
Definition: enums.h:69
constexpr void check_enum_error(EnumType type, Messages ... args)
Checks if the enum class type is good and otherwise throws an error message composed by variadic inpu...
Definition: enums.h:83
constexpr std::array< std::string_view, size_t(EnumType::FINAL)> enum_strarray(const std::string_view strchars) noexcept
Internal string view array generator.
Definition: enums.h:35
constexpr bool good_enum(EnumType x) noexcept
Checks if the enum number is good.
Definition: enums.h:22
#define min(a, b)
constexpr int isspace(int ch) noexcept
Returns 1 if x is a standard space-character.
Definition: nonstd.h:39
#define N1
Definition: rng.cc:273