#pragma once namespace pfc { template class vartoggle_t { T oldval; T & var; public: vartoggle_t(T & p_var,const T & val) : var(p_var) { oldval = var; var = val; } ~vartoggle_t() {var = oldval;} }; template class vartoggle_volatile_t { T oldval; volatile T & var; public: vartoggle_volatile_t(volatile T & p_var,const T & val) : var(p_var) { oldval = var; var = val; } ~vartoggle_volatile_t() {var = oldval;} }; typedef vartoggle_t booltoggle; }; #ifdef _MSC_VER class fpu_control { unsigned old_val; unsigned mask; public: inline fpu_control(unsigned p_mask,unsigned p_val) { mask = p_mask; _controlfp_s(&old_val,p_val,mask); } inline ~fpu_control() { unsigned dummy; _controlfp_s(&dummy,old_val,mask); } }; class fpu_control_roundnearest : private fpu_control { public: fpu_control_roundnearest() : fpu_control(_MCW_RC,_RC_NEAR) {} }; class fpu_control_flushdenormal : private fpu_control { public: fpu_control_flushdenormal() : fpu_control(_MCW_DN,_DN_FLUSH) {} }; class fpu_control_default : private fpu_control { public: fpu_control_default() : fpu_control(_MCW_DN|_MCW_RC,_DN_FLUSH|_RC_NEAR) {} }; #ifdef _M_IX86 class sse_control { public: sse_control(unsigned p_mask,unsigned p_val) : m_mask(p_mask) { __control87_2(p_val,p_mask,NULL,&m_oldval); } ~sse_control() { __control87_2(m_oldval,m_mask,NULL,&m_oldval); } private: unsigned m_mask,m_oldval; }; class sse_control_flushdenormal : private sse_control { public: sse_control_flushdenormal() : sse_control(_MCW_DN,_DN_FLUSH) {} }; #endif #endif namespace pfc { class releaser_delete { public: template static void release(T* p_ptr) {delete p_ptr;} }; class releaser_delete_array { public: template static void release(T* p_ptr) {delete[] p_ptr;} }; class releaser_free { public: static void release(void * p_ptr) {free(p_ptr);} }; //! Assumes t_freefunc to never throw exceptions. template class ptrholder_t { private: typedef ptrholder_t t_self; public: inline ptrholder_t(T* p_ptr) : m_ptr(p_ptr) {} inline ptrholder_t() : m_ptr(NULL) {} inline ~ptrholder_t() {t_releaser::release(m_ptr);} inline bool is_valid() const {return m_ptr != NULL;} inline bool is_empty() const {return m_ptr == NULL;} inline T* operator->() const {return m_ptr;} inline T* get_ptr() const {return m_ptr;} inline void release() {t_releaser::release(replace_null_t(m_ptr));;} inline void attach(T * p_ptr) {release(); m_ptr = p_ptr;} inline const t_self & operator=(T * p_ptr) {set(p_ptr);return *this;} inline T* detach() {return pfc::replace_null_t(m_ptr);} inline T& operator*() const {return *m_ptr;} inline t_self & operator<<(t_self & p_source) {attach(p_source.detach());return *this;} inline t_self & operator>>(t_self & p_dest) {p_dest.attach(detach());return *this;} //deprecated inline void set(T * p_ptr) {attach(p_ptr);} ptrholder_t(t_self&& other) { m_ptr = other.detach(); } const t_self& operator=(t_self&& other) { attach(other.detach()); return this; } private: ptrholder_t(const t_self &) {throw pfc::exception_not_implemented();} const t_self & operator=(const t_self & ) {throw pfc::exception_not_implemented();} T* m_ptr; }; //avoid "void&" breakage template class ptrholder_t { private: typedef void T; typedef ptrholder_t t_self; public: inline ptrholder_t(T* p_ptr) : m_ptr(p_ptr) {} inline ptrholder_t() : m_ptr(NULL) {} inline ~ptrholder_t() {t_releaser::release(m_ptr);} inline bool is_valid() const {return m_ptr != NULL;} inline bool is_empty() const {return m_ptr == NULL;} inline T* operator->() const {return m_ptr;} inline T* get_ptr() const {return m_ptr;} inline void release() {t_releaser::release(replace_null_t(m_ptr));;} inline void attach(T * p_ptr) {release(); m_ptr = p_ptr;} inline const t_self & operator=(T * p_ptr) {set(p_ptr);return *this;} inline T* detach() {return pfc::replace_null_t(m_ptr);} inline t_self & operator<<(t_self & p_source) {attach(p_source.detach());return *this;} inline t_self & operator>>(t_self & p_dest) {p_dest.attach(detach());return *this;} //deprecated inline void set(T * p_ptr) {attach(p_ptr);} private: ptrholder_t(const t_self &) {throw pfc::exception_not_implemented();} const t_self & operator=(const t_self & ) {throw pfc::exception_not_implemented();} T* m_ptr; }; PFC_NORETURN void crash(); void outputDebugLine(const char * msg); class debugLog : public string_formatter { public: ~debugLog() { outputDebugLine(this->get_ptr()); } }; #define PFC_DEBUGLOG ::pfc::debugLog()._formatter() template class int_container_helper { public: int_container_helper() : m_val(p_initval) {} t_type m_val; }; //warning: not multi-thread-safe template class instanceTracker : public t_base { private: typedef instanceTracker t_self; public: TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(instanceTracker,t_base,{g_list += this;}); instanceTracker(const t_self & p_other) : t_base( (const t_base &)p_other) {g_list += this;} ~instanceTracker() {g_list -= this;} typedef pfc::avltree_t t_list; static const t_list & instanceList() {return g_list;} template static void forEach(t_callback & p_callback) {instanceList().enumerate(p_callback);} private: static t_list g_list; }; template typename instanceTracker::t_list instanceTracker::g_list; //warning: not multi-thread-safe template class instanceTrackerV2 { private: typedef instanceTrackerV2 t_self; public: instanceTrackerV2(const t_self & p_other) {g_list += static_cast(this);} instanceTrackerV2() {g_list += static_cast(this);} ~instanceTrackerV2() {g_list -= static_cast(this);} typedef pfc::avltree_t t_instanceList; static const t_instanceList & instanceList() {return g_list;} template static void forEach(t_callback & p_callback) {instanceList().enumerate(p_callback);} private: static t_instanceList g_list; }; template typename instanceTrackerV2::t_instanceList instanceTrackerV2::g_list; struct objDestructNotifyData { bool m_flag; objDestructNotifyData * m_next; }; class objDestructNotify { public: objDestructNotify() : m_data() {} ~objDestructNotify() { set(); } void set() { objDestructNotifyData * w = m_data; while(w) { w->m_flag = true; w = w->m_next; } } objDestructNotifyData * m_data; }; class objDestructNotifyScope : private objDestructNotifyData { public: objDestructNotifyScope(objDestructNotify &obj) : m_obj(&obj) { m_next = m_obj->m_data; m_obj->m_data = this; } ~objDestructNotifyScope() { if (!m_flag) m_obj->m_data = m_next; } bool get() const {return m_flag;} PFC_CLASS_NOT_COPYABLE_EX(objDestructNotifyScope) private: objDestructNotify * m_obj; }; class bigmem { public: enum {slice = 1024*1024}; bigmem() : m_size() {} ~bigmem() {clear();} void resize(size_t newSize); size_t size() const {return m_size;} void clear(); void read(void * ptrOut, size_t bytes, size_t offset); void write(const void * ptrIn, size_t bytes, size_t offset); uint8_t * _slicePtr(size_t which); size_t _sliceCount(); size_t _sliceSize(size_t which); private: array_t m_data; size_t m_size; PFC_CLASS_NOT_COPYABLE_EX(bigmem) }; double exp_int( double base, int exp ); }