liblcf
Loading...
Searching...
No Matches
enum_tags.h
Go to the documentation of this file.
1/*
2 * This file is part of liblcf. Copyright (c) 2020 liblcf authors.
3 * https://github.com/EasyRPG/liblcf - https://easyrpg.org
4 *
5 * liblcf is Free/Libre Open Source Software, released under the MIT License.
6 * For the full copyright and license information, please view the COPYING
7 * file that was distributed with this source code.
8 */
9
10#ifndef LCF_ENUM_TAGS
11#define LCF_ENUM_TAGS
12
13#include <type_traits>
14#include <iterator>
15#include <cstddef>
16#include <array>
17#include <cstring>
18
19template <typename E, size_t N>
20class EnumTags {
21 public:
22 static constexpr size_t num_tags = N;
23 using int_type = typename std::make_signed<typename std::underlying_type<E>::type>::type;
24 using iterator = char const * const *;
25 using reverse_iterator = std::reverse_iterator<iterator>;
26
27 template <size_t... LN>
28 explicit constexpr EnumTags(const char (&...literals)[LN]) : _tags{{literals...}} {}
29
30 constexpr const char* tag(E etag) const { return tag(int_type(etag)); }
31 constexpr const char* tag(int_type idx) const { return _tags[idx]; }
32
33 constexpr const char* operator[](E etag) const { return tag(etag); }
34 constexpr const char* operator[](int_type idx) const { return tag(idx); }
35
36 bool etag(const char* tag, E& result) const;
37 E etagOr(const char* tag, E other) const;
38 int_type idx(const char* tag) const;
39
40 const std::array<const char*, num_tags>& tags() const { return _tags; }
41
42 constexpr iterator begin() const { return iterator(_tags.data()); }
43 constexpr iterator end() const { return iterator(_tags.data() + size()); }
44
45 constexpr iterator cbegin() const { return begin(); }
46 constexpr iterator cend() const { return end(); }
47
48 reverse_iterator rbegin() const { return reverse_iterator(end()); }
49 reverse_iterator rend() const { return reverse_iterator(begin()); }
50
51 static constexpr size_t size() { return num_tags; }
52
53 private:
54 const std::array<const char*, num_tags> _tags;
55};
56
57template <typename E, size_t... N>
58constexpr EnumTags<E,sizeof...(N)> makeEnumTags(const char (&...literals)[N]) {
59 return EnumTags<E,sizeof...(N)>(literals...);
60}
61
62template <typename E, size_t N>
63inline typename EnumTags<E, N>::int_type EnumTags<E, N>::idx(const char* tag) const {
64 for (size_t i = 0; i < _tags.size(); ++i) {
65 if (std::strcmp(_tags[i], tag) == 0) {
66 return i;
67 }
68 }
69 return -1;
70}
71
72template <typename E, size_t N>
73inline bool EnumTags<E, N>::etag(const char* tag, E& result) const {
74 auto i = idx(tag);
75 if (i < 0) {
76 return false;
77 }
78 result = E(i);
79 return true;
80}
81
82template <typename E, size_t N>
83inline E EnumTags<E, N>::etagOr(const char* tag, E other) const {
84 auto i = idx(tag);
85 return (i >= 0) ? E(i) : other;
86}
87
88#endif
bool etag(const char *tag, E &result) const
Definition: enum_tags.h:73
constexpr iterator cend() const
Definition: enum_tags.h:46
const std::array< const char *, num_tags > _tags
Definition: enum_tags.h:54
constexpr const char * operator[](int_type idx) const
Definition: enum_tags.h:34
constexpr const char * tag(E etag) const
Definition: enum_tags.h:30
reverse_iterator rend() const
Definition: enum_tags.h:49
static constexpr size_t num_tags
Definition: enum_tags.h:22
reverse_iterator rbegin() const
Definition: enum_tags.h:48
constexpr iterator end() const
Definition: enum_tags.h:43
constexpr iterator cbegin() const
Definition: enum_tags.h:45
constexpr const char * tag(int_type idx) const
Definition: enum_tags.h:31
static constexpr size_t size()
Definition: enum_tags.h:51
int_type idx(const char *tag) const
Definition: enum_tags.h:63
constexpr EnumTags(const char(&...literals)[LN])
Definition: enum_tags.h:28
E etagOr(const char *tag, E other) const
Definition: enum_tags.h:83
typename std::make_signed< typename std::underlying_type< E >::type >::type int_type
Definition: enum_tags.h:23
constexpr iterator begin() const
Definition: enum_tags.h:42
std::reverse_iterator< iterator > reverse_iterator
Definition: enum_tags.h:25
char const *const * iterator
Definition: enum_tags.h:24
constexpr const char * operator[](E etag) const
Definition: enum_tags.h:33
const std::array< const char *, num_tags > & tags() const
Definition: enum_tags.h:40
constexpr EnumTags< E, sizeof...(N)> makeEnumTags(const char(&...literals)[N])
Definition: enum_tags.h:58