/*
|
* =====================================================================================
|
*
|
* Filename: bh_util.h
|
*
|
* Description:
|
*
|
* Version: 1.0
|
* Created: 2021年03月13日 10时41分07秒
|
* Revision: none
|
* Compiler: gcc
|
*
|
* Author: lichao (),
|
* Organization:
|
*
|
* =====================================================================================
|
*/
|
#ifndef BH_UTIL_SOXWOK67
|
#define BH_UTIL_SOXWOK67
|
|
#include <functional>
|
#include <mutex>
|
#include <stdint.h>
|
|
inline uint16_t Get8(const void *p)
|
{
|
return static_cast<const uint8_t *>(p)[0];
|
}
|
inline void Put8(void *p, uint8_t u)
|
{
|
static_cast<uint8_t *>(p)[0] = u;
|
}
|
|
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]));
|
}
|
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);
|
}
|
|
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]));
|
}
|
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);
|
}
|
|
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]);
|
}
|
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);
|
}
|
|
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); }
|
|
class ExitCall
|
{
|
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(); }
|
}
|
};
|
|
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_);
|
}
|
};
|
|
// 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; })
|
|
#endif /* end of include guard: BH_UTIL_SOXWOK67 */
|