Fcitx
metastring.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2016-2016 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #ifndef _FCITX_UTILS_METASTRING_H_
8 #define _FCITX_UTILS_METASTRING_H_
9 
10 /// \addtogroup FcitxUtils
11 /// \{
12 /// \file
13 /// \brief Static string based on template argument.
14 
15 #include <cstddef>
16 #include <string_view>
17 
18 namespace fcitx {
19 
20 template <char... c>
21 struct MetaString final {
22 public:
23  using array_type = char const (&)[sizeof...(c) + 1];
24 
25  static constexpr std::size_t size() { return size_; }
26  static constexpr const char *data() { return str_; }
27  static constexpr bool empty() { return size_ == 0; }
28 
29  static constexpr array_type str() { return str_; }
30 
31 private:
32  static constexpr const char str_[sizeof...(c) + 1] = {c..., '\0'};
33  static const std::size_t size_ = sizeof...(c);
34 };
35 
36 template <int N, int M>
37 constexpr char __getChar(char const (&str)[M]) noexcept {
38  if constexpr (N < M) {
39  return str[N];
40  }
41  return '\0';
42 }
43 
44 template <int N>
45 constexpr char __getChar(std::string_view str) noexcept {
46  if (N < str.size()) {
47  return str[N];
48  }
49  return '\0';
50 }
51 
52 template <typename... T>
54 
55 template <char... c>
57  using type = MetaString<c...>;
58 };
59 
60 template <>
62  using type = MetaString<>;
63 };
64 
65 template <char... c, typename... Rem>
66 struct MetaStringCombine<MetaString<c...>, MetaString<'\0'>, Rem...> {
67  using type = typename MetaStringCombine<MetaString<c...>>::type;
68 };
69 template <char... c, char c2, typename... Rem>
70 struct MetaStringCombine<MetaString<c...>, MetaString<c2>, Rem...> {
71  using type = typename MetaStringCombine<MetaString<c..., c2>, Rem...>::type;
72 };
73 
74 template <typename...>
76 
77 template <>
79  using type = MetaString<>;
80 };
81 
82 template <char... c>
84  using type = MetaString<c...>;
85 };
86 
87 template <char... c1s, char... c2s, typename... _Rem>
88 struct ConcatMetaString<MetaString<c1s...>, MetaString<c2s...>, _Rem...> {
89  using type =
90  typename ConcatMetaString<MetaString<c1s..., c2s...>, _Rem...>::type;
91 };
92 
93 template <typename... Args>
94 using ConcatMetaStringType = typename ConcatMetaString<Args...>::type;
95 
96 template <typename T>
98 template <typename T>
99 using RemoveMetaStringTailType = typename RemoveMetaStringTail<T>::type;
100 
101 template <char first, char... next>
102 struct RemoveMetaStringTail<MetaString<first, next...>> {
103  using type =
104  ConcatMetaStringType<MetaString<first>,
105  RemoveMetaStringTailType<MetaString<next...>>>;
106 };
107 template <char first>
109  using type = MetaString<>;
110 };
111 
112 template <typename... T>
114 
115 template <typename... T>
116 using MetaStringBasenameHelperType =
117  typename MetaStringBasenameHelper<T...>::type;
118 
119 template <>
121  using type = MetaString<>;
122 };
123 
124 template <char... c>
126  using type = MetaString<c...>;
127 };
128 
129 template <char... c>
131  using type = MetaStringBasenameHelperType<MetaString<c...>>;
132 };
133 
134 template <char... c, char c2, typename... Rem>
135 struct MetaStringBasenameHelper<MetaString<c...>, MetaString<c2>, Rem...> {
136  using type = MetaStringBasenameHelperType<MetaString<c..., c2>, Rem...>;
137 };
138 
139 template <char... c, typename... Rem>
140 struct MetaStringBasenameHelper<MetaString<c...>, MetaString<'/'>, Rem...> {
141  using type = MetaStringBasenameHelperType<Rem...>;
142 };
143 
144 template <typename T>
146 
147 template <char... c>
149  using type = MetaStringBasenameHelperType<MetaString<c>...>;
150 };
151 
152 template <typename T>
153 using MetaStringBasenameType = typename MetaStringBasename<T>::type;
154 
155 template <char... c>
157  using type = typename MetaStringCombine<MetaString<c>...>::type;
158 };
159 
160 template <char... c>
161 using MetaStringTrimType = typename MetaStringTrim<c...>::type;
162 
163 #define FCITX_METASTRING_TEMPLATE_16(N, S) \
164  ::fcitx::__getChar<0x##N##0>(S), ::fcitx::__getChar<0x##N##1>(S), \
165  ::fcitx::__getChar<0x##N##2>(S), ::fcitx::__getChar<0x##N##3>(S), \
166  ::fcitx::__getChar<0x##N##4>(S), ::fcitx::__getChar<0x##N##5>(S), \
167  ::fcitx::__getChar<0x##N##6>(S), ::fcitx::__getChar<0x##N##7>(S), \
168  ::fcitx::__getChar<0x##N##8>(S), ::fcitx::__getChar<0x##N##9>(S), \
169  ::fcitx::__getChar<0x##N##A>(S), ::fcitx::__getChar<0x##N##B>(S), \
170  ::fcitx::__getChar<0x##N##C>(S), ::fcitx::__getChar<0x##N##D>(S), \
171  ::fcitx::__getChar<0x##N##E>(S), ::fcitx::__getChar<0x##N##F>(S)
172 
173 #define FCITX_METASTRING_TEMPLATE_256(N, S) \
174  FCITX_METASTRING_TEMPLATE_16(N##0, S) \
175  , FCITX_METASTRING_TEMPLATE_16(N##1, S), \
176  FCITX_METASTRING_TEMPLATE_16(N##2, S), \
177  FCITX_METASTRING_TEMPLATE_16(N##3, S), \
178  FCITX_METASTRING_TEMPLATE_16(N##4, S), \
179  FCITX_METASTRING_TEMPLATE_16(N##5, S), \
180  FCITX_METASTRING_TEMPLATE_16(N##6, S), \
181  FCITX_METASTRING_TEMPLATE_16(N##7, S), \
182  FCITX_METASTRING_TEMPLATE_16(N##8, S), \
183  FCITX_METASTRING_TEMPLATE_16(N##9, S), \
184  FCITX_METASTRING_TEMPLATE_16(N##A, S), \
185  FCITX_METASTRING_TEMPLATE_16(N##B, S), \
186  FCITX_METASTRING_TEMPLATE_16(N##C, S), \
187  FCITX_METASTRING_TEMPLATE_16(N##D, S), \
188  FCITX_METASTRING_TEMPLATE_16(N##E, S), \
189  FCITX_METASTRING_TEMPLATE_16(N##F, S)
190 
191 /// \brief Create meta string from string literal.
192 #define fcitxMakeMetaString(STRING) \
193  ::fcitx::MetaStringTrimType<FCITX_METASTRING_TEMPLATE_256(, STRING)>
194 } // namespace fcitx
195 
196 #endif // _FCITX_UTILS_METASTRING_H_
Definition: action.cpp:17