7 #ifndef _FCITX_UTILS_MISC_H_ 8 #define _FCITX_UTILS_MISC_H_ 11 #include <TargetConditionals.h> 21 #include <type_traits> 23 #include <fcitx-utils/fcitxutils_export.h> 24 #include <fcitx-utils/macros.h> 28 template <
class Parent,
class Member>
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)));
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)));
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)));
54 template <
typename Iter>
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 *;
64 FCITX_INLINE_DEFINE_DEFAULT_DTOR_AND_COPY(
KeyIterator)
66 bool operator==(
const KeyIterator &other)
const noexcept {
67 return iter_ == other.iter_;
69 bool operator!=(
const KeyIterator &other)
const noexcept {
70 return !operator==(other);
84 reference operator*() {
return iter_->first; }
86 pointer operator->() {
return &iter_->first; }
92 template <
typename It>
95 It begin()
const {
return begin_; }
96 It end()
const {
return end_; }
99 template <
typename Iter>
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));
112 FCITXUTILS_EXPORT
void startProcess(
const std::vector<std::string> &args,
113 const std::string &workingDirectory = {});
115 FCITXUTILS_EXPORT std::string getProcessName(pid_t pid);
117 template <auto FreeFunction>
119 template <
typename T>
120 void operator()(T *p)
const {
122 FreeFunction(
const_cast<std::remove_const_t<T> *
>(p));
126 template <
typename T, auto FreeFunction = std::free>
127 using UniqueCPtr = std::unique_ptr<T, FunctionDeleter<FreeFunction>>;
129 sizeof(
char *) ==
sizeof(UniqueCPtr<char>),
130 "UniqueCPtr size is not same as raw pointer.");
132 using UniqueFilePtr = std::unique_ptr<FILE, FunctionDeleter<std::fclose>>;
134 template <
typename T>
135 inline auto makeUniqueCPtr(T *ptr) {
136 return UniqueCPtr<T>(ptr);
140 FCITXUTILS_DEPRECATED_EXPORT ssize_t getline(UniqueCPtr<char> &lineptr,
141 size_t *n, std::FILE *stream);
152 FCITXUTILS_EXPORT
bool isInFlatpak();
159 constexpr
bool isAndroid() {
160 #if defined(ANDROID) || defined(__ANDROID__) 172 constexpr
bool isApple() {
173 #if defined(__APPLE__) 186 constexpr
bool isIOS() {
187 #ifdef TARGET_OS_IPHONE 188 return TARGET_OS_IPHONE == 1;
199 constexpr
bool isEmscripten() {
200 #if defined(__EMSCRIPTEN__) 212 constexpr
bool isWindows() {
222 #endif // _FCITX_UTILS_MISC_H_