Fcitx
misc.h
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_MISC_H_
8 #define _FCITX_UTILS_MISC_H_
9 
10 #include <optional>
11 #ifdef __APPLE__
12 #include <TargetConditionals.h>
13 #endif
14 
15 #include <unistd.h>
16 #include <cstddef>
17 #include <cstdio>
18 #include <cstdlib>
19 #include <functional>
20 #include <memory>
21 #include <string>
22 #include <type_traits>
23 #include <vector>
24 #include <fcitx-utils/fcitxutils_export.h>
25 #include <fcitx-utils/macros.h>
26 
27 namespace fcitx {
28 
29 template <class Parent, class Member>
30 inline std::ptrdiff_t
31 offsetFromPointerToMember(const Member Parent::*ptr_to_member) {
32  const Parent *const parent = 0;
33  const char *const member =
34  reinterpret_cast<const char *>(&(parent->*ptr_to_member));
35  return std::ptrdiff_t(member - reinterpret_cast<const char *>(parent));
36 }
37 
38 template <class Parent, class Member>
39 inline Parent *parentFromMember(Member *member,
40  const Member Parent::*ptr_to_member) {
41  return reinterpret_cast<Parent *>(reinterpret_cast<char *>(member) -
42  offsetFromPointerToMember(ptr_to_member));
43 }
44 
45 template <class Parent, class Member>
46 inline const Parent *parentFromMember(const Member *member,
47  const Member Parent::*ptr_to_member) {
48  return reinterpret_cast<const Parent *>(
49  reinterpret_cast<const char *>(member) -
50  offsetFromPointerToMember(ptr_to_member));
51 }
52 
53 template <typename Iter>
54 class KeyIterator {
55 public:
56  using iterator_category = typename Iter::iterator_category;
57  using value_type = typename Iter::value_type::first_type;
58  using difference_type = typename Iter::difference_type;
59  using reference = typename Iter::value_type::first_type &;
60  using pointer = typename Iter::value_type::first_type *;
61 
62  KeyIterator(Iter iter) : iter_(iter) {}
63  FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_COPY(KeyIterator)
64 
65  bool operator==(const KeyIterator &other) const noexcept {
66  return iter_ == other.iter_;
67  }
68  bool operator!=(const KeyIterator &other) const noexcept {
69  return !operator==(other);
70  }
71 
72  KeyIterator &operator++() {
73  iter_++;
74  return *this;
75  }
76 
77  KeyIterator operator++(int) {
78  auto old = iter_;
79  ++(*this);
80  return {old};
81  }
82 
83  reference operator*() { return iter_->first; }
84 
85  pointer operator->() { return &iter_->first; }
86 
87 private:
88  Iter iter_;
89 };
90 
91 template <typename It>
92 struct IterRange {
93  It begin_, end_;
94  It begin() const { return begin_; }
95  It end() const { return end_; }
96 };
97 
98 template <typename Iter>
99 IterRange<Iter> MakeIterRange(Iter begin, Iter end) {
100  return {begin, end};
101 }
102 
103 struct EnumHash {
104  template <typename T>
105  auto operator()(T const value) const {
106  return std::hash<std::underlying_type_t<T>>()(
107  static_cast<std::underlying_type_t<T>>(value));
108  }
109 };
110 
111 template <typename Callback>
112 class [[nodiscard]] ScopeExit {
113 public:
114  explicit ScopeExit(Callback callback) : callback_(std::move(callback)) {}
115 
116  ScopeExit(ScopeExit &&) = delete;
117  ScopeExit(const ScopeExit &) = delete;
118  ScopeExit &operator=(const ScopeExit &) = delete;
119  ScopeExit &operator=(ScopeExit &&) = delete;
120 
121  ~ScopeExit() noexcept { invoke(); }
122 
123  void release() noexcept { callback_.reset(); }
124  void invoke() noexcept {
125  if (callback_) {
126  (*callback_)();
127  callback_.reset();
128  }
129  }
130 
131 private:
132  std::optional<Callback> callback_;
133 };
134 
135 template <typename Callback>
136 ScopeExit(Callback) -> ScopeExit<Callback>;
137 
138 FCITXUTILS_EXPORT void startProcess(const std::vector<std::string> &args,
139  const std::string &workingDirectory = {});
140 
141 FCITXUTILS_EXPORT std::string getProcessName(pid_t pid);
142 
143 template <auto FreeFunction>
145  template <typename T>
146  void operator()(T *p) const {
147  if (p) {
148  FreeFunction(const_cast<std::remove_const_t<T> *>(p));
149  }
150  }
151 };
152 template <typename T, auto FreeFunction = std::free>
153 using UniqueCPtr = std::unique_ptr<T, FunctionDeleter<FreeFunction>>;
154 static_assert(
155  sizeof(char *) == sizeof(UniqueCPtr<char>),
156  "UniqueCPtr size is not same as raw pointer."); // ensure no overhead
157 
158 using UniqueFilePtr = std::unique_ptr<FILE, FunctionDeleter<std::fclose>>;
159 
160 template <typename T>
161 inline auto makeUniqueCPtr(T *ptr) {
162  return UniqueCPtr<T>(ptr);
163 }
164 
165 #ifndef _WIN32
166 FCITXUTILS_DEPRECATED_EXPORT ssize_t getline(UniqueCPtr<char> &lineptr,
167  size_t *n, std::FILE *stream);
168 #endif
169 
170 /**
171  * Util function to check whether fcitx is running in flatpak.
172  *
173  * If environment variable FCITX_OVERRIDE_FLATPAK is true, it will return true.
174  * Otherwise it will simply check the existence of file /.flatpak-info .
175  *
176  * @since 5.0.24
177  */
178 FCITXUTILS_EXPORT bool isInFlatpak();
179 
180 /**
181  * Util function that returns whether it is compile against android.
182  *
183  * @since 5.1.2
184  */
185 constexpr bool isAndroid() {
186 #if defined(ANDROID) || defined(__ANDROID__)
187  return true;
188 #else
189  return false;
190 #endif
191 }
192 
193 /**
194  * Util function that returns whether it is compile against apple.
195  *
196  * @since 5.1.7
197  */
198 constexpr bool isApple() {
199 #if defined(__APPLE__)
200  return true;
201 #else
202  return false;
203 #endif
204 }
205 
206 /**
207  * Util function that returns whether it is compile against iOS (real device or
208  * simulator).
209  *
210  * @since 5.1.20
211  */
212 constexpr bool isIOS() {
213 #ifdef TARGET_OS_IPHONE
214  return TARGET_OS_IPHONE == 1;
215 #else
216  return false;
217 #endif
218 }
219 
220 /**
221  * Util function that returns whether it is compile against emscripten.
222  *
223  * @since 5.1.12
224  */
225 constexpr bool isEmscripten() {
226 #if defined(__EMSCRIPTEN__)
227  return true;
228 #else
229  return false;
230 #endif
231 }
232 
233 /**
234  * Util function that returns whether it is compile against Windows.
235  *
236  * @since 5.1.13
237  */
238 constexpr bool isWindows() {
239 #if defined(_WIN32)
240  return true;
241 #else
242  return false;
243 #endif
244 }
245 
246 } // namespace fcitx
247 
248 #endif // _FCITX_UTILS_MISC_H_
Definition: action.cpp:17