Fcitx
macros.h
1 /*
2  * SPDX-FileCopyrightText: 2015-2015 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #ifndef _FCITX_UTILS_MACROS_H_
8 #define _FCITX_UTILS_MACROS_H_
9 
10 // steal some Qt macro here
11 
12 #define FCITX_DECLARE_PRIVATE(Class) \
13  inline Class##Private *d_func() { \
14  return static_cast<Class##Private *>(d_ptr.get()); \
15  } \
16  inline const Class##Private *d_func() const { \
17  return static_cast<Class##Private *>(d_ptr.get()); \
18  } \
19  friend class Class##Private;
20 
21 #define FCITX_D() auto *const d = d_func()
22 #define FCITX_Q() auto *const q = q_func()
23 
24 #define FCITX_TYPED_D(TYPE) auto *const d = static_cast<TYPE *>(d_func())
25 
26 #define FCITX_UNUSED(X) ((void)(X))
27 
28 #ifdef __cplusplus
29 #define FCITX_C_DECL_BEGIN extern "C" {
30 #define FCITX_C_DECL_END }
31 #else
32 #define FCITX_C_DECL_BEGIN
33 #define FCITX_C_DECL_END
34 #endif
35 
36 #define FCITX_ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
37 
38 #ifdef __GNUC__
39 #define _FCITX_UNUSED_ __attribute__((__unused__))
40 #else
41 #define _FCITX_UNUSED_
42 #endif
43 
44 #define FCITX_WHITESPACE "\f\n\r\t\v "
45 
46 #define FCITX_EXPAND(x) x
47 #define FCITX_REMOVE_PARENS_(...) __VA_ARGS__
48 #define FCITX_REMOVE_PARENS(X) FCITX_REMOVE_PARENS_ X
49 
50 #define FCITX_FOR_EACH_0(...)
51 #define FCITX_FOR_EACH_1(what, x, ...) what(x)
52 #define FCITX_FOR_EACH_2(what, x, ...) \
53  what(x) FCITX_EXPAND(FCITX_FOR_EACH_1(what, __VA_ARGS__))
54 #define FCITX_FOR_EACH_3(what, x, ...) \
55  what(x) FCITX_EXPAND(FCITX_FOR_EACH_2(what, __VA_ARGS__))
56 #define FCITX_FOR_EACH_4(what, x, ...) \
57  what(x) FCITX_EXPAND(FCITX_FOR_EACH_3(what, __VA_ARGS__))
58 #define FCITX_FOR_EACH_5(what, x, ...) \
59  what(x) FCITX_EXPAND(FCITX_FOR_EACH_4(what, __VA_ARGS__))
60 #define FCITX_FOR_EACH_6(what, x, ...) \
61  what(x) FCITX_EXPAND(FCITX_FOR_EACH_5(what, __VA_ARGS__))
62 #define FCITX_FOR_EACH_7(what, x, ...) \
63  what(x) FCITX_EXPAND(FCITX_FOR_EACH_6(what, __VA_ARGS__))
64 #define FCITX_FOR_EACH_8(what, x, ...) \
65  what(x) FCITX_EXPAND(FCITX_FOR_EACH_7(what, __VA_ARGS__))
66 #define FCITX_FOR_EACH_9(what, x, ...) \
67  what(x) FCITX_EXPAND(FCITX_FOR_EACH_8(what, __VA_ARGS__))
68 #define FCITX_FOR_EACH_10(what, x, ...) \
69  what(x) FCITX_EXPAND(FCITX_FOR_EACH_9(what, __VA_ARGS__))
70 #define FCITX_FOR_EACH_11(what, x, ...) \
71  what(x) FCITX_EXPAND(FCITX_FOR_EACH_10(what, __VA_ARGS__))
72 #define FCITX_FOR_EACH_12(what, x, ...) \
73  what(x) FCITX_EXPAND(FCITX_FOR_EACH_11(what, __VA_ARGS__))
74 
75 #define FCITX_FOR_EACH_IDX_0(...)
76 #define FCITX_FOR_EACH_IDX_1(what, x, ...) what(1, x)
77 #define FCITX_FOR_EACH_IDX_2(what, x, ...) \
78  what(2, x) FCITX_EXPAND(FCITX_FOR_EACH_IDX_1(what, __VA_ARGS__))
79 #define FCITX_FOR_EACH_IDX_3(what, x, ...) \
80  what(3, x) FCITX_EXPAND(FCITX_FOR_EACH_IDX_2(what, __VA_ARGS__))
81 #define FCITX_FOR_EACH_IDX_4(what, x, ...) \
82  what(4, x) FCITX_EXPAND(FCITX_FOR_EACH_IDX_3(what, __VA_ARGS__))
83 #define FCITX_FOR_EACH_IDX_5(what, x, ...) \
84  what(5, x) FCITX_EXPAND(FCITX_FOR_EACH_IDX_4(what, __VA_ARGS__))
85 #define FCITX_FOR_EACH_IDX_6(what, x, ...) \
86  what(6, x) FCITX_EXPAND(FCITX_FOR_EACH_IDX_5(what, __VA_ARGS__))
87 #define FCITX_FOR_EACH_IDX_7(what, x, ...) \
88  what(7, x) FCITX_EXPAND(FCITX_FOR_EACH_IDX_6(what, __VA_ARGS__))
89 #define FCITX_FOR_EACH_IDX_8(what, x, ...) \
90  what(8, x) FCITX_EXPAND(FCITX_FOR_EACH_IDX_7(what, __VA_ARGS__))
91 #define FCITX_FOR_EACH_IDX_9(what, x, ...) \
92  what(9, x) FCITX_EXPAND(FCITX_FOR_EACH_IDX_8(what, __VA_ARGS__))
93 #define FCITX_FOR_EACH_IDX_10(what, x, ...) \
94  what(10, x) FCITX_EXPAND(FCITX_FOR_EACH_IDX_9(what, __VA_ARGS__))
95 #define FCITX_FOR_EACH_IDX_11(what, x, ...) \
96  what(11, x) FCITX_EXPAND(FCITX_FOR_EACH_IDX_10(what, __VA_ARGS__))
97 #define FCITX_FOR_EACH_IDX_12(what, x, ...) \
98  what(12, x) FCITX_EXPAND(FCITX_FOR_EACH_IDX_11(what, __VA_ARGS__))
99 
100 #define FCITX_GET_ARG13(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, N, \
101  ...) \
102  N
103 
104 #define FCITX_HAS_COMMA(...) \
105  FCITX_GET_ARG13(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)
106 
107 #define FCITX_TRIGGER_PARENTHESIS_(...) ,
108 
109 #define FCITX_IS_EMPTY(...) \
110  FCITX_IS_EMPTY_(FCITX_HAS_COMMA(__VA_ARGS__), \
111  FCITX_HAS_COMMA(FCITX_TRIGGER_PARENTHESIS_ __VA_ARGS__), \
112  FCITX_HAS_COMMA(__VA_ARGS__()), \
113  FCITX_HAS_COMMA(FCITX_TRIGGER_PARENTHESIS_ __VA_ARGS__()))
114 
115 #define FCITX_PASTE5_(_0, _1, _2, _3, _4) _0##_1##_2##_3##_4
116 
117 #define FCITX_IS_EMPTY_(_0, _1, _2, _3) \
118  FCITX_HAS_COMMA(FCITX_PASTE5_(FCITX_IS_EMPTY_CASE_, _0, _1, _2, _3))
119 
120 #define FCITX_IS_EMPTY_CASE_0001 ,
121 
122 #define FCITX_EMPTY_1(X) 0
123 #define FCITX_EMPTY_0(X) X
124 
125 #define FCITX_NARG(...) \
126  FCITX_NARG_HELPER_(FCITX_IS_EMPTY(__VA_ARGS__), FCITX_NARG_(__VA_ARGS__))
127 #define FCITX_NARG_HELPER_(B, VAL) \
128  FCITX_NARG_HELPER__(FCITX_CONCATENATE(FCITX_EMPTY_, B), VAL)
129 #define FCITX_NARG_HELPER__(B, VAL) B(VAL)
130 
131 #define FCITX_NARG_(...) FCITX_NARG__(__VA_ARGS__, FCITX_RSEQ12())
132 #define FCITX_NARG__(...) FCITX_EXPAND(FCITX_GET_ARG13(__VA_ARGS__))
133 #define FCITX_RSEQ12() 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
134 #define FCITX_CONCATENATE(x, y) x##y
135 #define FCITX_FOR_EACH_(N, what, ...) \
136  FCITX_EXPAND(FCITX_CONCATENATE(FCITX_FOR_EACH_, N)(what, __VA_ARGS__))
137 #define FCITX_FOR_EACH(what, ...) \
138  FCITX_FOR_EACH_(FCITX_NARG(__VA_ARGS__), what, __VA_ARGS__)
139 
140 #define FCITX_FOR_EACH_IDX_(N, what, ...) \
141  FCITX_EXPAND(FCITX_CONCATENATE(FCITX_FOR_EACH_IDX_, N)(what, __VA_ARGS__))
142 #define FCITX_FOR_EACH_IDX(what, ...) \
143  FCITX_FOR_EACH_IDX_(FCITX_NARG(__VA_ARGS__), what, __VA_ARGS__)
144 
145 #define FCITX_XSTRINGIFY(...) #__VA_ARGS__
146 #define FCITX_STRINGIFY(...) FCITX_XSTRINGIFY(__VA_ARGS__)
147 #define FCITX_RETURN_IF(EXPR, VALUE) \
148  if ((EXPR)) { \
149  return (VALUE); \
150  }
151 
152 #define FCITX_DECLARE_READ_ONLY_PROPERTY(TYPE, GETTER) \
153  std::conditional_t<std::is_class_v<TYPE>, const TYPE &, TYPE> GETTER() \
154  const;
155 
156 #define FCITX_DECLARE_PROPERTY(TYPE, GETTER, SETTER) \
157  FCITX_DECLARE_READ_ONLY_PROPERTY(TYPE, GETTER) \
158  void SETTER(TYPE);
159 
160 #define FCITX_DEFINE_READ_ONLY_PROPERTY_PRIVATE(THIS, TYPE, GETTER) \
161  std::conditional_t<std::is_class_v<TYPE>, const TYPE &, TYPE> \
162  THIS::GETTER() const { \
163  FCITX_TYPED_D(const THIS##Private); \
164  return d->GETTER##_; \
165  }
166 
167 #define FCITX_DEFINE_PROPERTY_PRIVATE(THIS, TYPE, GETTER, SETTER) \
168  FCITX_DEFINE_READ_ONLY_PROPERTY_PRIVATE(THIS, TYPE, GETTER) \
169  void THIS::SETTER(TYPE v) { \
170  FCITX_TYPED_D(THIS##Private); \
171  d->GETTER##_ = std::move(v); \
172  }
173 
174 #define FCITX_DECLARE_VIRTUAL_DTOR(TypeName) virtual ~TypeName();
175 
176 #define FCITX_DECLARE_MOVE(TypeName) \
177  TypeName(TypeName &&other) noexcept; \
178  TypeName &operator=(TypeName &&other) noexcept;
179 
180 #define FCITX_DECLARE_COPY(TypeName) \
181  TypeName(const TypeName &other); \
182  TypeName &operator=(const TypeName &other);
183 
184 #define FCITX_DECLARE_COPY_AND_MOVE(TypeName) \
185  FCITX_DECLARE_COPY(TypeName) \
186  FCITX_DECLARE_MOVE(TypeName)
187 
188 #define FCITX_DECLARE_VIRTUAL_DTOR_COPY_AND_MOVE(TypeName) \
189  FCITX_DECLARE_VIRTUAL_DTOR(TypeName) \
190  FCITX_DECLARE_COPY_AND_MOVE(TypeName)
191 
192 #define FCITX_DECLARE_VIRTUAL_DTOR_COPY(TypeName) \
193  FCITX_DECLARE_VIRTUAL_DTOR(TypeName) \
194  FCITX_DECLARE_COPY(TypeName)
195 
196 #define FCITX_DECLARE_VIRTUAL_DTOR_MOVE(TypeName) \
197  FCITX_DECLARE_VIRTUAL_DTOR(TypeName) \
198  FCITX_DECLARE_MOVE(TypeName)
199 
200 #define FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE_WITH_SPEC(TypeName, Spec) \
201  ~TypeName() = default; \
202  TypeName(TypeName &&other) Spec = default; \
203  TypeName &operator=(TypeName &&other) Spec = default;
204 
205 #define FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE_WITHOUT_SPEC(TypeName) \
206  FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE_WITH_SPEC(TypeName, )
207 
208 // try to enforce rule of three-five-zero
209 #define FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE(TypeName) \
210  FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE_WITH_SPEC(TypeName, noexcept)
211 
212 #define FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_COPY(TypeName) \
213  ~TypeName() = default; \
214  TypeName(const TypeName &other) = default; \
215  TypeName &operator=(const TypeName &other) = default;
216 
217 #define FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE_WITH_SPEC(TypeName, \
218  Spec) \
219  FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_MOVE_WITH_SPEC(TypeName, Spec) \
220  TypeName(const TypeName &other) = default; \
221  TypeName &operator=(const TypeName &other) = default;
222 
223 #define FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE_WITHOUT_SPEC(TypeName) \
224  FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE_WITH_SPEC(TypeName, )
225 
226 #define FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE(TypeName) \
227  FCITX_INLINE_DEFINE_DEFAULT_DTOR_COPY_AND_MOVE_WITH_SPEC(TypeName, noexcept)
228 
229 #define FCITX_DEFINE_DEFAULT_MOVE(TypeName) \
230  TypeName::TypeName(TypeName &&other) noexcept = default; \
231  TypeName &TypeName::operator=(TypeName &&other) noexcept = default;
232 
233 #define FCITX_DEFINE_DEFAULT_COPY(TypeName) \
234  TypeName::TypeName(const TypeName &other) = default; \
235  TypeName &TypeName::operator=(const TypeName &other) = default;
236 
237 #define FCITX_DEFINE_DEFAULT_DTOR(TypeName) TypeName::~TypeName() = default;
238 
239 #define FCITX_DEFINE_DPTR_COPY(TypeName) \
240  TypeName::TypeName(const TypeName &other) \
241  : d_ptr( \
242  std::make_unique<decltype(d_ptr)::element_type>(*other.d_ptr)) { \
243  } \
244  TypeName &TypeName::operator=(const TypeName &other) { \
245  if (d_ptr) { \
246  *d_ptr = *other.d_ptr; \
247  } else { \
248  d_ptr = \
249  std::make_unique<decltype(d_ptr)::element_type>(*other.d_ptr); \
250  } \
251  return *this; \
252  }
253 
254 #define FCITX_DEFINE_DPTR_COPY_AND_DEFAULT_MOVE(TypeName) \
255  FCITX_DEFINE_DPTR_COPY(TypeName) \
256  FCITX_DEFINE_DEFAULT_MOVE(TypeName)
257 
258 #define FCITX_DEFINE_DEFAULT_DTOR_AND_MOVE(TypeName) \
259  FCITX_DEFINE_DEFAULT_DTOR(TypeName) \
260  FCITX_DEFINE_DEFAULT_MOVE(TypeName)
261 
262 #define FCITX_DEFINE_DPTR_COPY_AND_DEFAULT_DTOR_AND_MOVE(TypeName) \
263  FCITX_DEFINE_DPTR_COPY(TypeName) \
264  FCITX_DEFINE_DEFAULT_MOVE(TypeName) \
265  FCITX_DEFINE_DEFAULT_DTOR(TypeName)
266 
267 #define FCITX_DEFAULT_DTOR_MOVE_AND_COPY(TypeName) \
268  FCITX_DEFINE_DEFAULT_COPY(TypeName) \
269  FCITX_DEFINE_DEFAULT_MOVE(TypeName) \
270  FCITX_DEFINE_DEFAULT_DTOR(TypeName)
271 
272 #if defined(__clang__) || __GNUC__ >= 5
273 #define HAS_CPP_ATTRIBUTE(attr) __has_cpp_attribute(attr)
274 #else
275 #define HAS_CPP_ATTRIBUTE(attr) 0
276 #endif
277 
278 // Use [[nodiscard]] specifier if supported by our compiler.
279 #if HAS_CPP_ATTRIBUTE(nodiscard)
280 #define FCITX_NODISCARD [[nodiscard]]
281 #elif HAS_CPP_ATTRIBUTE(gnu::warn_unused_result)
282 #define FCITX_NODISCARD [[gnu::warn_unused_result]]
283 #else
284 #define FCITX_NODISCARD
285 #endif
286 
287 namespace fcitx {
288 template <typename T>
289 class QPtrHolder {
290 public:
291  explicit QPtrHolder(T *q) : q_ptr(q) {}
292  QPtrHolder(const QPtrHolder &) = delete;
293  QPtrHolder(QPtrHolder &&) = delete;
294 
295  QPtrHolder &operator=(const QPtrHolder &) = delete;
296  QPtrHolder &operator=(QPtrHolder &&) = delete;
297 
298  T *q_func() { return q_ptr; }
299  const T *q_func() const { return q_ptr; }
300 
301 protected:
302  T *q_ptr;
303 };
304 } // namespace fcitx
305 #endif // _FCITX_UTILS_MACROS_H_
Definition: action.cpp:17