liuxiaolong
2021-07-20 58d904a328c0d849769b483e901a0be9426b8209
src/bh_util.h
@@ -18,12 +18,14 @@
#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)
{
   return static_cast<const uint8_t*>(p)[0];
   return static_cast<const uint8_t *>(p)[0];
}
inline void Put8(void *p, uint8_t u)
{
@@ -32,57 +34,57 @@
inline uint16_t Get16(const void *p)
{
   auto ptr = static_cast<const uint8_t*>(p);
   return (((uint16_t)ptr[0]) << 8u) |
         (((uint16_t)ptr[1]));
   auto ptr = static_cast<const uint8_t *>(p);
   return (((uint16_t) ptr[0]) << 8u) |
          (((uint16_t) ptr[1]));
}
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)
{
   auto ptr = static_cast<const uint8_t*>(p);
   return (((uint32_t)ptr[0]) << 24u) |
         (((uint32_t)ptr[1]) << 16u) |
         (((uint32_t)ptr[2]) << 8u) |
         (((uint32_t)ptr[3]));
   auto ptr = static_cast<const uint8_t *>(p);
   return (((uint32_t) ptr[0]) << 24u) |
          (((uint32_t) ptr[1]) << 16u) |
          (((uint32_t) ptr[2]) << 8u) |
          (((uint32_t) ptr[3]));
}
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 uint64_t Get64(const void *p)
{
   auto ptr = static_cast<const uint8_t*>(p);
   return (((uint64_t)ptr[0]) << 56u) |
         (((uint64_t)ptr[1]) << 48u) |
         (((uint64_t)ptr[2]) << 40u) |
         (((uint64_t)ptr[3]) << 32u) |
         (((uint64_t)ptr[4]) << 24u) |
         (((uint64_t)ptr[5]) << 16u) |
         (((uint64_t)ptr[6]) << 8u) |
         ((uint64_t)ptr[7]);
   auto ptr = static_cast<const uint8_t *>(p);
   return (((uint64_t) ptr[0]) << 56u) |
          (((uint64_t) ptr[1]) << 48u) |
          (((uint64_t) ptr[2]) << 40u) |
          (((uint64_t) ptr[3]) << 32u) |
          (((uint64_t) ptr[4]) << 24u) |
          (((uint64_t) ptr[5]) << 16u) |
          (((uint64_t) ptr[6]) << 8u) |
          ((uint64_t) ptr[7]);
}
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); }
@@ -90,22 +92,58 @@
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
{
    typedef std::function<void(void)> func_t;
    func_t m_func;
   typedef std::function<void(void)> func_t;
   func_t m_func;
public:
    explicit ExitCall(func_t f): m_func(f) {}
    ~ExitCall() { if (m_func) { m_func(); } }
   explicit ExitCall(func_t f) :
       m_func(f) {}
   ~ExitCall()
   {
      if (m_func) { m_func(); }
   }
};
// 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 */