#pragma once #include #include #include #include #include #include "logging.h" #define DISALLOW_COPY_AND_MOVE(clazz) \ clazz(const clazz &) = delete; \ clazz(clazz &&) = delete; class mutex_guard { DISALLOW_COPY_AND_MOVE(mutex_guard) public: explicit mutex_guard(pthread_mutex_t &m): mutex(&m) { pthread_mutex_lock(mutex); } void unlock() { pthread_mutex_unlock(mutex); mutex = nullptr; } ~mutex_guard() { if (mutex) pthread_mutex_unlock(mutex); } private: pthread_mutex_t *mutex; }; using thread_entry = void *(*)(void *); int new_daemon_thread(thread_entry entry, void *arg); static inline bool str_contains(std::string_view s, std::string_view ss) { return s.find(ss) != std::string_view::npos; } template class stateless_allocator { public: using value_type = T; T *allocate(size_t num) { return static_cast(Impl::allocate(sizeof(T) * num)); } void deallocate(T *ptr, size_t num) { Impl::deallocate(ptr, sizeof(T) * num); } stateless_allocator() = default; stateless_allocator(const stateless_allocator&) = default; stateless_allocator(stateless_allocator&&) = default; template stateless_allocator(const stateless_allocator&) {} bool operator==(const stateless_allocator&) { return true; } bool operator!=(const stateless_allocator&) { return false; } }; template class reversed_container { public: reversed_container(T &base) : base(base) {} decltype(std::declval().rbegin()) begin() { return base.rbegin(); } decltype(std::declval().crbegin()) begin() const { return base.crbegin(); } decltype(std::declval().crbegin()) cbegin() const { return base.crbegin(); } decltype(std::declval().rend()) end() { return base.rend(); } decltype(std::declval().crend()) end() const { return base.crend(); } decltype(std::declval().crend()) cend() const { return base.crend(); } private: T &base; }; template reversed_container reversed(T &base) { return reversed_container(base); } template static inline void default_new(T *&p) { p = new T(); } template static inline void default_new(std::unique_ptr &p) { p.reset(new T()); } struct StringCmp { using is_transparent = void; bool operator()(std::string_view a, std::string_view b) const { return a < b; } }; /* * Bionic's atoi runs through strtol(). * Use our own implementation for faster conversion. */ int parse_int(std::string_view s); std::list split_str(std::string_view s, std::string_view delimiter); std::string join_str(const std::list& list, std::string_view delimiter); template static inline T align_to(T v, int a) { static_assert(std::is_integral::value); return (v + a - 1) / a * a; }