primitives.h

Go to the documentation of this file.
00001 #define tabsize(x) ((size_t)(sizeof(x)/sizeof(*x)))
00002 #define PFC_TABSIZE(x) ((size_t)(sizeof(x)/sizeof(*x)))
00003 
00004 #define TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(THISCLASS,MEMBER,INITIALIZER)       \
00005                                                                                                                                                                                                                                                                                                 THISCLASS() :                                                                                                                                                                                                                                                                                                                                                                           MEMBER() INITIALIZER    \
00006         template<typename t_param1>                                                                                                                                                                                                                                     THISCLASS(const t_param1 & p_param1) :                                                                                                                                                                                                                                                                                                                          MEMBER(p_param1) INITIALIZER    \
00007         template<typename t_param1,typename t_param2>                                                                                                                                                                                           THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2) :                                                                                                                                                                                                                                                                        MEMBER(p_param1,p_param2) INITIALIZER   \
00008         template<typename t_param1,typename t_param2,typename t_param3>                                                                                                                                                         THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3) :                                                                                                                                                                                                                      MEMBER(p_param1,p_param2,p_param3) INITIALIZER  \
00009         template<typename t_param1,typename t_param2,typename t_param3,typename t_param4>                                                                                                                       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 \
00010         template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5>                                                                                     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        \
00011         template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5,typename t_param6>                                           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       \
00012         template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5,typename t_param6, typename t_param7>        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
00013 
00014 #define TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(THISCLASS,MEMBER) TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(THISCLASS,MEMBER,{})
00015 
00016 
00017 #ifdef _MSC_VER
00018 
00019 //Bah. I noticed the fact that std::exception carrying a custom message is MS-specific *after* making exception classes a part of ABI. To be nuked next time fb2k component backwards compatibility is axed.
00020 
00021 #define PFC_DECLARE_EXCEPTION(NAME,BASECLASS,DEFAULTMSG)        \
00022 class NAME : public BASECLASS { \
00023 public: \
00024         static const char * g_what() {return DEFAULTMSG;}       \
00025         NAME() : BASECLASS(DEFAULTMSG,0) {}     \
00026         NAME(const char * p_msg) : BASECLASS(p_msg) {}  \
00027         NAME(const char * p_msg,int) : BASECLASS(p_msg,0) {}    \
00028         NAME(const NAME & p_source) : BASECLASS(p_source) {}    \
00029 };
00030 
00031 namespace pfc {
00032         template<typename t_exception> inline void throw_exception_with_message(const char * p_message) {
00033                 throw t_exception(p_message);
00034         }
00035 }
00036 
00037 #else
00038 
00039 #define PFC_DECLARE_EXCEPTION(NAME,BASECLASS,DEFAULTMSG)        \
00040 class NAME : public BASECLASS { \
00041 public: \
00042         static const char * g_what() {return DEFAULTMSG;}       \
00043         const char* what() const throw() {return DEFAULTMSG;}   \
00044 };
00045 
00046 namespace pfc {
00047         template<typename t_base> class __exception_with_message_t : public t_base {
00048         private:        typedef __exception_with_message_t<t_base> t_self;
00049         public:
00050                 __exception_with_message_t(const char * p_message) : m_message(NULL) {
00051                         set_message(p_message);                 
00052                 }
00053                 __exception_with_message_t() : m_message(NULL) {}
00054                 __exception_with_message_t(const t_self & p_source) : m_message(NULL) {set_message(p_source.m_message);}
00055 
00056                 const char* what() const throw() {return m_message != NULL ? m_message : "unnamed exception";}
00057 
00058                 const t_self & operator=(const t_self & p_source) {set_message(p_source.m_message);}
00059 
00060                 ~__exception_with_message_t() throw() {cleanup();}
00061 
00062         private:
00063                 void set_message(const char * p_message) throw() {
00064                         cleanup();
00065                         if (p_message != NULL) m_message = strdup(p_message);
00066                 }
00067                 void cleanup() throw() {
00068                         if (m_message != NULL) {free(m_message); m_message = NULL;}
00069                 }
00070                 char * m_message;
00071         };
00072         template<typename t_exception> void throw_exception_with_message(const char * p_message) {
00073                 throw __exception_with_message_t<t_exception>(p_message);
00074         }
00075 }
00076 #endif
00077 
00078 namespace pfc {
00079 
00080         template<typename p_type1,typename p_type2> class assert_same_type;
00081         template<typename p_type> class assert_same_type<p_type,p_type> {};
00082 
00083         template<typename p_type1,typename p_type2>
00084         class is_same_type { public: enum {value = false}; };
00085 
00086         template<typename p_type>
00087         class is_same_type<p_type,p_type> { public: enum {value = true}; };
00088 
00089         template<bool val> class static_assert;
00090         template<> class static_assert<true> {};
00091 
00092         template<bool val> class static_assert_t;
00093         template<> class static_assert_t<true> {};
00094 
00095 #define PFC_STATIC_ASSERT(X) { pfc::static_assert<(X)>(); }
00096 
00097         template<typename t_type>
00098         void assert_raw_type() {static_assert< !traits_t<t_type>::needs_constructor && !traits_t<t_type>::needs_destructor >();}
00099 
00100         template<typename t_type> class assert_byte_type;
00101         template<> class assert_byte_type<t_uint8> {};
00102         template<> class assert_byte_type<t_int8> {};
00103 
00104 
00105         template<typename t_type> void __unsafe__memcpy_t(t_type * p_dst,const t_type * p_src,t_size p_count) {
00106                 ::memcpy(reinterpret_cast<void*>(p_dst), reinterpret_cast<const void*>(p_src), p_count * sizeof(t_type));
00107         }
00108 
00109         template<typename t_type> void __unsafe__in_place_destructor_t(t_type & p_item) throw() {
00110                 if (traits_t<t_type>::needs_destructor) try{ p_item.~t_type(); } catch(...) {}
00111         }
00112         
00113         template<typename t_type> void __unsafe__in_place_constructor_t(t_type & p_item) {
00114                 if (traits_t<t_type>::needs_constructor) {
00115                         t_type * ret = new(&p_item) t_type;
00116                         PFC_ASSERT(ret == &p_item);
00117                 }
00118         }
00119 
00120         template<typename t_type> void __unsafe__in_place_destructor_array_t(t_type * p_items, t_size p_count) throw() {
00121                 if (traits_t<t_type>::needs_destructor) {
00122                         t_type * walk = p_items;
00123                         for(t_size n=p_count;n;--n) __unsafe__in_place_destructor_t(*(walk++));
00124                 }
00125         }
00126         
00127         template<typename t_type> t_type * __unsafe__in_place_constructor_array_t(t_type * p_items,t_size p_count) {
00128                 if (traits_t<t_type>::needs_constructor) {
00129                         t_size walkptr = 0;
00130                         try {
00131                                 for(walkptr=0;walkptr<p_count;++walkptr) __unsafe__in_place_constructor_t(p_items[walkptr]);
00132                         } catch(...) {
00133                                 __unsafe__in_place_destructor_array_t(p_items,walkptr);
00134                                 throw;
00135                         }
00136                 }
00137                 return p_items;
00138         }
00139 
00140         template<typename t_type> t_type * __unsafe__in_place_resize_array_t(t_type * p_items,t_size p_from,t_size p_to) {
00141                 if (p_from < p_to) __unsafe__in_place_constructor_array_t(p_items + p_from, p_to - p_from);
00142                 else if (p_from > p_to) __unsafe__in_place_destructor_array_t(p_items + p_to, p_from - p_to);
00143                 return p_items;
00144         }
00145 
00146         template<typename t_type,typename t_copy> void __unsafe__in_place_constructor_copy_t(t_type & p_item,const t_copy & p_copyfrom) {
00147                 if (traits_t<t_type>::needs_constructor) {
00148                         t_type * ret = new(&p_item) t_type(p_copyfrom);
00149                         PFC_ASSERT(ret == &p_item);
00150                 } else {
00151                         p_item = p_copyfrom;
00152                 }
00153         }
00154 
00155         template<typename t_type,typename t_copy> t_type * __unsafe__in_place_constructor_array_copy_t(t_type * p_items,t_size p_count, const t_copy * p_copyfrom) {
00156                 t_size walkptr = 0;
00157                 try {
00158                         for(walkptr=0;walkptr<p_count;++walkptr) __unsafe__in_place_constructor_copy_t(p_items[walkptr],p_copyfrom[walkptr]);
00159                 } catch(...) {
00160                         __unsafe__in_place_destructor_array_t(p_items,walkptr);
00161                         throw;
00162                 }
00163                 return p_items;
00164         }
00165 
00166         template<typename t_type,typename t_copy> 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) {
00167                 if (p_copyfrom_count > p_count) p_copyfrom_count = p_count;
00168                 __unsafe__in_place_constructor_array_copy_t(p_items,p_copyfrom_count,p_copyfrom);
00169                 try {
00170                         __unsafe__in_place_constructor_array_t(p_items + p_copyfrom_count,p_count - p_copyfrom_count);
00171                 } catch(...) {
00172                         __unsafe__in_place_destructor_array_t(p_items,p_copyfrom_count);
00173                         throw;
00174                 }
00175                 return p_items;
00176         }
00177 
00178         template<typename t_ret> inline t_ret safe_cast(t_ret val) {return val;}
00179 
00180         template<typename t_ret,typename t_param>
00181         t_ret * safe_ptr_cast(t_param * p_param) {
00182                 if (pfc::is_same_type<t_ret,t_param>::value) return p_param;
00183                 else {
00184                         if (p_param == NULL) return NULL;
00185                         else return p_param;
00186                 }
00187         }
00188 
00189         typedef std::exception exception;
00190 
00191         PFC_DECLARE_EXCEPTION(exception_overflow,exception,"Overflow");
00192         PFC_DECLARE_EXCEPTION(exception_bug_check,exception,"Bug check");
00193         PFC_DECLARE_EXCEPTION(exception_invalid_params,exception_bug_check,"Invalid parameters");
00194         PFC_DECLARE_EXCEPTION(exception_unexpected_recursion,exception_bug_check,"Unexpected recursion");
00195         PFC_DECLARE_EXCEPTION(exception_not_implemented,exception_bug_check,"Feature not implemented");
00196         PFC_DECLARE_EXCEPTION(exception_dynamic_assert,exception_bug_check,"dynamic_assert failure");
00197 
00198         template<typename t_ret,typename t_param>
00199         t_ret downcast_guarded(const t_param & p_param) {
00200                 t_ret temp = (t_ret) p_param;
00201                 if ((t_param) temp != p_param) throw exception_overflow();
00202                 return temp;
00203         }
00204         
00205         template<typename t_exception,typename t_ret,typename t_param>
00206         t_ret downcast_guarded_ex(const t_param & p_param) {
00207                 t_ret temp = (t_ret) p_param;
00208                 if ((t_param) temp != p_param) throw t_exception();
00209                 return temp;
00210         }
00211 
00212         template<typename t_acc,typename t_add>
00213         void accumulate_guarded(t_acc & p_acc, const t_add & p_add) {
00214                 t_acc delta = downcast_guarded<t_acc>(p_add);
00215                 delta += p_acc;
00216                 if (delta < p_acc) throw exception_overflow();
00217                 p_acc = delta;
00218         }
00219 
00220         //deprecated
00221         inline void bug_check_assert(bool p_condition, const char * p_msg) {
00222                 if (!p_condition) {
00223                         PFC_ASSERT(0);
00224                         throw_exception_with_message<exception_bug_check>(p_msg);
00225                 }
00226         }
00227         //deprecated
00228         inline void bug_check_assert(bool p_condition) {
00229                 if (!p_condition) {
00230                         PFC_ASSERT(0);
00231                         throw exception_bug_check();
00232                 }
00233         }
00234 
00235         inline void dynamic_assert(bool p_condition, const char * p_msg) {
00236                 if (!p_condition) {
00237                         PFC_ASSERT(0);
00238                         throw_exception_with_message<exception_dynamic_assert>(p_msg);
00239                 }
00240         }
00241         inline void dynamic_assert(bool p_condition) {
00242                 if (!p_condition) {
00243                         PFC_ASSERT(0);
00244                         throw exception_dynamic_assert();
00245                 }
00246         }
00247 
00248         template<typename T>
00249         inline void swap_multi_t(T * p_buffer1,T * p_buffer2,t_size p_size) {
00250                 T * walk1 = p_buffer1, * walk2 = p_buffer2;
00251                 for(t_size n=p_size;n;--n) {
00252                         T temp (* walk1);
00253                         *walk1 = *walk2;
00254                         *walk2 = temp;
00255                         walk1++; walk2++;
00256                 }
00257         }
00258 
00259         template<typename T,t_size p_size>
00260         inline void swap_multi_t(T * p_buffer1,T * p_buffer2) {
00261                 T * walk1 = p_buffer1, * walk2 = p_buffer2;
00262                 for(t_size n=p_size;n;--n) {
00263                         T temp (* walk1);
00264                         *walk1 = *walk2;
00265                         *walk2 = temp;
00266                         walk1++; walk2++;
00267                 }
00268         }
00269 
00270 
00271         template<t_size p_size>
00272         inline void __unsafe__swap_raw_t(void * p_object1, void * p_object2) {
00273                 if (p_size % sizeof(t_size) == 0) {
00274                         swap_multi_t<t_size,p_size/sizeof(t_size)>(reinterpret_cast<t_size*>(p_object1),reinterpret_cast<t_size*>(p_object2));
00275                 } else {
00276                         swap_multi_t<t_uint8,p_size>(reinterpret_cast<t_uint8*>(p_object1),reinterpret_cast<t_uint8*>(p_object2));
00277                 }
00278         }
00279 
00280         template<typename T>
00281         inline void swap_t(T & p_item1, T & p_item2) {
00282                 if (traits_t<T>::realloc_safe) {
00283                         __unsafe__swap_raw_t<sizeof(T)>( reinterpret_cast<void*>( &p_item1 ), reinterpret_cast<void*>( &p_item2 ) );
00284                 } else {
00285                         T temp(p_item2);
00286                         p_item2 = p_item1;
00287                         p_item1 = temp;
00288                 }
00289         }
00290 
00291         template<typename t_array>
00292         t_size array_size_t(const t_array & p_array) {return p_array.get_size();}
00293 
00294         template<typename t_item, t_size p_width>
00295         t_size array_size_t(const t_item (&p_array)[p_width]) {return p_width;}
00296 
00297 
00298         template<typename t_array,typename t_filler>
00299         inline void fill_t(t_array & p_buffer,const t_size p_count, const t_filler & p_filler) {
00300                 for(t_size n=0;n<p_count;n++)
00301                         p_buffer[n] = p_filler;
00302         }
00303 
00304         template<typename t_array,typename t_filler>
00305         inline void fill_ptr_t(t_array * p_buffer,const t_size p_count, const t_filler & p_filler) {
00306                 for(t_size n=0;n<p_count;n++)
00307                         p_buffer[n] = p_filler;
00308         }
00309 
00310         template<typename t_item1, typename t_item2>
00311         inline int compare_t(const t_item1 & p_item1, const t_item2 & p_item2) {
00312                 if (p_item1 < p_item2) return -1;
00313                 else if (p_item1 > p_item2) return 1;
00314                 else return 0;
00315         }
00316 
00318         class comparator_default {
00319         public:
00320                 template<typename t_item1,typename t_item2>
00321                 inline static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {return pfc::compare_t(p_item1,p_item2);}
00322         };
00323 
00324         template<typename t_comparator = pfc::comparator_default> class comparator_pointer { public:
00325                 template<typename t_item1,typename t_item2> static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {return t_comparator::compare(*p_item1,*p_item2);}
00326         };
00327 
00328         template<typename t_primary,typename t_secondary> class comparator_dual { public:
00329                 template<typename t_item1,typename t_item2> static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {
00330                         int state = t_primary::compare(p_item1,p_item2);
00331                         if (state != 0) return state;
00332                         return t_secondary::compare(p_item1,p_item2);
00333                 }
00334         };
00335 
00336         class comparator_memcmp {
00337         public:
00338                 template<typename t_item1,typename t_item2>
00339                 inline static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {
00340                         static_assert<sizeof(t_item1) == sizeof(t_item2)>();
00341                         return memcmp(&p_item1,&p_item2,sizeof(t_item1));
00342                 }
00343         };
00344 
00345         template<typename t_source1, typename t_source2>
00346         t_size subtract_sorted_lists_calculate_count(const t_source1 & p_source1, const t_source2 & p_source2) {
00347                 t_size walk1 = 0, walk2 = 0, walk_out = 0;
00348                 const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
00349                 for(;;) {
00350                         int state;
00351                         if (walk1 < max1 && walk2 < max2) {
00352                                 state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
00353                         } else if (walk1 < max1) {
00354                                 state = -1;
00355                         } else if (walk2 < max2) {
00356                                 state = 1;
00357                         } else {
00358                                 break;
00359                         }
00360                         if (state < 0) walk_out++;
00361                         if (state <= 0) walk1++;
00362                         if (state >= 0) walk2++;
00363                 }
00364                 return walk_out;
00365         }
00366 
00369         template<typename t_destination, typename t_source1, typename t_source2>
00370         void subtract_sorted_lists(t_destination & p_destination,const t_source1 & p_source1, const t_source2 & p_source2) {
00371                 p_destination.set_size(subtract_sorted_lists_calculate_count(p_source1,p_source2));
00372                 t_size walk1 = 0, walk2 = 0, walk_out = 0;
00373                 const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
00374                 for(;;) {
00375                         int state;
00376                         if (walk1 < max1 && walk2 < max2) {
00377                                 state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
00378                         } else if (walk1 < max1) {
00379                                 state = -1;
00380                         } else if (walk2 < max2) {
00381                                 state = 1;
00382                         } else {
00383                                 break;
00384                         }
00385                         
00386                         
00387                         if (state < 0) p_destination[walk_out++] = p_source1[walk1];
00388                         if (state <= 0) walk1++;
00389                         if (state >= 0) walk2++;
00390                 }
00391         }
00392 
00393         template<typename t_source1, typename t_source2>
00394         t_size merge_sorted_lists_calculate_count(const t_source1 & p_source1, const t_source2 & p_source2) {
00395                 t_size walk1 = 0, walk2 = 0, walk_out = 0;
00396                 const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
00397                 for(;;) {
00398                         int state;
00399                         if (walk1 < max1 && walk2 < max2) {
00400                                 state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
00401                         } else if (walk1 < max1) {
00402                                 state = -1;
00403                         } else if (walk2 < max2) {
00404                                 state = 1;
00405                         } else {
00406                                 break;
00407                         }
00408                         if (state <= 0) walk1++;
00409                         if (state >= 0) walk2++;
00410                         walk_out++;
00411                 }
00412                 return walk_out;
00413         }
00414 
00417         template<typename t_destination, typename t_source1, typename t_source2>
00418         void merge_sorted_lists(t_destination & p_destination,const t_source1 & p_source1, const t_source2 & p_source2) {
00419                 p_destination.set_size(merge_sorted_lists_calculate_count(p_source1,p_source2));
00420                 t_size walk1 = 0, walk2 = 0, walk_out = 0;
00421                 const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
00422                 for(;;) {
00423                         int state;
00424                         if (walk1 < max1 && walk2 < max2) {
00425                                 state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
00426                         } else if (walk1 < max1) {
00427                                 state = -1;
00428                         } else if (walk2 < max2) {
00429                                 state = 1;
00430                         } else {
00431                                 break;
00432                         }
00433                         if (state < 0) {
00434                                 p_destination[walk_out] = p_source1[walk1++];
00435                         } else if (state > 0) {
00436                                 p_destination[walk_out] = p_source2[walk2++];
00437                         } else {
00438                                 p_destination[walk_out] = p_source1[walk1];
00439                                 walk1++; walk2++;
00440                         }
00441                         walk_out++;
00442                 }
00443         }
00444 
00445         
00446 
00447         template<typename t_array,typename T>
00448         inline t_size append_t(t_array & p_array,const T & p_item)
00449         {
00450                 t_size old_count = p_array.get_size();
00451                 p_array.set_size(old_count + 1);
00452                 p_array[old_count] = p_item;
00453                 return old_count;
00454         }
00455 
00456         template<typename t_array,typename T>
00457         inline t_size append_swap_t(t_array & p_array,T & p_item)
00458         {
00459                 t_size old_count = p_array.get_size();
00460                 p_array.set_size(old_count + 1);
00461                 swap_t(p_array[old_count],p_item);
00462                 return old_count;
00463         }
00464 
00465         template<typename t_array,typename T>
00466         inline t_size insert_t(t_array & p_array,const T & p_item,t_size p_index)
00467         {
00468                 t_size old_count = p_array.get_size();
00469                 if (p_index > old_count) p_index = old_count;
00470                 p_array.set_size(old_count + 1);
00471                 for(t_size n=old_count;n>p_index;n--)
00472                         p_array[n] = p_array[n-1];
00473                 p_array[p_index] = p_item;
00474                 return p_index;
00475         }
00476         template<typename t_array>
00477         inline t_size insert_default_t(t_array & p_array,t_size p_index)
00478         {
00479                 t_size old_count = p_array.get_size();
00480                 if (p_index > old_count) p_index = old_count;
00481                 p_array.set_size(old_count + 1);
00482                 for(t_size n=old_count;n>p_index;n--)
00483                         p_array[n] = p_array[n-1];
00484                 /*p_array[p_index] = p_item;*/
00485                 return p_index;
00486         }
00487 
00488         template<typename t_array,typename T>
00489         inline t_size insert_swap_t(t_array & p_array,T & p_item,t_size p_index)
00490         {
00491                 t_size old_count = p_array.get_size();
00492                 if (p_index > old_count) p_index = old_count;
00493                 p_array.set_size(old_count + 1);
00494                 for(t_size n=old_count;n>p_index;n--)
00495                         swap_t(p_array[n],p_array[n-1]);
00496                 swap_t(p_array[p_index],p_item);
00497                 return p_index;
00498         }
00499 
00500         
00501         template<typename T>
00502         inline T max_t(const T & item1, const T & item2) {return item1 > item2 ? item1 : item2;};
00503 
00504         template<typename T>
00505         inline T min_t(const T & item1, const T & item2) {return item1 < item2 ? item1 : item2;};
00506 
00507         template<typename T>
00508         inline T abs_t(T item) {return item<0 ? -item : item;}
00509 
00510         template<typename T>
00511         inline T sqr_t(T item) {return item * item;}
00512 
00513         template<typename T>
00514         inline T clip_t(const T & p_item, const T & p_min, const T & p_max) {
00515                 if (p_item < p_min) return p_min;
00516                 else if (p_item <= p_max) return p_item;
00517                 else return p_max;
00518         }
00519 
00520 
00521 
00522 
00523 
00524         template<typename T>
00525         inline void delete_t(T* ptr) {delete ptr;}
00526 
00527         template<typename T>
00528         inline void delete_array_t(T* ptr) {delete[] ptr;}
00529 
00530         template<typename T>
00531         inline T* clone_t(T* ptr) {return new T(*ptr);}
00532 
00533 
00534         template<typename t_exception,typename t_int>
00535         inline t_int mul_safe_t(t_int p_val1,t_int p_val2) {
00536                 if (p_val1 == 0 || p_val2 == 0) return 0;
00537                 t_int temp = (t_int) (p_val1 * p_val2);
00538                 if (temp < p_val1 || temp < p_val2) throw t_exception();
00539                 return temp;
00540         }
00541 
00542         template<typename t_src,typename t_dst>
00543         void memcpy_t(t_dst* p_dst,const t_src* p_src,t_size p_count) {
00544                 for(t_size n=0;n<p_count;n++) p_dst[n] = p_src[n];
00545         }
00546 
00547         template<typename t_dst,typename t_src>
00548         void copy_array_loop_t(t_dst & p_dst,const t_src & p_src,t_size p_count) {
00549                 for(t_size n=0;n<p_count;n++) p_dst[n] = p_src[n];
00550         }
00551 
00552         template<typename t_src,typename t_dst>
00553         void memcpy_backwards_t(t_dst * p_dst,const t_src * p_src,t_size p_count) {
00554                 p_dst += p_count; p_src += p_count;
00555                 for(t_size n=0;n<p_count;n++) *(--p_dst) = *(--p_src);
00556         }
00557 
00558         template<typename T,typename t_val>
00559         void memset_t(T * p_buffer,const t_val & p_val,t_size p_count) {
00560                 for(t_size n=0;n<p_count;n++) p_buffer[n] = p_val;
00561         }
00562 
00563         template<typename T,typename t_val>
00564         void memset_t(T &p_buffer,const t_val & p_val) {
00565                 const t_size width = pfc::array_size_t(p_buffer);
00566                 for(t_size n=0;n<width;n++) p_buffer[n] = p_val;
00567         }
00568 
00569         template<typename T>
00570         void memset_null_t(T * p_buffer,t_size p_count) {
00571                 for(t_size n=0;n<p_count;n++) p_buffer[n] = 0;
00572         }
00573 
00574         template<typename T>
00575         void memset_null_t(T &p_buffer) {
00576                 const t_size width = pfc::array_size_t(p_buffer);
00577                 for(t_size n=0;n<width;n++) p_buffer[n] = 0;
00578         }
00579 
00580         template<typename T>
00581         void memmove_t(T* p_dst,const T* p_src,t_size p_count) {
00582                 if (p_dst == p_src) {/*do nothing*/}
00583                 else if (p_dst > p_src && p_dst < p_src + p_count) memcpy_backwards_t<T>(p_dst,p_src,p_count);
00584                 else memcpy_t<T>(p_dst,p_src,p_count);
00585         }
00586 
00587         template<typename TVal> void memxor_t(TVal * out, const TVal * s1, const TVal * s2, t_size count) {
00588                 for(t_size walk = 0; walk < count; ++walk) out[walk] = s1[walk] ^ s2[walk];
00589         }
00590         static void memxor(void * target, const void * source1, const void * source2, t_size size) {
00591                 memxor_t( reinterpret_cast<t_uint8*>(target), reinterpret_cast<const t_uint8*>(source1), reinterpret_cast<const t_uint8*>(source2), size);
00592         }
00593 
00594         template<typename T>
00595         T* new_ptr_check_t(T* p_ptr) {
00596                 if (p_ptr == NULL) throw std::bad_alloc();
00597                 return p_ptr;
00598         }
00599 
00600         template<typename T>
00601         int sgn_t(const T & p_val) {
00602                 if (p_val < 0) return -1;
00603                 else if (p_val > 0) return 1;
00604                 else return 0;
00605         }
00606 
00607         template<typename T> const T* empty_string_t();
00608 
00609         template<> inline const char * empty_string_t<char>() {return "";}
00610         template<> inline const wchar_t * empty_string_t<wchar_t>() {return L"";}
00611 
00612 
00613         template<typename t_type,typename t_newval>
00614         t_type replace_t(t_type & p_var,const t_newval & p_newval) {
00615                 t_type oldval = p_var;
00616                 p_var = p_newval;
00617                 return oldval;
00618         }
00619         template<typename t_type>
00620         t_type replace_null_t(t_type & p_var) {
00621                 t_type ret = p_var;
00622                 p_var = NULL;
00623                 return ret;
00624         }
00625 
00626         template<t_size p_size_pow2>
00627         inline bool is_ptr_aligned_t(const void * p_ptr) {
00628                 static_assert< (p_size_pow2 & (p_size_pow2 - 1)) == 0 >();
00629                 return ( ((t_size)p_ptr) & (p_size_pow2-1) ) == 0;
00630         }
00631 
00632 
00633         template<typename t_array>
00634         void array_rangecheck_t(const t_array & p_array,t_size p_index) {
00635                 if (p_index >= pfc::array_size_t(p_array)) throw pfc::exception_overflow();
00636         }
00637 
00638         template<typename t_array>
00639         void array_rangecheck_t(const t_array & p_array,t_size p_from,t_size p_to) {
00640                 if (p_from > p_to) throw pfc::exception_overflow();
00641                 array_rangecheck_t(p_array,p_from); array_rangecheck_t(p_array,p_to);
00642         }
00643 
00644         inline t_int32 rint32(double p_val) {return (t_int32) floor(p_val + 0.5);}
00645         inline t_int64 rint64(double p_val) {return (t_int64) floor(p_val + 0.5);}
00646 
00647 
00648 
00649 
00650         template<typename t_array>
00651         inline t_size remove_mask_t(t_array & p_array,const bit_array & p_mask)//returns amount of items left
00652         {
00653                 t_size n,count = p_array.get_size(), total = 0;
00654 
00655                 n = total = p_mask.find(true,0,count);
00656 
00657                 if (n<count)
00658                 {
00659                         for(n=p_mask.find(false,n+1,count-n-1);n<count;n=p_mask.find(false,n+1,count-n-1))
00660                                 swap_t(p_array[total++],p_array[n]);
00661 
00662                         p_array.set_size(total);
00663                         
00664                         return total;
00665                 }
00666                 else return count;
00667         }
00668 
00669         template<typename t_array,typename t_compare>
00670         t_size find_duplicates_sorted_t(t_array p_array,t_size p_count,t_compare p_compare,bit_array_var & p_out) {
00671                 t_size ret = 0;
00672                 t_size n;
00673                 if (p_count > 0)
00674                 {
00675                         p_out.set(0,false);
00676                         for(n=1;n<p_count;n++)
00677                         {
00678                                 bool found = p_compare(p_array[n-1],p_array[n]) == 0;
00679                                 if (found) ret++;
00680                                 p_out.set(n,found);
00681                         }
00682                 }
00683                 return ret;
00684         }
00685 
00686         template<typename t_array,typename t_compare,typename t_permutation>
00687         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) {
00688                 t_size ret = 0;
00689                 t_size n;
00690                 if (p_count > 0) {
00691                         p_out.set(p_permutation[0],false);
00692                         for(n=1;n<p_count;n++)
00693                         {
00694                                 bool found = p_compare(p_array[p_permutation[n-1]],p_array[p_permutation[n]]) == 0;
00695                                 if (found) ret++;
00696                                 p_out.set(p_permutation[n],found);
00697                         }
00698                 }
00699                 return ret;
00700         }
00701 
00702         template<typename t_char>
00703         t_size strlen_t(const t_char * p_string,t_size p_length = infinite) {
00704                 for(t_size walk = 0;;walk++) {
00705                         if (walk >= p_length || p_string[walk] == 0) return walk;
00706                 }
00707         }
00708 
00709 
00710         template<typename t_array>
00711         class __list_to_array_enumerator {
00712         public:
00713                 __list_to_array_enumerator(t_array & p_array) : m_array(p_array), m_walk(0) {}
00714                 template<typename t_item>
00715                 void operator() (const t_item & p_item) {
00716                         PFC_ASSERT(m_walk < m_array.get_size());
00717                         m_array[m_walk++] = p_item;
00718                 }
00719                 void finalize() {
00720                         PFC_ASSERT(m_walk == m_array.get_size());
00721                 }
00722         private:
00723                 t_size m_walk;
00724                 t_array & m_array;
00725         };
00726 
00727         template<typename t_list,typename t_array>
00728         void list_to_array(t_array & p_array,const t_list & p_list) {
00729                 p_array.set_size(p_list.get_count());
00730                 __list_to_array_enumerator<t_array> enumerator(p_array);
00731                 p_list.enumerate(enumerator);
00732                 enumerator.finalize();
00733         }
00734 
00735         template<typename t_receiver>
00736         class enumerator_add_item {
00737         public:
00738                 enumerator_add_item(t_receiver & p_receiver) : m_receiver(p_receiver) {}
00739                 template<typename t_item> void operator() (const t_item & p_item) {m_receiver.add_item(p_item);}
00740         private:
00741                 t_receiver & m_receiver;
00742         };
00743 
00744         template<typename t_receiver,typename t_giver>
00745         void overwrite_list_enumerated(t_receiver & p_receiver,const t_giver & p_giver) {
00746                 enumerator_add_item<t_receiver> wrapper(p_receiver);
00747                 p_giver.enumerate(wrapper);
00748         }
00749 
00750         template<typename t_receiver,typename t_giver>
00751         void copy_list_enumerated(t_receiver & p_receiver,const t_giver & p_giver) {
00752                 p_receiver.remove_all();
00753                 overwrite_list_enumerated(p_receiver,p_giver);
00754         }
00755 
00756         inline bool lxor(bool p_val1,bool p_val2) {
00757                 return p_val1 == !p_val2;
00758         }
00759 
00760         template<typename t_val>
00761         inline void min_acc(t_val & p_acc,const t_val & p_val) {
00762                 if (p_val < p_acc) p_acc = p_val;
00763         }
00764 
00765         template<typename t_val>
00766         inline void max_acc(t_val & p_acc,const t_val & p_val) {
00767                 if (p_val > p_acc) p_acc = p_val;
00768         }
00769 
00770         t_uint64 pow_int(t_uint64 base, t_uint64 exp);
00771 };
00772 
00773 
00774 #define PFC_CLASS_NOT_COPYABLE(THISCLASSNAME,THISTYPE) \
00775         private:        \
00776         THISCLASSNAME(const THISTYPE&) {throw pfc::exception_bug_check();}      \
00777         const THISTYPE & operator=(const THISTYPE &) {throw pfc::exception_bug_check();}
00778 
00779 #define PFC_CLASS_NOT_COPYABLE_EX(THISTYPE) PFC_CLASS_NOT_COPYABLE(THISTYPE,THISTYPE)

Generated on Fri Apr 25 18:49:37 2008 for foobar2000 SDK by  doxygen 1.5.5