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
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
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
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
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) {}
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)
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)