📄 helpers.h
字号:
#ifndef __INC_helpers_h__#define __INC_helpers_h__
#ifndef OXSEMI_INLINE
#define OXSEMI_INLINE inline
#endif#include <cstddef>#include <new>#include <utility>#include <memory>namespace oxsemi{/** * This compile time assert is better then the CT_ASSERT from the xdbg.h, as this one * can go anywhere where a typedef can go, as opposed to the CT_ASSERT which can be * used only where a statement can be put. */namespace debug {template <bool x> struct STATIC_ASSERTION_FAILURE;template <> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };template<int x> struct static_assert_test{};} // namespace debug#define STATIC_ASSERT(B, desc) \ typedef oxsemi::debug::static_assert_test<\ sizeof(oxsemi::debug::STATIC_ASSERTION_FAILURE< (bool)(B) >)>\ ERROR_##desc/*************************************************************************** * * Function: PTR_DIFF() * * Description: subtract one pointer from another and return the * relative offset * **************************************************************************/template<typename T1, typename T2>inlinesize_t PTR_DIFF(const T1* upper, const T2* lower){ return reinterpret_cast<const char*>(upper) - reinterpret_cast<const char*>(lower);}/*************************************************************************** * * Function: PTR_ADD() * * Description: Add a specified offset to a pointer * **************************************************************************/template<typename T>inlineT* PTR_ADD(T* ptr, size_t val){ return reinterpret_cast<T*>((char*)ptr + val);}/*************************************************************************** * * Function: PTR_SUB() * * Description: subtract a specified offset from a pointer * **************************************************************************/template<typename T>inlineT* PTR_SUB(T* ptr, size_t val){ return reinterpret_cast<T*>((char*)ptr - val);}/*************************************************************************** * * Class: noncopyable * * Description: derive from this to make a class noncopyable * Contributed by Dave Abrahams * **************************************************************************/class noncopyable{protected: OXSEMI_INLINE noncopyable() {} OXSEMI_INLINE ~noncopyable() {}private: noncopyable(const noncopyable&); const noncopyable& operator=(const noncopyable&);};class noheap{protected: OXSEMI_INLINE noheap() {} OXSEMI_INLINE ~noheap() {}private: static void* operator new(size_t size); static void operator delete(void* ptr);};class nonaddressable{protected: OXSEMI_INLINE nonaddressable() {} OXSEMI_INLINE ~nonaddressable() {}private: nonaddressable* operator&();};/*************************************************************************** * * auto locks * * Description: type-independent lock templates * **************************************************************************/template <typename T>class lock_ops : private noncopyable{private: OXSEMI_INLINE lock_ops() { }public: OXSEMI_INLINE static void lock(T& m) { m.lock(); } OXSEMI_INLINE static void unlock(T& m) { m.unlock(); } OXSEMI_INLINE static void lock() { T::lock(); } OXSEMI_INLINE static void unlock() { T::unlock(); }};template <typename T, typename P>class lock_ops1 : private noncopyable{private: OXSEMI_INLINE lock_ops1() { }public: OXSEMI_INLINE static void lock(T m, P p) { m.lock(p); } OXSEMI_INLINE static void unlock(T m, P p) { m.unlock(p); }};template<typename T>class scoped_lock : private noncopyable, private noheap, private nonaddressable{ friend class lock_ops<scoped_lock<T> >;private: T& obj_;public: OXSEMI_INLINE explicit scoped_lock(T& obj) : obj_(obj) { lock_ops<T>::lock(obj_); } OXSEMI_INLINE ~scoped_lock() { lock_ops<T>::unlock(obj_); }private: OXSEMI_INLINE void lock() { lock_ops<T>::lock(obj_); } OXSEMI_INLINE void unlock() { lock_ops<T>::unlock(obj_); }};// Static lockingtemplate<typename T>class scoped_static_lock : private noncopyable, private noheap, private nonaddressable{ friend class lock_ops<scoped_lock<T> >;private:public: OXSEMI_INLINE scoped_static_lock() { lock_ops<T>::lock(); } OXSEMI_INLINE ~scoped_static_lock() { lock_ops<T>::unlock(); }private: OXSEMI_INLINE void lock() { lock_ops<T>::lock(); } OXSEMI_INLINE void unlock() { lock_ops<T>::unlock(); }};// exception-safe versiontemplate<typename T, typename P>class scoped_lock1 : private noncopyable, private noheap, private nonaddressable{ friend class lock_ops1<scoped_lock1<T, P>, P>;private: T obj_; P p_;public: OXSEMI_INLINE explicit scoped_lock1(T obj, P p) : obj_(obj), p_(p) { lock_ops1<T, P>::lock(obj_, p_); } OXSEMI_INLINE ~scoped_lock1() { lock_ops1<T, P>::unlock(obj_, p_); }private: OXSEMI_INLINE void lock() { lock_ops1<T, P>::lock(obj_, p_); } OXSEMI_INLINE void unlock() { lock_ops1<T, P>::unlock(obj_, p_); }};template<typename T>class empty_lock : private noncopyable, private noheap, private nonaddressable{public: OXSEMI_INLINE explicit empty_lock(T& obj) { } OXSEMI_INLINE ~empty_lock() { }};// ----------------------------------------------------------// object wrapper// ----------------------------------------------------------template<typename T, typename W, typename WP>class object_wrapper : private oxsemi::noncopyable{private: W wrapper_; T& object_;public: explicit object_wrapper(T& object, WP& wrapper_param); ~object_wrapper(); W& Wrapper(); const W& Wrapper() const; T* operator->(); T* operator->() const;};template<typename T, typename W, typename WP>OXSEMI_INLINE object_wrapper<T,W,WP>::object_wrapper(T& object, WP& wrapper_param): wrapper_(wrapper_param), object_(object){}template<typename T, typename W, typename WP>OXSEMI_INLINE object_wrapper<T,W,WP>::~object_wrapper(){}template<typename T, typename W, typename WP>OXSEMI_INLINEW& object_wrapper<T,W,WP>::Wrapper(){ return wrapper_;}template<typename T, typename W, typename WP>OXSEMI_INLINEconst W& object_wrapper<T,W,WP>::Wrapper() const{ return wrapper_;}template<typename T, typename W, typename WP>OXSEMI_INLINE T* object_wrapper<T,W,WP>::operator->(){ return &object_;}template<typename T, typename W, typename WP>OXSEMI_INLINE T* object_wrapper<T,W,WP>::operator->() const{ return &object_;}// ----------------------------------------------------------// type helpers// ----------------------------------------------------------class NullType {};template<int x> class Null {};template<typename T>class max_align{public: union { short dummy1; int dummy2; long dummy3;// long long dummy4; double dummy5; long double dummy6; void* dummy7; void (*dummy8)(); NullType* dummy9; void (NullType::*dummy10)(); T dummy11; } dummy;};/** * 'plain old data' of size sizeof(T) aligned to A. * Do not use this for user defined types, use udtpod<> instead! * In other words DO NOT add operator->() to this class. */template<typename T, typename A = max_align<NullType> >class pod{protected: union { A align_; char data_[sizeof(T)]; };public: OXSEMI_INLINE const A& align() const { return align_; } OXSEMI_INLINE A& align() { return align_; } OXSEMI_INLINE const T& data() const { return *reinterpret_cast<const T*>(data_); } OXSEMI_INLINE T& data() { return *reinterpret_cast<T*>(data_); } OXSEMI_INLINE const T& operator*() const { return *reinterpret_cast<const T*>(data_); } OXSEMI_INLINE T& operator*() { return *reinterpret_cast<T*>(data_); }};/*************************************************************************** * * Class: udtpod<UDT,A> * * Description: user defined type in 'plain old data' container of * size sizeof(UDT) aligned to A * **************************************************************************/template<typename UDT, typename A = max_align<NullType> >class udtpod : public pod<UDT, A>{public: OXSEMI_INLINE const UDT* operator->() const { return reinterpret_cast<const UDT*>(this->data_); } OXSEMI_INLINE UDT* operator->() { return reinterpret_cast<UDT*>(this->data_); }};/*************************************************************************** * * Function: construct * * Description: constructs a new object in a given location using an * initial value * **************************************************************************/template<typename Destination, typename Source>OXSEMI_INLINEvoid construct(Destination* d, const Source& s){ new (d) Destination(s);}/*************************************************************************** * * Function: destruct * * Description: destruct an object previously created with construct() * **************************************************************************/template<typename T>OXSEMI_INLINEvoid destruct(T* p){ p->~T();}// move object Source to Destination object using copy constructor. Destroy the original object.template<typename Destination, typename Source>OXSEMI_INLINEvoid move(Destination* d, Source* s){ new (d) Destination(*s); s->~Source();}template<typename T>OXSEMI_INLINEvoid destruct(T* first, T* last){ for(; first != last; ++first) destruct(first);}template<typename T1, typename T2>OXSEMI_INLINET1 xmin(T1 a, T2 b){ return a < b ? a : b;}template<typename T1, typename T2>OXSEMI_INLINET1 xmax(T1 a, T2 b){ return a < b ? b : a;}/** * The zeroth approximation of the boost's tuple library. * See www.boost.org for details on fully-fledged tuple * library. * * The sole reason for existence of the tuple class is * tie function template (see below). */template<typename V1, typename V2>class tuple{public: typedef V1 T1; typedef V2 T2;public: OXSEMI_INLINE tuple(T1 p1, T2 p2) : e1(p1), e2(p2) { } /** * Templated copy constructor */ template <typename U1, typename U2> OXSEMI_INLINE tuple(const tuple<U1, U2>& t) : e1(t.e1), e2(t.e2) { } template <typename U1, typename U2> OXSEMI_INLINE tuple<T1,T2>& operator=(const tuple<U1, U2>& t) { e1 = t.e1; e2 = t.e2; return *this; } template <typename U1, typename U2> OXSEMI_INLINE tuple<T1,T2>& operator=(const std::pair<U1, U2>& pair) { e1 = pair.first; e2 = pair.second; return *this; }public: T1 e1; T2 e2;};/** * Makes life with functions returning std::pair<> much easier. * No more fiddling with .first and .second. * * Use it like this: * * std::pair<bool, int> SomeFunction(); * ... * bool ok; * int index; * tie(ok, index) = SomeFunction(); * if(ok) { * array[index] = bla... * } */template<typename T1, typename T2>OXSEMI_INLINEtuple<T1&, T2&> tie(T1& p1, T2& p2){ return tuple<T1&, T2&>(p1, p2);}template< typename TParent, typename TChild >inline std::auto_ptr< TParent > static_up_cast( std::auto_ptr< TChild > pChild ){ //STATIC_ASSERT( (Loki::SuperSubclassStrict<TChild,TParent>::value) , MUST_BE_A_BASE_CLASS ); return std::auto_ptr< TParent >( pChild.release() );}} // namespace oxsemi#if defined(__GNUC__)#include <cstdlib>#define DYNAMIC_ARRAY(type, name, size) \ type name[size]#else#include <malloc.h>#define DYNAMIC_ARRAY(type, name, size) \ type* name = (type*)alloca(size*sizeof(type))#endif // OXSEMI_WINNT#endif // __INC_helpers_h__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -