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 
17 namespace fcitx {
18 
19 template <char... c>
20 struct MetaString final {
21 public:
22  using array_type = char const (&)[sizeof...(c) + 1];
23 
24  static constexpr std::size_t size() { return size_; }
25  static constexpr const char *data() { return str_; }
26  static constexpr bool empty() { return size_ == 0; }
27 
28  static constexpr array_type str() { return str_; }
29 
30 private:
31  static constexpr const char str_[sizeof...(c) + 1] = {c..., '\0'};
32  static const std::size_t size_ = sizeof...(c);
33 };
34 
35 template <int N, int M>
36 constexpr char __getChar(char const (&str)[M]) noexcept {
37  if constexpr (N < M) {
38  return str[N];
39  }
40  return '\0';
41 }
42 
43 template <typename... T>
45 
46 template <char... c>
48  using type = MetaString<c...>;
49 };
50 
51 template <>
53  using type = MetaString<>;
54 };
55 
56 template <char... c, typename... Rem>
57 struct MetaStringCombine<MetaString<c...>, MetaString<'\0'>, Rem...> {
58  using type = typename MetaStringCombine<MetaString<c...>>::type;
59 };
60 template <char... c, char c2, typename... Rem>
61 struct MetaStringCombine<MetaString<c...>, MetaString<c2>, Rem...> {
62  using type = typename MetaStringCombine<MetaString<c..., c2>, Rem...>::type;
63 };
64 
65 template <typename...>
67 
68 template <>
70  using type = MetaString<>;
71 };
72 
73 template <char... c>
75  using type = MetaString<c...>;
76 };
77 
78 template <char... c1s, char... c2s, typename... _Rem>
79 struct ConcatMetaString<MetaString<c1s...>, MetaString<c2s...>, _Rem...> {
80  using type =
81  typename ConcatMetaString<MetaString<c1s..., c2s...>, _Rem...>::type;
82 };
83 
84 template <typename... Args>
85 using ConcatMetaStringType = typename ConcatMetaString<Args...>::type;
86 
87 template <typename T>
89 template <typename T>
90 using RemoveMetaStringTailType = typename RemoveMetaStringTail<T>::type;
91 
92 template <char first, char... next>
93 struct RemoveMetaStringTail<MetaString<first, next...>> {
94  using type =
95  ConcatMetaStringType<MetaString<first>,
96  RemoveMetaStringTailType<MetaString<next...>>>;
97 };
98 template <char first>
100  using type = MetaString<>;
101 };
102 
103 template <typename... T>
105 
106 template <typename... T>
107 using MetaStringBasenameHelperType =
108  typename MetaStringBasenameHelper<T...>::type;
109 
110 template <>
112  using type = MetaString<>;
113 };
114 
115 template <char... c>
117  using type = MetaString<c...>;
118 };
119 
120 template <char... c>
122  using type = MetaStringBasenameHelperType<MetaString<c...>>;
123 };
124 
125 template <char... c, char c2, typename... Rem>
126 struct MetaStringBasenameHelper<MetaString<c...>, MetaString<c2>, Rem...> {
127  using type = MetaStringBasenameHelperType<MetaString<c..., c2>, Rem...>;
128 };
129 
130 template <char... c, typename... Rem>
131 struct MetaStringBasenameHelper<MetaString<c...>, MetaString<'/'>, Rem...> {
132  using type = MetaStringBasenameHelperType<Rem...>;
133 };
134 
135 template <typename T>
137 
138 template <char... c>
140  using type = MetaStringBasenameHelperType<MetaString<c>...>;
141 };
142 
143 template <typename T>
144 using MetaStringBasenameType = typename MetaStringBasename<T>::type;
145 
146 template <char... c>
148  using type = typename MetaStringCombine<MetaString<c>...>::type;
149 };
150 
151 template <char... c>
152 using MetaStringTrimType = typename MetaStringTrim<c...>::type;
153 
154 #define FCITX_METASTRING_TEMPLATE_16(N, S) \
155  ::fcitx::__getChar<0x##N##0>(S), ::fcitx::__getChar<0x##N##1>(S), \
156  ::fcitx::__getChar<0x##N##2>(S), ::fcitx::__getChar<0x##N##3>(S), \
157  ::fcitx::__getChar<0x##N##4>(S), ::fcitx::__getChar<0x##N##5>(S), \
158  ::fcitx::__getChar<0x##N##6>(S), ::fcitx::__getChar<0x##N##7>(S), \
159  ::fcitx::__getChar<0x##N##8>(S), ::fcitx::__getChar<0x##N##9>(S), \
160  ::fcitx::__getChar<0x##N##A>(S), ::fcitx::__getChar<0x##N##B>(S), \
161  ::fcitx::__getChar<0x##N##C>(S), ::fcitx::__getChar<0x##N##D>(S), \
162  ::fcitx::__getChar<0x##N##E>(S), ::fcitx::__getChar<0x##N##F>(S)
163 
164 #define FCITX_METASTRING_TEMPLATE_256(N, S) \
165  FCITX_METASTRING_TEMPLATE_16(N##0, S) \
166  , FCITX_METASTRING_TEMPLATE_16(N##1, S), \
167  FCITX_METASTRING_TEMPLATE_16(N##2, S), \
168  FCITX_METASTRING_TEMPLATE_16(N##3, S), \
169  FCITX_METASTRING_TEMPLATE_16(N##4, S), \
170  FCITX_METASTRING_TEMPLATE_16(N##5, S), \
171  FCITX_METASTRING_TEMPLATE_16(N##6, S), \
172  FCITX_METASTRING_TEMPLATE_16(N##7, S), \
173  FCITX_METASTRING_TEMPLATE_16(N##8, S), \
174  FCITX_METASTRING_TEMPLATE_16(N##9, S), \
175  FCITX_METASTRING_TEMPLATE_16(N##A, S), \
176  FCITX_METASTRING_TEMPLATE_16(N##B, S), \
177  FCITX_METASTRING_TEMPLATE_16(N##C, S), \
178  FCITX_METASTRING_TEMPLATE_16(N##D, S), \
179  FCITX_METASTRING_TEMPLATE_16(N##E, S), \
180  FCITX_METASTRING_TEMPLATE_16(N##F, S)
181 
182 /// \brief Create meta string from string literal.
183 #define fcitxMakeMetaString(STRING) \
184  ::fcitx::MetaStringTrimType<FCITX_METASTRING_TEMPLATE_256(, STRING)>
185 } // namespace fcitx
186 
187 #endif // _FCITX_UTILS_METASTRING_H_
Definition: action.cpp:12