liblcf
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 
19 template <typename E, size_t N>
20 class 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 
57 template <typename E, size_t... N>
58 constexpr EnumTags<E,sizeof...(N)> makeEnumTags(const char (&...literals)[N]) {
59  return EnumTags<E,sizeof...(N)>(literals...);
60 }
61 
62 template <typename E, size_t N>
63 inline 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 
72 template <typename E, size_t N>
73 inline 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 
82 template <typename E, size_t N>
83 inline 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
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
const std::array< const char *, num_tags > & tags() const
Definition: enum_tags.h:40
constexpr iterator cbegin() const
Definition: enum_tags.h:45
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 const char * operator[](int_type idx) const
Definition: enum_tags.h:34
constexpr iterator begin() const
Definition: enum_tags.h:42
constexpr const char * tag(int_type idx) const
Definition: enum_tags.h:31
constexpr const char * tag(E etag) const
Definition: enum_tags.h:30
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
constexpr EnumTags< E, sizeof...(N)> makeEnumTags(const char(&...literals)[N])
Definition: enum_tags.h:58