| | |
| | | #ifndef BH_UTIL_SOXWOK67 |
| | | #define BH_UTIL_SOXWOK67 |
| | | |
| | | #include "macro.h" |
| | | #include <functional> |
| | | #include <mutex> |
| | | #include <stdint.h> |
| | | |
| | | inline uint16_t Get8(const void *p) |
| | |
| | | inline void Put16(void *p, uint16_t u) |
| | | { |
| | | auto ptr = static_cast<uint8_t *>(p); |
| | | ptr[0] = (uint8_t)(u >> 8u); |
| | | ptr[1] = (uint8_t)(u); |
| | | ptr[0] = (uint8_t) (u >> 8u); |
| | | ptr[1] = (uint8_t) (u); |
| | | } |
| | | |
| | | inline uint32_t Get32(const void *p) |
| | |
| | | inline void Put32(void *p, uint32_t u) |
| | | { |
| | | auto ptr = static_cast<uint8_t *>(p); |
| | | ptr[0] = (uint8_t)(u >> 24u); |
| | | ptr[1] = (uint8_t)(u >> 16u); |
| | | ptr[2] = (uint8_t)(u >> 8u); |
| | | ptr[3] = (uint8_t)(u); |
| | | ptr[0] = (uint8_t) (u >> 24u); |
| | | ptr[1] = (uint8_t) (u >> 16u); |
| | | ptr[2] = (uint8_t) (u >> 8u); |
| | | ptr[3] = (uint8_t) (u); |
| | | } |
| | | |
| | | inline uint64_t Get64(const void *p) |
| | |
| | | inline void Put64(void *p, uint64_t u) |
| | | { |
| | | auto ptr = static_cast<uint8_t *>(p); |
| | | ptr[0] = (uint8_t)(u >> 56); |
| | | ptr[1] = (uint8_t)(u >> 48); |
| | | ptr[2] = (uint8_t)(u >> 40u); |
| | | ptr[3] = (uint8_t)(u >> 32); |
| | | ptr[4] = (uint8_t)(u >> 24u); |
| | | ptr[5] = (uint8_t)(u >> 16u); |
| | | ptr[6] = (uint8_t)(u >> 8u); |
| | | ptr[7] = (uint8_t)(u); |
| | | ptr[0] = (uint8_t) (u >> 56); |
| | | ptr[1] = (uint8_t) (u >> 48); |
| | | ptr[2] = (uint8_t) (u >> 40u); |
| | | ptr[3] = (uint8_t) (u >> 32); |
| | | ptr[4] = (uint8_t) (u >> 24u); |
| | | ptr[5] = (uint8_t) (u >> 16u); |
| | | ptr[6] = (uint8_t) (u >> 8u); |
| | | ptr[7] = (uint8_t) (u); |
| | | } |
| | | |
| | | inline void PutInt(void *p, uint8_t u) { Put8(p, u); } |
| | | inline void PutInt(void *p, uint16_t u) { Put16(p, u); } |
| | | inline void PutInt(void *p, uint32_t u) { Put32(p, u); } |
| | | inline void PutInt(void *p, uint64_t u) { Put64(p, u); } |
| | | |
| | | constexpr uint64_t MaskBits(int nbits) { return (uint64_t(1) << nbits) - 1; } |
| | | |
| | | class ExitCall |
| | | { |
| | |
| | | } |
| | | }; |
| | | |
| | | // macro helper |
| | | #define JOIN_IMPL(a, b) a##b |
| | | #define JOIN(a, b) JOIN_IMPL(a, b) |
| | | // defer function / lambda. |
| | | #define DEFERF(func) ExitCall JOIN(defer_, __LINE__)(func) |
| | | // defer simple expression |
| | | #define DEFER1(expr) DEFERF([&]() { expr; }) |
| | | template <class D, class M, class G = std::unique_lock<M>> |
| | | class SyncedPtr |
| | | { |
| | | G lock_; |
| | | D *p_ = nullptr; |
| | | |
| | | public: |
| | | SyncedPtr(M &mtx, D &data) : |
| | | lock_(mtx), p_(&data) {} |
| | | SyncedPtr(SyncedPtr &&a) |
| | | { |
| | | lock_.swap(a.lock_); |
| | | std::swap(p_, a.p_); |
| | | } |
| | | D *operator->() const { return p_; } |
| | | D &operator*() const { return *p_; } |
| | | }; |
| | | |
| | | template <class T, class TMutex = std::mutex, class Lock = std::unique_lock<TMutex>> |
| | | class Synced |
| | | { |
| | | typedef T Data; |
| | | TMutex mutex_; |
| | | Data data_; |
| | | typedef SyncedPtr<Data, TMutex, Lock> Ptr; |
| | | |
| | | public: |
| | | template <class... P> |
| | | explicit Synced(const P &...p) : |
| | | data_(p...) {} |
| | | Ptr operator->() { return Ptr(mutex_, data_); } |
| | | auto Apply(const auto &f) |
| | | { |
| | | Lock lk(mutex_); |
| | | return f(data_); |
| | | } |
| | | }; |
| | | |
| | | #endif /* end of include guard: BH_UTIL_SOXWOK67 */ |