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