7 #ifndef _FCITX_UTILS_MISC_H_ 8 #define _FCITX_UTILS_MISC_H_ 12 #include <TargetConditionals.h> 22 #include <type_traits> 24 #include <fcitx-utils/fcitxutils_export.h> 25 #include <fcitx-utils/macros.h> 29 template <
class Parent,
class Member>
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));
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));
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));
53 template <
typename Iter>
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 *;
63 FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_COPY(
KeyIterator)
65 bool operator==(
const KeyIterator &other)
const noexcept {
66 return iter_ == other.iter_;
68 bool operator!=(
const KeyIterator &other)
const noexcept {
69 return !operator==(other);
83 reference operator*() {
return iter_->first; }
85 pointer operator->() {
return &iter_->first; }
91 template <
typename It>
94 It begin()
const {
return begin_; }
95 It end()
const {
return end_; }
98 template <
typename Iter>
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));
111 template <
typename Callback>
114 explicit ScopeExit(Callback callback) : callback_(std::move(callback)) {}
123 void release() noexcept { callback_.reset(); }
124 void invoke() noexcept {
132 std::optional<Callback> callback_;
135 template <
typename Callback>
138 FCITXUTILS_EXPORT
void startProcess(
const std::vector<std::string> &args,
139 const std::string &workingDirectory = {});
141 FCITXUTILS_EXPORT std::string getProcessName(pid_t pid);
143 template <auto FreeFunction>
145 template <
typename T>
146 void operator()(T *p)
const {
148 FreeFunction(
const_cast<std::remove_const_t<T> *
>(p));
152 template <
typename T, auto FreeFunction = std::free>
153 using UniqueCPtr = std::unique_ptr<T, FunctionDeleter<FreeFunction>>;
155 sizeof(
char *) ==
sizeof(UniqueCPtr<char>),
156 "UniqueCPtr size is not same as raw pointer.");
158 using UniqueFilePtr = std::unique_ptr<FILE, FunctionDeleter<std::fclose>>;
160 template <
typename T>
161 inline auto makeUniqueCPtr(T *ptr) {
162 return UniqueCPtr<T>(ptr);
166 FCITXUTILS_DEPRECATED_EXPORT ssize_t getline(UniqueCPtr<char> &lineptr,
167 size_t *n, std::FILE *stream);
178 FCITXUTILS_EXPORT
bool isInFlatpak();
185 constexpr
bool isAndroid() {
186 #if defined(ANDROID) || defined(__ANDROID__) 198 constexpr
bool isApple() {
199 #if defined(__APPLE__) 212 constexpr
bool isIOS() {
213 #ifdef TARGET_OS_IPHONE 214 return TARGET_OS_IPHONE == 1;
225 constexpr
bool isEmscripten() {
226 #if defined(__EMSCRIPTEN__) 238 constexpr
bool isWindows() {
248 #endif // _FCITX_UTILS_MISC_H_