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