41 #include "bj_big_number.h" 44 #include "top_exception.h" 45 #include "ch_string.h" 46 #include "print_macros.h" 48 #define NUM_BYTES_IN_KBYTE 1024 52 typedef integer row_index;
53 typedef char comparison;
55 #define CMP_FN_T(nm_fun) comparison (*nm_fun)(obj_t const & obj1, obj_t const & obj2) 57 #define as_bool(prm) ((prm) != 0) 67 #ifndef k_num_bits_byte 68 #define k_num_bits_byte 8 71 #define TOOLS_CK(prm) DBG_CK(prm) 72 #define TOOLS_CK_2(prm, comm) DBG_CK_2(prm, comm) 74 #define MIN_TYPE(type) (((type)1) << (sizeof(type) * k_num_bits_byte - 1)) 75 #define MAX_TYPE(type) (- (MIN_TYPE(type) + 1)) 77 #define MIN_INTEGER MIN_TYPE(integer) 80 #define MIN_INDEX MIN_TYPE(row_index) 83 #define SUB_SET_OPS 4 // each loop counts as this num ops 85 #define indent_fmt "%-*d" 87 #define SELEC_SORT_LIM 10 90 #define INVALID_IDX -1 93 #ifndef INVALID_NATURAL 94 #define INVALID_NATURAL -1 101 #ifndef FILL_FULL_CAP 102 #define FILL_FULL_CAP -100 106 #define START_CAP 16 // avoid mem problems (due to mem alloc, re-alloc failures) 109 #define SZ_ATTRIB_T(the_type) row_data<the_type>::sz 110 #define CAP_ATTRIB_T(the_type) row_data<the_type>::cap 112 #define SZ_ATTRIB row_data<obj_t>::sz 113 #define CAP_ATTRIB row_data<obj_t>::cap 115 #define lo_hex_as_int(the_byte) (((the_byte) >> 4) & 0xF) 116 #define hi_hex_as_int(the_byte) ((the_byte) & 0x0F) 124 rwx_bad_call_set_cap,
129 class row_exception :
public top_exception {
131 row_exception(
long the_id = 0) : top_exception(the_id)
162 return abs_long(lit);
167 cmp_string(ch_string
const & n1, ch_string
const & n2){
168 if(n1 == n2){
return 0; }
169 if(n1 < n2){
return -1; }
175 cmp_long(
long const & n1,
long const & n2){
176 if(n1 == n2){
return 0; }
177 if(n1 < n2){
return -1; }
183 cmp_char(
char const & c1,
char const & c2){
184 if(c1 == c2){
return 0; }
185 if(c1 < c2){
return -1; }
191 cmp_double(
double const & n1,
double const & n2){
192 if(n1 == n2){
return 0; }
193 if(n1 < n2){
return -1; }
199 cmp_abs_long(
long const & nn1,
long const & nn2){
200 long n1 = abs_long(nn1);
201 long n2 = abs_long(nn2);
204 return cmp_long(n1, n2);
209 cmp_integer(integer
const & i1, integer
const & i2){
210 if(i1 == i2){
return 0; }
211 if(i1 < i2){
return -1; }
217 cmp_big_floating(bj_big_float_t
const & bn1, bj_big_float_t
const & bn2){
218 if(bn1 < bn2){
return -1; }
219 if(bn1 > bn2){
return 1; }
226 typedef char trinary;
228 template<
class obj_t>
static inline obj_t
229 min_val(obj_t x, obj_t y) {
230 return (x < y) ? x : y;
233 template<
class obj_t>
static inline obj_t
234 max_val(obj_t x, obj_t y) {
235 return (x > y) ? x : y;
240 bj_ostream&
operator << (bj_ostream& os, __int64 ii ){
242 sprintf(buf,
"%I64d", ii );
249 template<class obj_t>
250 static inline row_index
251 get_idx_of_pt(obj_t* data, obj_t* pt_obj, row_index the_size){
252 row_index pt_idx = INVALID_IDX;
254 long pt1 = (long)data;
255 long pt2 = pt1 + (
sizeof(obj_t) * the_size);
256 long pt3 = (long)pt_obj;
257 bool in_range = (pt1 <= pt3) && (pt3 < pt2);
258 bool in_place = (((pt3 - pt1) %
sizeof(obj_t)) == 0);
259 if(in_range && in_place){
260 pt_idx = ((pt3 - pt1) /
sizeof(obj_t));
269 #define k_flag0 ((char)0x01) 270 #define k_flag1 ((char)0x02) 271 #define k_flag2 ((char)0x04) 272 #define k_flag3 ((char)0x08) 273 #define k_flag4 ((char)0x10) 274 #define k_flag5 ((char)0x20) 275 #define k_flag6 ((char)0x40) 276 #define k_flag7 ((char)0x80) 279 char set_flag(
char& flags,
char bit_flag){
280 flags = (char)(flags | bit_flag);
285 char reset_flag(
char& flags,
char bit_flag){
286 flags = (char)(flags & ~bit_flag);
291 bool get_flag(
char flags,
char bit_flag){
292 char resp = (char)(flags & bit_flag);
300 long div8l(
long val){
305 long mod8l(
long val){
310 bool bit_get(t_1byte* the_bits,
long bit_idx){
311 return (
bool)((the_bits[div8l(bit_idx)] >> mod8l(bit_idx)) & 1);
315 void bit_set(t_1byte* the_bits,
long bit_idx){
316 the_bits[div8l(bit_idx)] |= (1 << mod8l(bit_idx));
320 void bit_reset(t_1byte* the_bits,
long bit_idx){
321 the_bits[div8l(bit_idx)] &= ~(1 << mod8l(bit_idx));
325 void bit_toggle(t_1byte* the_bits,
long bit_idx){
326 the_bits[div8l(bit_idx)] ^= (1 << mod8l(bit_idx));
330 long as_num_bytes(
long num_bits){
331 return (div8l(num_bits) + (mod8l(num_bits) > 0));
335 long as_num_bits(
long num_bytes){
336 return (num_bytes * 8);
346 template<
class obj_t>
354 typedef bj_ostream& (*print_func_t)(bj_ostream& os, obj_t& obj);
355 typedef comparison (*cmp_func_t)(obj_t
const & obj1, obj_t
const & obj2);
361 virtual bool ck_valid_pt(obj_t* pt_obj){
362 throw row_exception(rwx_bad_pt);
365 virtual void set_cap(row_index min_cap){
366 throw row_exception(rwx_bad_call_set_cap);
369 virtual void clear(
bool destroy =
false,
bool dealloc =
false, row_index from = 0){
370 throw row_exception(rwx_bad_call_clear);
373 virtual obj_t& pos(row_index idx){
374 throw row_exception(rwx_bad_call_pos);
378 row_index sz_in_bytes(){
379 return (sz *
sizeof(obj_t));
387 row_data(): sz(0), cap(0) {}
394 void grow(row_index min_cap){
395 if(min_cap <= cap){
return; }
396 row_index nxt_cap = cap;
403 nxt_cap = nxt_cap * 2;
404 }
while(nxt_cap < min_cap);
406 TOOLS_CK(nxt_cap > 1);
411 row_index size()
const {
415 row_index last_idx(){
425 void push(
const obj_t elem){
429 new (&pos(sz)) obj_t(elem);
437 new (&pos(sz)) obj_t();
442 void minc_sz(
long num_incs){
443 for(
long aa = 0; aa < num_incs; aa++){
457 obj_t tmp1 = pos(sz);
472 void swap(row_index idx1, row_index idx2){
473 TOOLS_CK(is_valid_idx(idx1));
474 TOOLS_CK(is_valid_idx(idx2));
476 obj_t tmp1 = pos(idx1);
477 pos(idx1) = pos(idx2);
481 void call_swap_with(row_index idx1, row_index idx2){
482 TOOLS_CK(is_valid_idx(idx1));
483 TOOLS_CK(is_valid_idx(idx2));
485 obj_t& tmp1 = pos(idx1);
486 obj_t& tmp2 = pos(idx2);
487 tmp1.swap_with(tmp2);
502 obj_t swap_pop(row_index idx){
503 TOOLS_CK(is_valid_idx(idx));
505 obj_t tmp1 = pos(idx);
512 void swapop(row_index idx){
513 TOOLS_CK(is_valid_idx(idx));
522 void fill(
const obj_t elem, row_index num_fill = INVALID_IDX,
523 row_index from_idx = 0)
525 if(from_idx == INVALID_IDX){
529 if(num_fill == INVALID_IDX){
532 if(num_fill == FILL_FULL_CAP){
535 num_fill += from_idx;
538 row_index ii = from_idx;
539 for(ii = from_idx; ((ii < sz) && (ii < num_fill)); ii++){
542 for(; ii < num_fill; ii++){
547 void fill_new(row_index num_fill = INVALID_IDX){
549 if(num_fill == INVALID_IDX){
552 if(num_fill == FILL_FULL_CAP){
556 for(row_index ii = 0; ii < num_fill; ii++){
561 bool is_valid_idx(row_index idx){
562 return ((idx >= 0) && (idx < sz));
565 obj_t& operator [] (row_index idx) {
566 TOOLS_CK(is_valid_idx(idx));
573 row_data<obj_t>& operator = (row_data<obj_t>& other) {
577 row_data(row_data<obj_t>& other){
582 void copy_to(row_data<obj_t>& dest,
583 row_index first_ii = 0, row_index last_ii = -1,
586 TOOLS_CK(&dest !=
this);
587 dest.clear(
true,
true);
588 append_to(dest, first_ii, last_ii, inv);
591 void append_to(row_data<obj_t>& dest,
592 row_index first_ii = 0, row_index last_ii = -1,
595 if((last_ii < 0) || (last_ii > sz)){
598 if((first_ii < 0) || (first_ii > last_ii)){
601 dest.set_cap(dest.sz + (last_ii - first_ii));
602 row_index ii = INVALID_IDX;
604 for(ii = last_ii - 1; ii >= first_ii; ii--){
605 TOOLS_CK(is_valid_idx(ii));
610 for(ii = first_ii; ii < last_ii; ii++){
611 TOOLS_CK(is_valid_idx(ii));
620 bj_ostream& print_row_data(
622 bool with_lims =
true,
623 const char* sep =
" ",
624 row_index low = INVALID_IDX,
625 row_index hi = INVALID_IDX,
626 bool pointers =
false,
627 row_index grp_sz = -1,
628 const char* grp_sep =
"\n",
629 row_index from_idx = 0,
630 print_func_t prt_fn = NULL_PT
633 if(from_idx == INVALID_IDX){
637 row_index num_elem = 1;
638 if(with_lims){ os <<
"["; }
639 for(row_index ii = from_idx; ii < sz; ii++){
640 if(ii == low){ os <<
">"; }
641 if(prt_fn != NULL_PT){
642 (*prt_fn)(os, pos(ii));
653 if(ii == hi){ os <<
"<"; }
656 if((grp_sz > 1) && ((num_elem % grp_sz) == 0)){
661 if(with_lims){ os <<
"] "; }
668 void selec_sort(cmp_func_t cmp_fn){
669 row_index ii, jj, best_ii;
671 for (ii = 0; ii < (sz - 1); ii++){
673 for (jj = ii+1; jj < sz; jj++){
674 if((*cmp_fn)(pos(jj), pos(best_ii)) < 0){
679 pos(ii) = pos(best_ii);
684 bool is_sorted(cmp_func_t cmp_fn){
685 if(sz == 0){
return true; }
686 obj_t* lst = &(pos(0));
687 for(row_index ii = 1; ii < sz; ii++){
688 if((*cmp_fn)(*lst, pos(ii)) > 0){
696 bool equal_to(row_data<obj_t>& rw2, row_index first_ii = 0, row_index last_ii = -1){
697 if((sz == 0) && (rw2.size() == 0)){
700 if((last_ii < 0) && (sz != rw2.size())){
703 if((last_ii < 0) || (last_ii > sz)){
706 if((first_ii < 0) || (first_ii > last_ii)){
710 if(! is_valid_idx(first_ii)){
return false; }
711 if(! is_valid_idx(last_ii - 1)){
return false; }
712 if(! rw2.is_valid_idx(first_ii)){
return false; }
713 if(! rw2.is_valid_idx(last_ii - 1)){
return false; }
715 for (row_index ii = first_ii; ii < last_ii; ii++){
716 if(pos(ii) != rw2.pos(ii)){
723 long equal_to_diff(cmp_func_t cmp_fn,
724 row_data<obj_t>& rw2, row_data<obj_t>* diff = NULL_PT,
725 row_index first_ii = 0, row_index last_ii = -1)
727 if((sz == 0) && (rw2.size() == 0)){
730 if((last_ii < 0) || (last_ii > sz)){
733 if((first_ii < 0) || (first_ii > last_ii)){
738 diff->fill_new(last_ii);
741 long df_pos = INVALID_IDX;
742 row_index ii = INVALID_IDX;
743 for (ii = first_ii; ii < last_ii; ii++){
744 if(! is_valid_idx(ii)){
break; }
745 if(! rw2.is_valid_idx(ii)){
break; }
748 if((*cmp_fn)(pos(ii), rw2.pos(ii)) != 0){
751 diff->pos(ii) = pos(ii);
753 if(df_pos == INVALID_IDX){
758 if((ii >= 0) && (ii != last_ii)){
765 template<
class obj_t>
767 bj_ostream& operator << (bj_ostream& os, row_data<obj_t>& rr){
768 rr.print_row_data(os,
true,
" ");
772 template<
class obj_t>
774 bj_ostream& operator << (bj_ostream& os, row_data<obj_t>* rr){
778 rr->print_row_data(os,
true,
" ");
783 template<
class obj_t>
785 row_data<obj_t>& operator << (row_data<obj_t>& rr,
const obj_t elem){
790 template<
class obj_t>
792 row_data<obj_t>& operator >> (row_data<obj_t>& rr, obj_t& elem){
801 template<
class obj_t>
804 row_data<obj_t>& the_row;
807 row_iter(row_data<obj_t>& d_row) : the_row(d_row){
808 the_ref = INVALID_IDX;
810 row_iter(row_iter& row_it): the_row(row_it.the_row){
811 the_ref = INVALID_IDX;
817 return the_row.size();
824 the_ref = INVALID_IDX;
830 the_ref = the_row.last_idx();
832 the_ref = INVALID_IDX;
837 return the_row[the_ref];
841 return ((the_ref < 0) || (the_ref >= size()));
864 void operator ++ (
int) { ++(*this); }
866 void operator -- (
int) { --(*this); }
872 #define DATA_ATTRIB_T(the_type) row<the_type>::data 874 #define DATA_ATTRIB row<obj_t>::data 876 template<
class obj_t>
877 class row:
public row_data<obj_t> {
882 typedef comparison (*cmp_func_t)(obj_t
const & obj1, obj_t
const & obj2);
883 typedef void (*in_both_func_t)(obj_t
const & obj1);
888 row<obj_t>& operator = (row<obj_t>& other) {
892 row(row<obj_t>& other){
896 const t_1byte* get_data(){
897 return ((t_1byte*)data);
901 return (SZ_ATTRIB *
sizeof(obj_t));
904 void as_hex_txt(row<char>& hex_str){
905 char hexval[16] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
906 '8',
'9',
'a',
'b',
'c',
'd',
'e',
'f'};
907 const t_1byte* by_arr = get_data();
908 long sz_arr = get_data_sz();
909 long hex_sz = sz_arr * 2;
912 hex_str.fill(
'0', hex_sz);
914 for(
long aa = 0; aa < sz_arr; aa++){
915 hex_str[aa * 2] = hexval[lo_hex_as_int(by_arr[aa])];
916 hex_str[(aa * 2) + 1] = hexval[hi_hex_as_int(by_arr[aa])];
920 ch_string as_hex_str(){
924 ch_string out_str = hex_txt.get_c_array();
928 const obj_t* get_c_array(){
932 long get_c_array_sz(){
937 void init_s_bit_row(s_bit_row& rr){
938 rr.init_data(((t_1byte*)data), get_data_sz());
942 virtual bool ck_valid_pt(obj_t* pt_obj){
943 row_index pt_idx = get_idx_of_pt<obj_t>(data, pt_obj, SZ_ATTRIB);
944 return (pt_idx != INVALID_IDX);
947 virtual void set_cap(row_index min_cap){
948 if(min_cap <= CAP_ATTRIB){
return; }
949 row_index old_cap = CAP_ATTRIB;
950 TOOLS_CK(old_cap >= 0);
952 CAP_ATTRIB = min_cap;
953 obj_t* n_dat = tpl_realloc(data, old_cap, CAP_ATTRIB);
958 void set_size(row_index n_sz){
963 void clear_each(row_index from = 0){
964 for(row_index ii = from; ii < SZ_ATTRIB; ii++){
969 virtual void clear(
bool destroy =
false,
bool dealloc =
false, row_index from = 0){
975 for(row_index ii = from; ii < SZ_ATTRIB; ii++){
981 tpl_free(data, CAP_ATTRIB);
989 obj_t& pos(row_index idx){
994 void move_to(row<obj_t>& dest,
bool just_init =
false){
996 dest.clear(
true,
true);
1000 dest.cap = CAP_ATTRIB;
1007 void swap_with(row<obj_t>& other){
1008 obj_t* tmp_data = other.data;
1009 row_index tmp_sz = other.sz;
1010 row_index tmp_cap = other.cap;
1013 other.sz = SZ_ATTRIB;
1014 other.cap = CAP_ATTRIB;
1018 CAP_ATTRIB = tmp_cap;
1022 bool copy_to_c(
long c_arr_sz, obj_t* c_arr){
1023 TOOLS_CK(c_arr != data);
1024 if(c_arr_sz != SZ_ATTRIB){
1027 bj_memcpy(c_arr, data, row_data<obj_t>::sz_in_bytes());
1031 void mem_copy_to(row<obj_t>& r_cpy){
1032 TOOLS_CK(&r_cpy !=
this);
1033 r_cpy.set_cap(SZ_ATTRIB);
1034 bj_memcpy(r_cpy.data, data, row_data<obj_t>::sz_in_bytes());
1035 r_cpy.sz = SZ_ATTRIB;
1039 row(row_index pm_cap = 0): row_data<obj_t>(), data(NULL_PT){
1040 if(pm_cap > 0){ row<obj_t>::set_cap(pm_cap); }
1047 void mix_sort(cmp_func_t cmp_fn);
1053 void sorted_set_adhere(row<obj_t>&
set, cmp_func_t cmp_fn);
1059 void sorted_set_reduce(row<obj_t>&
set, cmp_func_t cmp_fn);
1065 void sorted_set_shared(row<obj_t>& shared,
1066 row<obj_t>&
set, cmp_func_t cmp_fn);
1068 cmp_is_sub sorted_set_is_subset(row<obj_t>&
set,
1069 cmp_func_t cmp_fn,
bool& are_eq, in_both_func_t both_fn = NULL_PT);
1071 long shuffle(row_index from = 0,
bool init_random =
true);
1075 typedef row<long> row_long_t;
1076 typedef row<row_long_t> row_row_long_t;
1078 template<
class obj_t>
1080 comparison cmp_with(row<obj_t>& set1, row<obj_t>& set2, CMP_FN_T(cmp_fn)){
1082 if(set1.size() < set2.size()){
1085 if(set1.size() > set2.size()){
1088 TOOLS_CK(set1.size() == set2.size());
1089 for(row_index ii = 0; ii < set1.size(); ii++){
1090 comparison cmp_resp = (*cmp_fn)(set1.pos(ii), set2.pos(ii));
1104 template<
class obj_t>
1105 class s_row :
public row<obj_t> {
1108 void grow(row_index bits_cap){ MARK_USED(bits_cap); }
1110 void set_cap(row_index bits_cap){ MARK_USED(bits_cap); }
1112 void set_size(row_index bits_sz){ MARK_USED(bits_sz); }
1114 void push(
const bool elem){ MARK_USED(elem); }
1120 bool pop(){
return false; }
1122 bool swap_pop(row_index idx){ MARK_USED(idx);
return false; }
1124 void swapop(row_index idx){ MARK_USED(idx); }
1127 s_row(t_1byte* dat = NULL_PT,
long dat_num_bytes = 0){
1128 init_data(dat, dat_num_bytes);
1136 void clear(
bool reset_them =
false,
bool dealloc =
false, row_index from = 0){
1137 MARK_USED(reset_them);
1142 DATA_ATTRIB = NULL_PT;
1145 long to_objs(
long num_bytes){
1146 return (num_bytes /
sizeof(obj_t));
1149 void init_obj_data(
const obj_t* dat,
long num_obj){
1150 SZ_ATTRIB = num_obj;
1151 CAP_ATTRIB = num_obj;
1153 DATA_ATTRIB = (obj_t*)dat;
1155 DATA_ATTRIB = NULL_PT;
1159 void init_data(t_1byte* dat,
long dat_num_bytes){
1160 SZ_ATTRIB = to_objs(dat_num_bytes);
1161 CAP_ATTRIB = to_objs(dat_num_bytes);
1163 DATA_ATTRIB = (obj_t*)dat;
1165 DATA_ATTRIB = NULL_PT;
1170 void init_data_with_s_bit_row(s_bit_row& rr){
1171 SZ_ATTRIB = to_objs(rr.get_bytes_cap());
1172 CAP_ATTRIB = to_objs(rr.get_bytes_cap());
1174 DATA_ATTRIB = (obj_t*)(rr.data);
1176 DATA_ATTRIB = NULL_PT;
1182 if(DATA_ATTRIB == NULL_PT){
1185 bj_memset(DATA_ATTRIB, 0, (SZ_ATTRIB *
sizeof(obj_t)));
1192 template<
class obj_t>
1193 class k_row :
public row_data<obj_t> {
1196 row_index first_exp;
1197 row_index first_cap;
1199 row_index cap2i(row_index& nxt_cap, row_index& rest){
1203 while(cc < nxt_cap){ cc <<= 1; first_exp++; }
1207 TOOLS_CK(first_cap == cc);
1212 TOOLS_CK(first_cap > 0);
1214 row_index cc = first_cap;
1215 row_index n_cap = first_cap;
1217 while(n_cap < nxt_cap){
1222 rest = nxt_cap - (n_cap - cc);
1227 row_index i2e(row_index ii){
1228 return (ii + first_exp);
1231 row_index i2c(row_index ii){
1232 row_index ee = i2e(ii);
1236 virtual void set_cap(row_index nxt_cap){
1237 if(nxt_cap <= CAP_ATTRIB){
return; }
1238 if(nxt_cap <= START_CAP){ nxt_cap = START_CAP; }
1240 row_index rest = INVALID_IDX;
1241 row_index old_cap = CAP_ATTRIB;
1242 row_index old_i = cap2i(old_cap, rest);
1243 row_index old_dt_sz = old_i + 1;
1244 TOOLS_CK(old_cap == CAP_ATTRIB);
1246 row_index new_i = cap2i(nxt_cap, rest);
1247 row_index new_dt_sz = new_i + 1;
1249 CAP_ATTRIB = nxt_cap;
1250 TOOLS_CK(first_cap == i2c(0));
1252 obj_t** n_pt_dat = tpl_realloc(pt_data, old_dt_sz, new_dt_sz);
1255 for(row_index ii = old_dt_sz; ii < new_dt_sz; ii++){
1256 pt_data[ii] = NULL_PT;
1257 pt_data[ii] = tpl_malloc<obj_t>(i2c(ii));
1261 virtual void clear(
bool destroy =
false,
bool dealloc =
false, row_index from = 0){
1262 if(pt_data != NULL_PT){
1267 for(row_index ii = from; ii < SZ_ATTRIB; ii++){
1273 TOOLS_CK(first_exp > 0);
1274 row_index rest = INVALID_IDX;
1275 row_index dt_sz = cap2i(CAP_ATTRIB, rest) + 1;
1279 for(row_index jj = 0; jj < dt_sz; jj++){
1281 tpl_free(pt_data[jj], i2c(jj));
1282 pt_data[jj] = NULL_PT;
1284 tpl_free(pt_data, dt_sz);
1293 void get_coordinates(row_index idx,
1294 row_index& coor1, row_index& coor2)
1296 if(idx < first_cap){
1302 row_index sub_ii = INVALID_IDX;
1303 row_index ii = idx + 1;
1304 row_index dt_ii = cap2i(ii, sub_ii);
1310 virtual obj_t& pos(row_index idx){
1311 row_index coor1 = INVALID_IDX;
1312 row_index coor2 = INVALID_IDX;
1313 get_coordinates(idx, coor1, coor2);
1314 TOOLS_CK(coor1 != INVALID_IDX);
1315 TOOLS_CK(coor2 != INVALID_IDX);
1316 return pt_data[coor1][coor2];
1319 virtual bool ck_valid_pt(obj_t* pt_obj){
1320 bool ck_valid =
false;
1321 if(pt_data != NULL_PT){
1322 TOOLS_CK(first_exp > 0);
1323 row_index rest = INVALID_IDX;
1324 row_index dt_sz = cap2i(CAP_ATTRIB, rest) + 1;
1325 for(row_index jj = 0; jj < dt_sz; jj++){
1326 TOOLS_CK(pt_data[jj] != NULL_PT);
1327 row_index pt_idx = get_idx_of_pt<obj_t>(pt_data[jj],
1329 if(pt_idx != INVALID_IDX){
1330 row_index coor1_last = INVALID_IDX;
1331 row_index coor2_last = INVALID_IDX;
1332 get_coordinates(SZ_ATTRIB - 1, coor1_last, coor2_last);
1333 if( (jj < coor1_last) ||
1334 ((jj == coor1_last) && (pt_idx <= coor2_last)))
1336 TOOLS_CK(&(pt_data[jj][pt_idx]) == pt_obj);
1347 k_row(row_index pm_cap = 0):
1353 if(pm_cap > 0){ k_row<obj_t>::set_cap(pm_cap); }
1365 template <
class obj_t>
1366 class queue :
public row<obj_t> {
1370 queue(
void) : first(0) { }
1373 return row<obj_t>::pos(first);
1376 return row<obj_t>::pos(first++);
1379 virtual void clear(
bool destroy =
false,
bool dealloc =
false){
1381 row<obj_t>::clear(destroy, dealloc);
1383 virtual long size()
const {
1384 return SZ_ATTRIB - first;
1392 template<
class obj_t>
1393 class heap :
public row<obj_t> {
1394 row_index parent(row_index idx){
return ((idx+1)>>1) - 1; }
1395 row_index left(row_index idx){
return ((idx+1)<<1) - 1; }
1396 row_index right(row_index idx){
return ((idx+1)<<1); }
1398 row_index heapify(row_index idx);
1400 void update_idx(row_index idx){
1401 if(func_idx == NULL_PT){
return; }
1402 (*func_idx)(row<obj_t>::pos(idx)) = idx;
1404 void ck_idx(row_index idx){
1405 if(func_idx == NULL_PT){
return; }
1406 TOOLS_CK(idx == (*func_idx)(row<obj_t>::pos(idx)));
1410 typedef comparison (*cmp_func_t)(obj_t
const & obj1, obj_t
const & obj2);
1411 typedef row_index& (*func_idx_t)(obj_t&);
1413 cmp_func_t cmp_func;
1414 func_idx_t func_idx;
1416 comparison cmp(row_index idx1, row_index idx2){
1417 return (*cmp_func)(row<obj_t>::pos(idx1), row<obj_t>::pos(idx2));
1420 comparison cmp_obj(row_index idx1, obj_t& obj){
1421 return (*cmp_func)(row<obj_t>::pos(idx1), obj);
1424 heap(cmp_func_t f_key, func_idx_t f_idx = NULL_PT, row_index pm_cap = 0)
1425 : row<obj_t>(pm_cap)
1431 heap(row<obj_t>& arr, cmp_func_t f_key, func_idx_t f_idx = NULL_PT)
1436 arr.move_to(*
this,
true);
1441 row<obj_t>::clear(
true,
true);
1445 row_index insert(obj_t obj);
1446 row_index changed_key(row_index idx);
1448 obj_t
remove(row_index idx);
1452 if(SZ_ATTRIB > 0){
return row<obj_t>::pos(0); }
1455 void n_top_to(row_index nn, row<obj_t>& top_ob){
1456 if(SZ_ATTRIB == 0){
return; }
1457 for(row_index ii = 0;
1458 ( (ii < SZ_ATTRIB) &&
1459 (top_ob.size() < nn) &&
1463 top_ob.push(row<obj_t>::pos(ii));
1468 bool dbg_is_heap_ok(row_index idx = 0);
1470 bj_ostream& print_heap(bj_ostream& os, row_index idx);
1473 row_index orig_sz = SZ_ATTRIB;
1474 for(row_index ii = orig_sz - 1; ii >= 0; ii--){
1475 row_data<obj_t>::swap(0, ii);
1479 row<obj_t>::clear(
true,
false, orig_sz);
1484 template<
class obj_t>
1486 bj_ostream& operator << (bj_ostream& os, heap<obj_t>& he){
1487 return he.print_heap(os, 0);
1495 ch_string subset_cmp_str(cmp_is_sub val){
1496 ch_string str =
"k_invalid !!!";
1499 str =
"k_lft_is_sub";
break;
1501 str =
"k_no_is_sub";
break;
1503 str =
"k_rgt_is_sub";
break;
1508 #define decl_cmp_fn(o_t, nam) comparison (*nam)(o_t const & obj1, o_t const & obj2) 1509 #define decl_both_fn(o_t, nam) void (*nam)(o_t const & obj1) 1511 template<
class obj_t,
class iter_t>
1513 is_subset_cmp(iter_t& iter1, iter_t& iter2,
1514 decl_cmp_fn(obj_t, cmp_fn),
bool& are_eq,
1515 decl_both_fn(obj_t, both_fn) = NULL_PT)
1519 long sz1 = iter1.size();
1520 long sz2 = iter2.size();
1521 bool empt1 = (sz1 == 0);
1522 bool empt2 = (sz2 == 0);
1527 return k_lft_is_sub;
1530 return k_rgt_is_sub;
1533 iter_t* sub_iter = &iter1;
1534 iter_t* set_iter = &iter2;
1535 cmp_is_sub is_sub_val = k_lft_is_sub;
1540 is_sub_val = k_rgt_is_sub;
1543 iter_t& hi_sub = *(sub_iter);
1545 iter_t lo_sub(hi_sub);
1547 iter_t& hi_set = *(set_iter);
1548 iter_t lo_set(hi_set);
1550 long hi_sub_to_ck = sub_iter->size() - 1;
1551 long lo_sub_to_ck = 0;
1553 long hi_set_to_ck = set_iter->size() - 1;
1554 long lo_set_to_ck = 0;
1556 lo_sub.go_first_ref();
1557 hi_sub.go_last_ref();
1559 lo_set.go_first_ref();
1560 hi_set.go_last_ref();
1562 cmp_is_sub final_cmp = k_no_is_sub;
1564 bool is_sub =
false;
1567 comparison cmp_lo = -3, cmp_hi = -3;
1569 TOOLS_CK((is_sub_val == k_lft_is_sub) || (is_sub_val == k_rgt_is_sub));
1577 long sub_to_ck = (hi_sub_to_ck - lo_sub_to_ck);
1578 long set_to_ck = (hi_set_to_ck - lo_set_to_ck);
1584 TOOLS_CK(final_cmp == k_no_is_sub);
1588 obj_t& lo_sub_obj = lo_sub.get_obj();
1589 obj_t& hi_sub_obj = hi_sub.get_obj();
1590 obj_t& lo_set_obj = lo_set.get_obj();
1591 obj_t& hi_set_obj = hi_set.get_obj();
1593 cmp_lo = (*cmp_fn)(lo_sub_obj, lo_set_obj);
1594 cmp_hi = (*cmp_fn)(hi_sub_obj, hi_set_obj);
1596 if(both_fn != NULL_PT){
1598 (*both_fn)(lo_sub_obj);
1599 (*both_fn)(lo_set_obj);
1602 (*both_fn)(hi_sub_obj);
1603 (*both_fn)(hi_set_obj);
1607 if((sub_to_ck == 0) && ((cmp_lo == 0) || (cmp_hi == 0))){
1608 are_eq = (sz1 == sz2);
1609 TOOLS_CK(! are_eq || (set_to_ck <= 0));
1610 final_cmp = is_sub_val;
1611 TOOLS_CK(final_cmp != k_no_is_sub);
1615 if( (sub_to_ck > set_to_ck) ||
1619 TOOLS_CK(final_cmp == k_no_is_sub);
1623 if(cmp_lo > 0){ lo_set++; lo_set_to_ck++; }
1624 if(cmp_lo == 0){ lo_sub++; lo_set++; lo_sub_to_ck++; lo_set_to_ck++; }
1625 if(cmp_hi == 0){ hi_sub--; hi_set--; hi_sub_to_ck--; hi_set_to_ck--; }
1626 if(cmp_hi < 0){ hi_set--; hi_set_to_ck--;}
1629 TOOLS_CK(final_cmp == k_no_is_sub);
1630 if((cmp_lo == 0) && (cmp_hi == 0)){
1631 are_eq = (sz1 == sz2);
1633 final_cmp = is_sub_val;
1634 TOOLS_CK(final_cmp != k_no_is_sub);
1639 template<
class obj_t>
1641 cmp_sorted_rows(row_data<obj_t>& r1, row_data<obj_t>& r2,
1642 decl_cmp_fn(obj_t, cmp_fn),
bool& are_eq,
1643 decl_both_fn(obj_t, both_fn) = NULL_PT)
1645 row_iter<obj_t> iter1(r1);
1646 row_iter<obj_t> iter2(r2);
1648 return is_subset_cmp<obj_t, row_iter<obj_t> >(iter1,
1649 iter2, cmp_fn, are_eq, both_fn);
1652 #define decl_cmp_sm_fn(o_t, nam) cmp_subsume_t (*nam)(o_t const & obj1, o_t const & obj2) 1657 template<
class obj_t>
1660 get_last_eq_obj_pos(row_index from_pos,
1661 row<obj_t>& rr1, row<obj_t>& rr2){
1671 TOOLS_CK(from_pos >= 0);
1672 int sz1 = rr1.size();
1673 int sz2 = rr2.size();
1674 int min_sz = (sz1 < sz2)?(sz1):(sz2);
1675 TOOLS_CK_2(from_pos < min_sz,
1676 os <<
"from_pos=" << from_pos << bj_eol;
1677 os <<
"min_sz=" << min_sz << bj_eol;
1678 os <<
"sz1=" << sz1 << bj_eol;
1679 os <<
"sz2=" << sz2 << bj_eol;
1683 for(ii = from_pos; ii < min_sz; ii++){
1684 TOOLS_CK(rr1.is_valid_idx(ii));
1685 TOOLS_CK(rr2.is_valid_idx(ii));
1686 obj_t vv1 = rr1[ii];
1687 obj_t vv2 = rr2[ii];
1692 row_index lst_pos = ii - 1;
1693 if((lst_pos >= from_pos) && (lst_pos < min_sz)){
1694 TOOLS_CK_2(rr1[lst_pos] == rr2[lst_pos],
1695 os <<
"from_pos=" << from_pos << bj_eol;
1696 os <<
"min_sz=" << min_sz << bj_eol;
1697 os <<
"sz1=" << sz1 << bj_eol;
1698 os <<
"sz2=" << sz2 << bj_eol;
1699 os <<
"lst_pos=" << lst_pos << bj_eol;
1700 os <<
"rr1=" << rr1 << bj_eol;
1701 os <<
"rr2=" << rr2 << bj_eol;
1708 template<
class obj_t>
1710 row<obj_t>::sorted_set_is_subset(row<obj_t>&
set,
1711 cmp_func_t cmp_fn,
bool& are_eq, in_both_func_t both_fn)
1713 return cmp_sorted_rows(*
this,
set, cmp_fn, are_eq, both_fn);
1716 template<
class obj_t>
1718 row<obj_t>::sorted_set_shared(row<obj_t>& shared,
1719 row<obj_t>& rr2, cmp_func_t cmp_fn)
1721 row_index lo_idx1 = 0;
1722 row_index hi_idx1 = row<obj_t>::last_idx();
1723 row_index lo_idx2 = 0;
1724 row_index hi_idx2 = rr2.last_idx();
1726 shared.clear(
true,
true);
1729 if(hi_idx1 < lo_idx1){
1732 if(hi_idx2 < lo_idx2){
1736 obj_t& lo_a1 = row<obj_t>::pos(lo_idx1);
1737 obj_t& hi_a1 = row<obj_t>::pos(hi_idx1);
1738 obj_t& lo_a2 = rr2[lo_idx2];
1739 obj_t& hi_a2 = rr2[hi_idx2];
1741 comparison cmp_a1 = (*cmp_fn)(lo_a1, hi_a1);
1742 comparison cmp_a2 = (*cmp_fn)(lo_a2, hi_a2);
1743 comparison cmp_hi1_lo2 = (*cmp_fn)(hi_a1, lo_a2);
1744 comparison cmp_hi2_lo1 = (*cmp_fn)(hi_a2, lo_a1);
1745 comparison cmp_lo1_lo2 = (*cmp_fn)(lo_a1, lo_a2);
1746 comparison cmp_hi1_hi2 = (*cmp_fn)(hi_a1, hi_a2);
1749 TOOLS_CK(cmp_a1 <= 0);
1750 TOOLS_CK(cmp_a2 <= 0);
1752 if(cmp_hi1_lo2 < 0){
1755 if(cmp_hi2_lo1 < 0){
1759 if(cmp_lo1_lo2 < 0){ lo_idx1++; }
1760 if(cmp_lo1_lo2 > 0){ lo_idx2++; }
1761 if(cmp_lo1_lo2 == 0){
1762 TOOLS_CK(lo_a1 == lo_a2);
1764 lo_idx1++; lo_idx2++;
1766 if((cmp_a1 != 0) && (cmp_hi1_hi2 == 0)){
1767 TOOLS_CK(hi_a1 == hi_a2);
1769 hi_idx1--; hi_idx2--;
1771 if(cmp_hi1_hi2 < 0){ hi_idx2--; }
1772 if(cmp_hi1_hi2 > 0){ hi_idx1--; }
1776 template<
class obj_t>
1778 row<obj_t>::sorted_set_adhere(row<obj_t>&
set, cmp_func_t cmp_fn){
1782 if(row<obj_t>::is_empty()){
1787 DBG(
bool is_sted = row<obj_t>::is_sorted(cmp_fn));
1789 DBG(
bool is_sted_set =
set.is_sorted(cmp_fn));
1790 TOOLS_CK(is_sted_set);
1793 row_index s_idx =
set.last_idx();
1794 row<obj_t>::set_cap(row<obj_t>::size() +
set.size());
1796 row_index m_idx = row<obj_t>::last_idx();
1797 minc_sz(
set.size());
1798 row_index a_idx = row<obj_t>::last_idx();
1801 obj_t& s_obj =
set[s_idx];
1803 TOOLS_CK((s_idx < 0) || (cmp_fn(
set[s_idx], s_obj) < 0));
1804 comparison cmp_val = 1;
1805 while((m_idx >= 0) &&
1806 ((cmp_val = cmp_fn(s_obj, row<obj_t>::pos(m_idx))) < 0))
1808 row<obj_t>::swap(m_idx, a_idx);
1812 TOOLS_CK((m_idx < 0) || (cmp_val > 0));
1813 row<obj_t>::pos(a_idx) = s_obj;
1817 DBG(is_sted = row<obj_t>::is_sorted(cmp_fn));
1821 template<
class obj_t>
1823 row<obj_t>::sorted_set_reduce(row<obj_t>&
set, cmp_func_t cmp_fn){
1827 DBG(
bool is_sted = row<obj_t>::is_sorted(cmp_fn));
1829 DBG(
bool is_sted_set =
set.is_sorted(cmp_fn));
1830 TOOLS_CK(is_sted_set);
1832 row_index s_idx = 0;
1833 row_index d_idx = 0;
1836 while(s_idx <
set.size()){
1837 TOOLS_CK(d_idx < row<obj_t>::size());
1839 while((cmp_val = cmp_fn(
set[s_idx], row<obj_t>::pos(d_idx))) > 0){
1841 row<obj_t>::pos(d_idx - num_reds) = row<obj_t>::pos(d_idx);
1844 TOOLS_CK(d_idx < row<obj_t>::size());
1846 TOOLS_CK(cmp_val == 0);
1851 while(d_idx < row<obj_t>::size()){
1852 TOOLS_CK(num_reds > 0);
1853 row<obj_t>::pos(d_idx - num_reds) = row<obj_t>::pos(d_idx);
1856 row<obj_t>::clear(
true,
false, d_idx - num_reds);
1858 DBG(is_sted = row<obj_t>::is_sorted(cmp_fn));
1891 template<
class obj_t>
1893 row<obj_t>::mix_sort(cmp_func_t cmp_fn){
1894 if(SZ_ATTRIB < SELEC_SORT_LIM){
1895 row_data<obj_t>::selec_sort(cmp_fn);
1897 heap<obj_t> he1(*
this, cmp_fn);
1903 template<
class obj_t>
1905 heap<obj_t>::build(){
1906 for(row_index ii = (SZ_ATTRIB)/2; ii >= 0; ii--){ heapify(ii); }
1909 template<
class obj_t>
1911 heap<obj_t>::heapify(row_index idx){
1915 row_index lft = left(idx);
1916 row_index rgt = right(idx);
1917 row_index maxx = idx;
1918 if((lft < SZ_ATTRIB) && (cmp(lft, maxx) > 0)){ maxx = lft; }
1919 if((rgt < SZ_ATTRIB) && (cmp(rgt, maxx) > 0)){ maxx = rgt; }
1921 row_data<obj_t>::swap(idx, maxx);
1932 template<
class obj_t>
1934 heap<obj_t>::changed_key(row_index idx){
1935 row_index ii = idx, pp = parent(idx);
1936 obj_t the_obj = row<obj_t>::pos(idx);
1938 for(; (ii > 0) && (pp >= 0) && (cmp_obj(pp, the_obj) < 0); ii = pp, pp = parent(ii)){
1939 row<obj_t>::pos(ii) = row<obj_t>::pos(pp);
1942 row<obj_t>::pos(ii) = the_obj;
1948 template<
class obj_t>
1950 heap<obj_t>::insert(obj_t n_obj){
1951 row_data<obj_t>::inc_sz();
1952 TOOLS_CK((func_idx == NULL_PT) || ((*func_idx)(n_obj) == INVALID_IDX));
1953 row<obj_t>::pos(SZ_ATTRIB - 1) = n_obj;
1954 update_idx(SZ_ATTRIB - 1);
1955 return changed_key(SZ_ATTRIB - 1);
1958 template<
class obj_t>
1960 heap<obj_t>::pop_top(){
1961 obj_t resp = obj_t();
1962 if(SZ_ATTRIB == 0){
return resp; }
1963 resp = row<obj_t>::pos(0);
1964 if(func_idx != NULL_PT){ (*func_idx)(resp) = INVALID_IDX; }
1966 row<obj_t>::pos(0) = row<obj_t>::pos(SZ_ATTRIB - 1);
1973 template<
class obj_t>
1975 heap<obj_t>::remove(row_index idx){
1976 if(SZ_ATTRIB == 0){
return obj_t(); }
1977 obj_t obj = row_data<obj_t>::swap_pop(idx);
1978 if(func_idx != NULL_PT){ (*func_idx)(obj) = INVALID_IDX; }
1985 template<
class obj_t>
1987 heap<obj_t>::print_heap(bj_ostream& os, row_index idx){
1989 for(row_index ii = 0; ii < SZ_ATTRIB; ii++){
1994 os << row<obj_t>::pos(ii);
1995 if(func_idx != NULL_PT){ os <<
"@" << (*func_idx)(row<obj_t>::pos(ii)); }
2002 template<
class obj_t>
2004 heap<obj_t>::dbg_is_heap_ok(row_index idx){
2005 row_index lft = left(idx);
2006 row_index rgt = right(idx);
2007 row_index maxx = idx;
2008 if((lft < SZ_ATTRIB) && (cmp(lft, maxx) > 0)){ maxx = lft; }
2009 if((rgt < SZ_ATTRIB) && (cmp(rgt, maxx) > 0)){ maxx = rgt; }
2010 if(maxx != idx){
return false; }
2011 if((func_idx != NULL_PT) && (idx != (*func_idx)(row<obj_t>::pos(idx)))){
2014 if((lft < SZ_ATTRIB) && !dbg_is_heap_ok(lft)){
return false; }
2015 if((rgt < SZ_ATTRIB) && !dbg_is_heap_ok(rgt)){
return false; }
2022 typedef row<ch_string> row_str_t;
2036 void init_average(bj_big_float_t the_avg = 0, bj_big_int_t the_sz = 0){
2041 void add_val(bj_big_float_t val){
2042 if(sz == 0){ sz = 1; avg = val;
return; }
2043 avg = (avg * ((bj_big_float_t)sz / (sz + 1))) + (val / (sz + 1));
2047 void remove_val(bj_big_float_t val){
2048 if(sz == 1){ sz = 0; avg = 0;
return; }
2049 avg = (avg * ((bj_big_float_t)sz / (sz - 1))) - (val / (sz - 1));
2053 bj_ostream& print_average(bj_ostream& os){
2054 os <<
"avg:" << avg <<
" sz:" << sz <<
" ";
2062 bj_ostream& operator << (bj_ostream& os, average& obj){
2063 return obj.print_average(os);
2069 class avg_stat :
public average {
2071 bj_big_float_t vs_tot_val;
2072 bj_big_float_t vs_max_val;
2075 avg_stat(ch_string nam =
"avg?") {
2081 void add_val(bj_big_float_t val){
2083 average::add_val(val);
2084 if(val > vs_max_val){ vs_max_val = val; }
2087 void remove_val(bj_big_float_t val){
2089 average::remove_val(val);
2092 bj_ostream& print_avg_stat(bj_ostream& os);
2098 avg_stat::print_avg_stat(bj_ostream& os){
2099 bj_big_float_t avg_perc = 0.0;
2100 if(vs_max_val > 0.0){
2101 avg_perc = ((avg / vs_max_val) * 100.0);
2108 os <<
" tot=" << vs_tot_val;
2109 os <<
" avg=" << avg;
2110 os <<
" max=" << vs_max_val;
2111 os <<
" (avg/max)=" << avg_perc <<
"%";
2118 bj_ostream& operator << (bj_ostream& os, avg_stat& obj){
2119 return obj.print_avg_stat(os);
2126 class timeout_exception :
public top_exception {
2128 timeout_exception(
long the_id = 0) : top_exception(the_id)
2135 #define MIN_TIMER_PERIOD 0.0 2136 #define MIN_TIMER_TIMEOUT 0.0 2143 typedef void (*tmr_func_t)(
void* pm,
double curr_secs);
2148 double tmr_start_secs;
2149 double tmr_last_secs;
2150 double tmr_desired_secs;
2151 double tmr_desired_timeout;
2154 double tmr_current_cycle;
2156 bool tmr_force_check;
2158 bool tmr_first_cycle;
2160 bool tmr_is_periodic;
2161 bool tmr_has_timeout;
2163 timer(
double period = 4.0,
double tm_out = 0.0){
2164 init_timer(period, tm_out);
2167 void init_timer(
double period = 4.0,
double tm_out = 0.0){
2168 tmr_reporting =
false;
2169 tmr_start_secs = 0.0;
2170 tmr_last_secs = 0.0;
2171 tmr_desired_secs = period;
2172 tmr_desired_timeout = tm_out;
2175 tmr_current_cycle = 0;
2177 tmr_force_check =
false;
2179 tmr_first_cycle =
true;
2181 tmr_is_periodic = (tmr_desired_secs > MIN_TIMER_PERIOD);
2182 tmr_has_timeout = (tmr_desired_timeout > MIN_TIMER_TIMEOUT);
2185 double elapsed_time(
double current_secs = 0.0){
2186 if(current_secs == 0.0){
2187 current_secs = run_time();
2189 double s_time = (current_secs - tmr_start_secs);
2193 double period_time(
double current_secs = 0.0){
2194 if(current_secs == 0.0){
2195 current_secs = run_time();
2197 double p_time = (current_secs - tmr_last_secs);
2201 bool check_period(tmr_func_t fn = NULL_PT,
void* pm = NULL_PT);
2206 timer::check_period(tmr_func_t tmr_fn,
void* pm_fn){
2207 if(! tmr_has_timeout && ! tmr_is_periodic){
2211 tmr_current_cycle++;
2213 bool is_over =
false;
2214 bool is_period = (tmr_current_cycle >= tmr_cycles);
2216 if(is_period || tmr_force_check){
2217 tmr_force_check =
false;
2218 double tmr_current_secs = run_time();
2219 if(tmr_first_cycle){
2220 tmr_first_cycle =
false;
2221 TOOLS_CK(tmr_start_secs == 0.0);
2222 tmr_start_secs = tmr_current_secs;
2223 tmr_last_secs = tmr_current_secs;
2225 TOOLS_CK(tmr_current_secs >= tmr_start_secs);
2227 tmr_current_cycle = 0;
2228 double real_period = (tmr_current_secs - tmr_last_secs);
2229 tmr_last_secs = tmr_current_secs;
2231 if(real_period < tmr_desired_secs){
2233 }
else if(tmr_cycles > 2.0){
2236 TOOLS_CK(tmr_cycles >= 1.0);
2238 double elpsd_tm = elapsed_time(tmr_current_secs);
2239 if(! tmr_reporting &&
2240 (elpsd_tm > tmr_desired_secs))
2242 tmr_reporting =
true;
2245 if(tmr_has_timeout){
2246 is_over = (elpsd_tm > tmr_desired_timeout);
2249 bool report_prd = tmr_reporting && ! is_over &&
2251 ( ! tmr_force_check ||
2252 (real_period >= tmr_desired_secs));
2254 if(report_prd && (tmr_fn != NULL_PT)){
2255 (*tmr_fn)(pm_fn, tmr_current_secs);