#pragma once #include #define tabsize(x) ((size_t)(sizeof(x)/sizeof(*x))) #define PFC_TABSIZE(x) ((size_t)(sizeof(x)/sizeof(*x))) #define TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(THISCLASS,MEMBER,INITIALIZER) \ THISCLASS() : MEMBER() INITIALIZER \ template THISCLASS(const t_param1 & p_param1) : MEMBER(p_param1) INITIALIZER \ template THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2) : MEMBER(p_param1,p_param2) INITIALIZER \ template THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3) : MEMBER(p_param1,p_param2,p_param3) INITIALIZER \ template THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4) : MEMBER(p_param1,p_param2,p_param3,p_param4) INITIALIZER \ template THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4,const t_param5 & p_param5) : MEMBER(p_param1,p_param2,p_param3,p_param4,p_param5) INITIALIZER \ template THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4,const t_param5 & p_param5,const t_param6 & p_param6) : MEMBER(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6) INITIALIZER \ template THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4,const t_param5 & p_param5,const t_param6 & p_param6,const t_param7 & p_param7) : MEMBER(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6,p_param7) INITIALIZER \ template THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4,const t_param5 & p_param5,const t_param6 & p_param6,const t_param7 & p_param7, const t_param8 & p_param8) : MEMBER(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6,p_param7, p_param8) INITIALIZER #define TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(THISCLASS,MEMBER) TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(THISCLASS,MEMBER,{}) #ifdef _WIN32 #ifndef _MSC_VER #error MSVC expected #endif // MSVC specific - part of fb2k ABI - cannot ever change on MSVC/Windows #define PFC_DECLARE_EXCEPTION(NAME,BASECLASS,DEFAULTMSG) \ class NAME : public BASECLASS { \ public: \ static const char * g_what() {return DEFAULTMSG;} \ NAME() : BASECLASS(DEFAULTMSG,0) {} \ NAME(const char * p_msg) : BASECLASS(p_msg) {} \ NAME(const char * p_msg,int) : BASECLASS(p_msg,0) {} \ NAME(const NAME & p_source) : BASECLASS(p_source) {} \ }; namespace pfc { template PFC_NORETURN inline void throw_exception_with_message(const char * p_message) { throw t_exception(p_message); } } #else #define PFC_DECLARE_EXCEPTION(NAME,BASECLASS,DEFAULTMSG) \ class NAME : public BASECLASS { \ public: \ static const char * g_what() {return DEFAULTMSG;} \ const char* what() const throw() {return DEFAULTMSG;} \ }; namespace pfc { template class __exception_with_message_t : public t_base { private: typedef __exception_with_message_t t_self; public: __exception_with_message_t(const char * p_message) : m_message(NULL) { set_message(p_message); } __exception_with_message_t() : m_message(NULL) {} __exception_with_message_t(const t_self & p_source) : m_message(NULL) {set_message(p_source.m_message);} const char* what() const throw() {return m_message != NULL ? m_message : "unnamed exception";} const t_self & operator=(const t_self & p_source) {set_message(p_source.m_message);} ~__exception_with_message_t() throw() {cleanup();} private: void set_message(const char * p_message) throw() { cleanup(); if (p_message != NULL) m_message = strdup(p_message); } void cleanup() throw() { if (m_message != NULL) {free(m_message); m_message = NULL;} } char * m_message; }; template PFC_NORETURN void throw_exception_with_message(const char * p_message) { throw __exception_with_message_t(p_message); } } #endif namespace pfc { template class assert_same_type; template class assert_same_type {}; template class is_same_type { public: enum {value = false}; }; template class is_same_type { public: enum {value = true}; }; template class static_assert_t; template<> class static_assert_t {}; #define PFC_STATIC_ASSERT(X) { ::pfc::static_assert_t<(X)>(); } template void assert_raw_type() {static_assert_t< !traits_t::needs_constructor && !traits_t::needs_destructor >();} template class assert_byte_type; template<> class assert_byte_type {}; template<> class assert_byte_type {}; template<> class assert_byte_type {}; template void __unsafe__memcpy_t(t_type * p_dst,const t_type * p_src,t_size p_count) { ::memcpy(reinterpret_cast(p_dst), reinterpret_cast(p_src), p_count * sizeof(t_type)); } template void __unsafe__in_place_destructor_t(t_type & p_item) throw() { if (traits_t::needs_destructor) try{ p_item.~t_type(); } catch(...) {} } template void __unsafe__in_place_constructor_t(t_type & p_item) { if (traits_t::needs_constructor) { t_type * ret = new(&p_item) t_type; PFC_ASSERT(ret == &p_item); (void) ret; // suppress warning } } template void __unsafe__in_place_destructor_array_t(t_type * p_items, t_size p_count) throw() { if (traits_t::needs_destructor) { t_type * walk = p_items; for(t_size n=p_count;n;--n) __unsafe__in_place_destructor_t(*(walk++)); } } template t_type * __unsafe__in_place_constructor_array_t(t_type * p_items,t_size p_count) { if (traits_t::needs_constructor) { t_size walkptr = 0; try { for(walkptr=0;walkptr t_type * __unsafe__in_place_resize_array_t(t_type * p_items,t_size p_from,t_size p_to) { if (p_from < p_to) __unsafe__in_place_constructor_array_t(p_items + p_from, p_to - p_from); else if (p_from > p_to) __unsafe__in_place_destructor_array_t(p_items + p_to, p_from - p_to); return p_items; } template void __unsafe__in_place_constructor_copy_t(t_type & p_item,const t_copy & p_copyfrom) { if (traits_t::needs_constructor) { t_type * ret = new(&p_item) t_type(p_copyfrom); PFC_ASSERT(ret == &p_item); (void) ret; // suppress warning } else { p_item = p_copyfrom; } } template t_type * __unsafe__in_place_constructor_array_copy_t(t_type * p_items,t_size p_count, const t_copy * p_copyfrom) { t_size walkptr = 0; try { for(walkptr=0;walkptr t_type * __unsafe__in_place_constructor_array_copy_partial_t(t_type * p_items,t_size p_count, const t_copy * p_copyfrom,t_size p_copyfrom_count) { if (p_copyfrom_count > p_count) p_copyfrom_count = p_count; __unsafe__in_place_constructor_array_copy_t(p_items,p_copyfrom_count,p_copyfrom); try { __unsafe__in_place_constructor_array_t(p_items + p_copyfrom_count,p_count - p_copyfrom_count); } catch(...) { __unsafe__in_place_destructor_array_t(p_items,p_copyfrom_count); throw; } return p_items; } template t_ret implicit_cast(t_ret val) {return val;} template t_ret * safe_ptr_cast(t_param * p_param) { if (pfc::is_same_type::value) return p_param; else { if (p_param == NULL) return NULL; else return p_param; } } typedef std::exception exception; PFC_DECLARE_EXCEPTION(exception_overflow,exception,"Overflow"); PFC_DECLARE_EXCEPTION(exception_bug_check,exception,"Bug check"); PFC_DECLARE_EXCEPTION(exception_invalid_params,exception_bug_check,"Invalid parameters"); PFC_DECLARE_EXCEPTION(exception_unexpected_recursion,exception_bug_check,"Unexpected recursion"); PFC_DECLARE_EXCEPTION(exception_not_implemented,exception_bug_check,"Feature not implemented"); PFC_DECLARE_EXCEPTION(exception_dynamic_assert,exception_bug_check,"dynamic_assert failure"); template t_ret downcast_guarded(const t_param & p_param) { t_ret temp = (t_ret) p_param; if ((t_param) temp != p_param) throw exception_overflow(); return temp; } template t_ret downcast_guarded_ex(const t_param & p_param) { t_ret temp = (t_ret) p_param; if ((t_param) temp != p_param) throw t_exception(); return temp; } template void accumulate_guarded(t_acc & p_acc, const t_add & p_add) { t_acc delta = downcast_guarded(p_add); delta += p_acc; if (delta < p_acc) throw exception_overflow(); p_acc = delta; } //deprecated inline void bug_check_assert(bool p_condition, const char * p_msg) { if (!p_condition) { PFC_ASSERT(0); throw_exception_with_message(p_msg); } } //deprecated inline void bug_check_assert(bool p_condition) { if (!p_condition) { PFC_ASSERT(0); throw exception_bug_check(); } } inline void dynamic_assert(bool p_condition, const char * p_msg) { if (!p_condition) { PFC_ASSERT(0); throw_exception_with_message(p_msg); } } inline void dynamic_assert(bool p_condition) { if (!p_condition) { PFC_ASSERT(0); throw exception_dynamic_assert(); } } template inline void swap_multi_t(T * p_buffer1,T * p_buffer2,t_size p_size) { T * walk1 = p_buffer1, * walk2 = p_buffer2; for(t_size n=p_size;n;--n) { T temp (* walk1); *walk1 = *walk2; *walk2 = temp; walk1++; walk2++; } } template inline void swap_multi_t(T * p_buffer1,T * p_buffer2) { T * walk1 = p_buffer1, * walk2 = p_buffer2; for(t_size n=p_size;n;--n) { T temp (* walk1); *walk1 = *walk2; *walk2 = temp; walk1++; walk2++; } } template inline void __unsafe__swap_raw_t(void * p_object1, void * p_object2) { if (p_size % sizeof(t_size) == 0) { swap_multi_t(reinterpret_cast(p_object1),reinterpret_cast(p_object2)); } else { swap_multi_t(reinterpret_cast(p_object1),reinterpret_cast(p_object2)); } } template inline void swap_t(T & p_item1, T & p_item2) { if (traits_t::realloc_safe) { __unsafe__swap_raw_t( reinterpret_cast( &p_item1 ), reinterpret_cast( &p_item2 ) ); } else { T temp( std::move(p_item2) ); p_item2 = std::move(p_item1); p_item1 = std::move(temp); } } //! This is similar to plain p_item1 = p_item2; assignment, but optimized for the case where p_item2 content is no longer needed later on. This can be overridden for specific classes for optimal performance. \n //! p_item2 value is undefined after performing a move_t. For an example, in certain cases move_t will fall back to swap_t. template inline void move_t(T & p_item1, T & p_item2) { typedef traits_t t; if (t::needs_constructor || t::needs_destructor) { if (t::realloc_safe) swap_t(p_item1, p_item2); else p_item1 = std::move( p_item2 ); } else { p_item1 = std::move( p_item2 ); } } template t_size array_size_t(const t_array & p_array) {return p_array.get_size();} template t_size array_size_t(const t_item (&p_array)[p_width]) {return p_width;} template static bool array_isLast(const t_array & arr, const t_item & item) { const t_size size = pfc::array_size_t(arr); return size > 0 && arr[size-1] == item; } template static bool array_isFirst(const t_array & arr, const t_item & item) { const t_size size = pfc::array_size_t(arr); return size > 0 && arr[0] == item; } template inline void fill_t(t_array & p_buffer,const t_size p_count, const t_filler & p_filler) { for(t_size n=0;n inline void fill_ptr_t(t_array * p_buffer,const t_size p_count, const t_filler & p_filler) { for(t_size n=0;n inline int compare_t(const t_item1 & p_item1, const t_item2 & p_item2) { if (p_item1 < p_item2) return -1; else if (p_item1 > p_item2) return 1; else return 0; } //! For use with avltree/map etc. class comparator_default { public: template inline static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {return pfc::compare_t(p_item1,p_item2);} }; template class comparator_pointer { public: template static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {return t_comparator::compare(*p_item1,*p_item2);} }; template class comparator_dual { public: template static int compare(const t_item1 & p_item1,const t_item2 & p_item2) { int state = t_primary::compare(p_item1,p_item2); if (state != 0) return state; return t_secondary::compare(p_item1,p_item2); } }; class comparator_memcmp { public: template inline static int compare(const t_item1 & p_item1,const t_item2 & p_item2) { static_assert_t(); return memcmp(&p_item1,&p_item2,sizeof(t_item1)); } }; template t_size subtract_sorted_lists_calculate_count(const t_source1 & p_source1, const t_source2 & p_source2) { t_size walk1 = 0, walk2 = 0, walk_out = 0; const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size(); for(;;) { int state; if (walk1 < max1 && walk2 < max2) { state = pfc::compare_t(p_source1[walk1],p_source2[walk2]); } else if (walk1 < max1) { state = -1; } else if (walk2 < max2) { state = 1; } else { break; } if (state < 0) walk_out++; if (state <= 0) walk1++; if (state >= 0) walk2++; } return walk_out; } //! Subtracts p_source2 contents from p_source1 and stores result in p_destination. Both source lists must be sorted. //! Note: duplicates will be carried over (and ignored for p_source2). template void subtract_sorted_lists(t_destination & p_destination,const t_source1 & p_source1, const t_source2 & p_source2) { p_destination.set_size(subtract_sorted_lists_calculate_count(p_source1,p_source2)); t_size walk1 = 0, walk2 = 0, walk_out = 0; const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size(); for(;;) { int state; if (walk1 < max1 && walk2 < max2) { state = pfc::compare_t(p_source1[walk1],p_source2[walk2]); } else if (walk1 < max1) { state = -1; } else if (walk2 < max2) { state = 1; } else { break; } if (state < 0) p_destination[walk_out++] = p_source1[walk1]; if (state <= 0) walk1++; if (state >= 0) walk2++; } } template t_size merge_sorted_lists_calculate_count(const t_source1 & p_source1, const t_source2 & p_source2) { t_size walk1 = 0, walk2 = 0, walk_out = 0; const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size(); for(;;) { int state; if (walk1 < max1 && walk2 < max2) { state = pfc::compare_t(p_source1[walk1],p_source2[walk2]); } else if (walk1 < max1) { state = -1; } else if (walk2 < max2) { state = 1; } else { break; } if (state <= 0) walk1++; if (state >= 0) walk2++; walk_out++; } return walk_out; } //! Merges p_source1 and p_source2, storing content in p_destination. Both source lists must be sorted. //! Note: duplicates will be carried over. template void merge_sorted_lists(t_destination & p_destination,const t_source1 & p_source1, const t_source2 & p_source2) { p_destination.set_size(merge_sorted_lists_calculate_count(p_source1,p_source2)); t_size walk1 = 0, walk2 = 0, walk_out = 0; const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size(); for(;;) { int state; if (walk1 < max1 && walk2 < max2) { state = pfc::compare_t(p_source1[walk1],p_source2[walk2]); } else if (walk1 < max1) { state = -1; } else if (walk2 < max2) { state = 1; } else { break; } if (state < 0) { p_destination[walk_out] = p_source1[walk1++]; } else if (state > 0) { p_destination[walk_out] = p_source2[walk2++]; } else { p_destination[walk_out] = p_source1[walk1]; walk1++; walk2++; } walk_out++; } } template inline t_size append_t(t_array & p_array,const T & p_item) { t_size old_count = p_array.get_size(); p_array.set_size(old_count + 1); p_array[old_count] = p_item; return old_count; } template inline t_size append_swap_t(t_array & p_array,T & p_item) { t_size old_count = p_array.get_size(); p_array.set_size(old_count + 1); swap_t(p_array[old_count],p_item); return old_count; } template inline t_size insert_uninitialized_t(t_array & p_array,t_size p_index) { t_size old_count = p_array.get_size(); if (p_index > old_count) p_index = old_count; p_array.set_size(old_count + 1); for(t_size n=old_count;n>p_index;n--) move_t(p_array[n], p_array[n-1]); return p_index; } template inline t_size insert_t(t_array & p_array,const T & p_item,t_size p_index) { t_size old_count = p_array.get_size(); if (p_index > old_count) p_index = old_count; p_array.set_size(old_count + 1); for(t_size n=old_count;n>p_index;n--) move_t(p_array[n], p_array[n-1]); p_array[p_index] = p_item; return p_index; } template void insert_array_t( array1_t & outArray, size_t insertAt, array2_t const & inArray, size_t inArraySize) { const size_t oldSize = outArray.get_size(); if (insertAt > oldSize) insertAt = oldSize; const size_t newSize = oldSize + inArraySize; outArray.set_size( newSize ); for(size_t m = oldSize; m != insertAt; --m) { move_t( outArray[ m - 1 + inArraySize], outArray[m - 1] ); } for(size_t w = 0; w < inArraySize; ++w) { outArray[ insertAt + w ] = inArray[ w ]; } } template inline t_size insert_multi_t(t_array & p_array,const in_array_t & p_items, size_t p_itemCount, t_size p_index) { const t_size old_count = p_array.get_size(); const size_t new_count = old_count + p_itemCount; if (p_index > old_count) p_index = old_count; p_array.set_size(new_count); size_t toMove = old_count - p_index; for(size_t w = 0; w < toMove; ++w) { move_t( p_array[new_count - 1 - w], p_array[old_count - 1 - w] ); } for(size_t w = 0; w < p_itemCount; ++w) { p_array[p_index+w] = p_items[w]; } return p_index; } template inline t_size insert_swap_t(t_array & p_array,T & p_item,t_size p_index) { t_size old_count = p_array.get_size(); if (p_index > old_count) p_index = old_count; p_array.set_size(old_count + 1); for(t_size n=old_count;n>p_index;n--) swap_t(p_array[n],p_array[n-1]); swap_t(p_array[p_index],p_item); return p_index; } template inline T max_t(const T & item1, const T & item2) {return item1 > item2 ? item1 : item2;}; template inline T min_t(const T & item1, const T & item2) {return item1 < item2 ? item1 : item2;}; template inline T abs_t(T item) {return item<0 ? -item : item;} template inline T sqr_t(T item) {return item * item;} template inline T clip_t(const T & p_item, const T & p_min, const T & p_max) { if (p_item < p_min) return p_min; else if (p_item <= p_max) return p_item; else return p_max; } template inline void delete_t(T* ptr) {delete ptr;} template inline void delete_array_t(T* ptr) {delete[] ptr;} template inline T* clone_t(T* ptr) {return new T(*ptr);} template inline t_int mul_safe_t(t_int p_val1,t_int p_val2) { if (p_val1 == 0 || p_val2 == 0) return 0; t_int temp = (t_int) (p_val1 * p_val2); if (temp / p_val1 != p_val2) throw t_exception(); return temp; } template t_int multiply_guarded(t_int v1, t_int v2) { return mul_safe_t(v1, v2); } template t_int add_unsigned_clipped(t_int v1, t_int v2) { t_int v = v1 + v2; if (v < v1) return ~0; return v; } template t_int sub_unsigned_clipped(t_int v1, t_int v2) { t_int v = v1 - v2; if (v > v1) return 0; return v; } template void acc_unsigned_clipped(t_int & v1, t_int v2) { v1 = add_unsigned_clipped(v1, v2); } template void memcpy_t(t_dst* p_dst,const t_src* p_src,t_size p_count) { for(t_size n=0;n void copy_array_loop_t(t_dst & p_dst,const t_src & p_src,t_size p_count) { for(t_size n=0;n void memcpy_backwards_t(t_dst * p_dst,const t_src * p_src,t_size p_count) { p_dst += p_count; p_src += p_count; for(t_size n=0;n void memset_t(T * p_buffer,const t_val & p_val,t_size p_count) { for(t_size n=0;n void memset_t(T &p_buffer,const t_val & p_val) { const t_size width = pfc::array_size_t(p_buffer); for(t_size n=0;n void memset_null_t(T * p_buffer,t_size p_count) { for(t_size n=0;n void memset_null_t(T &p_buffer) { const t_size width = pfc::array_size_t(p_buffer); for(t_size n=0;n void memmove_t(T* p_dst,const T* p_src,t_size p_count) { if (p_dst == p_src) {/*do nothing*/} else if (p_dst > p_src && p_dst < p_src + p_count) memcpy_backwards_t(p_dst,p_src,p_count); else memcpy_t(p_dst,p_src,p_count); } template void memxor_t(TVal * out, const TVal * s1, const TVal * s2, t_size count) { for(t_size walk = 0; walk < count; ++walk) out[walk] = s1[walk] ^ s2[walk]; } static void memxor(void * target, const void * source1, const void * source2, t_size size) { memxor_t( reinterpret_cast(target), reinterpret_cast(source1), reinterpret_cast(source2), size); } template T* new_ptr_check_t(T* p_ptr) { if (p_ptr == NULL) throw std::bad_alloc(); return p_ptr; } template int sgn_t(const T & p_val) { if (p_val < 0) return -1; else if (p_val > 0) return 1; else return 0; } template const T* empty_string_t(); template<> inline const char * empty_string_t() {return "";} template<> inline const wchar_t * empty_string_t() {return L"";} template t_type replace_t(t_type & p_var,const t_newval & p_newval) { t_type oldval = p_var; p_var = p_newval; return oldval; } template t_type replace_null_t(t_type & p_var) { t_type ret = p_var; p_var = 0; return ret; } template inline bool is_ptr_aligned_t(const void * p_ptr) { static_assert_t< (p_size_pow2 & (p_size_pow2 - 1)) == 0 >(); return ( ((t_size)p_ptr) & (p_size_pow2-1) ) == 0; } template void array_rangecheck_t(const t_array & p_array,t_size p_index) { if (p_index >= pfc::array_size_t(p_array)) throw pfc::exception_overflow(); } template void array_rangecheck_t(const t_array & p_array,t_size p_from,t_size p_to) { if (p_from > p_to) throw pfc::exception_overflow(); array_rangecheck_t(p_array,p_from); array_rangecheck_t(p_array,p_to); } t_int32 rint32(double p_val); t_int64 rint64(double p_val); template inline size_t remove_if_t( array_t & arr, pred_t pred ) { const size_t inCount = arr.size(); size_t walk = 0; for( walk = 0; walk < inCount; ++ walk ) { if ( pred(arr[walk]) ) break; } size_t total = walk; for( ; walk < inCount; ++ walk ) { if ( !pred(arr[walk] ) ) { move_t(arr[total++], arr[walk]); } } arr.resize(total); return total; } template inline t_size remove_mask_t(t_array & p_array,const bit_array & p_mask)//returns amount of items left { t_size n,count = p_array.size(), total = 0; n = total = p_mask.find(true,0,count); if (n t_size find_duplicates_sorted_t(t_array p_array,t_size p_count,t_compare p_compare,bit_array_var & p_out) { t_size ret = 0; t_size n; if (p_count > 0) { p_out.set(0,false); for(n=1;n t_size find_duplicates_sorted_permutation_t(t_array p_array,t_size p_count,t_compare p_compare,t_permutation const & p_permutation,bit_array_var & p_out) { t_size ret = 0; t_size n; if (p_count > 0) { p_out.set(p_permutation[0],false); for(n=1;n t_size strlen_t(const t_char * p_string,t_size p_length = ~0) { for(t_size walk = 0;;walk++) { if (walk >= p_length || p_string[walk] == 0) return walk; } } template class __list_to_array_enumerator { public: __list_to_array_enumerator(t_array & p_array) : m_walk(), m_array(p_array) {} template void operator() (const t_item & p_item) { PFC_ASSERT(m_walk < m_array.get_size()); m_array[m_walk++] = p_item; } void finalize() { PFC_ASSERT(m_walk == m_array.get_size()); } private: t_size m_walk; t_array & m_array; }; template void list_to_array(t_array & p_array,const t_list & p_list) { p_array.set_size(p_list.get_count()); __list_to_array_enumerator enumerator(p_array); p_list.enumerate(enumerator); enumerator.finalize(); } template class enumerator_add_item { public: enumerator_add_item(t_receiver & p_receiver) : m_receiver(p_receiver) {} template void operator() (const t_item & p_item) {m_receiver.add_item(p_item);} private: t_receiver & m_receiver; }; template void overwrite_list_enumerated(t_receiver & p_receiver,const t_giver & p_giver) { enumerator_add_item wrapper(p_receiver); p_giver.enumerate(wrapper); } template void copy_list_enumerated(t_receiver & p_receiver,const t_giver & p_giver) { p_receiver.remove_all(); overwrite_list_enumerated(p_receiver,p_giver); } inline bool lxor(bool p_val1,bool p_val2) { return p_val1 == !p_val2; } template inline void min_acc(t_val & p_acc,const t_val & p_val) { if (p_val < p_acc) p_acc = p_val; } template inline void max_acc(t_val & p_acc,const t_val & p_val) { if (p_val > p_acc) p_acc = p_val; } t_uint64 pow_int(t_uint64 base, t_uint64 exp); template class incrementScope { public: incrementScope(t_val & i) : v(i) {++v;} ~incrementScope() {--v;} private: t_val & v; }; inline unsigned countBits32(uint32_t i) { const uint32_t mask = 0x11111111; uint32_t acc = i & mask; acc += (i >> 1) & mask; acc += (i >> 2) & mask; acc += (i >> 3) & mask; const uint32_t mask2 = 0x0F0F0F0F; uint32_t acc2 = acc & mask2; acc2 += (acc >> 4) & mask2; const uint32_t mask3 = 0x00FF00FF; uint32_t acc3 = acc2 & mask3; acc3 += (acc2 >> 8) & mask3; return (acc3 & 0xFFFF) + ((acc3 >> 16) & 0xFFFF); } // Forward declarations template void copy_array_t(t_to & p_to,const t_from & p_from); template void fill_array_t(t_array & p_array,const t_value & p_value); // Generic no-op for breakpointing stuff inline void nop() {} class onLeaving { public: onLeaving() {} onLeaving( std::function f_ ) : f(f_) {} ~onLeaving() { if (f) f(); } std::function f; private: void operator=( onLeaving const & ) = delete; onLeaving( const onLeaving & ) = delete; }; template class singleton { public: static obj_t instance; }; template obj_t singleton::instance; }; #define PFC_SINGLETON(X) ::pfc::singleton::instance #define PFC_CLASS_NOT_COPYABLE(THISCLASSNAME,THISTYPE) \ private: \ THISCLASSNAME(const THISTYPE&) = delete; \ const THISTYPE & operator=(const THISTYPE &) = delete; #define PFC_CLASS_NOT_COPYABLE_EX(THISTYPE) PFC_CLASS_NOT_COPYABLE(THISTYPE,THISTYPE)