1 #ifndef _GLUCAT_INDEX_SET_IMP_H
2 #define _GLUCAT_INDEX_SET_IMP_H
45 template<const index_t LO, const index_t HI>
50 {
return "index_set"; }
53 template<const index_t LO, const index_t HI>
59 template<const index_t LO, const index_t HI>
66 template<const index_t LO, const index_t HI>
68 index_set(
const set_value_t folded_val,
const index_set_t frm,
const bool prechecked)
70 if (!prechecked && folded_val >=
set_value_t(1 << frm.count()))
71 throw error_t(
"index_set(val,frm): cannot create: value gives an index set outside of frame");
72 const index_set_t folded_frame = frm.fold();
73 const index_t min_index = folded_frame.min();
74 const index_t skip = min_index > 0 ? 1 : 0;
75 const index_set_t folded_set = index_set_t(bitset_t(folded_val) << (min_index - skip - LO));
76 *
this = folded_set.unfold(frm);
80 template<const index_t LO, const index_t HI>
82 index_set(
const index_pair_t& range,
const bool prechecked)
84 if (!prechecked && (range.first < LO || range.second > HI))
85 throw error_t(
"index_set(range): cannot create: range is too large");
86 const index_t begin_bit = (range.first < 0)
89 const index_t end_bit = (range.second < 0)
92 unsigned long mask = ( (end_bit == _GLUCAT_BITS_PER_ULONG)
94 : (1UL << end_bit)-1UL)
95 & ~((1UL << begin_bit)-1UL);
100 template<const index_t LO, const index_t HI>
104 std::istringstream ss(str);
107 throw error_t(
"index_set_t(str): could not parse string");
111 throw error_t(
"index_set_t(str): could not parse entire string");
115 template<const index_t LO, const index_t HI>
122 return *pthis ==
static_cast<bitset_t>(rhs);
126 template<const index_t LO, const index_t HI>
133 return *pthis !=
static_cast<bitset_t>(rhs);
137 template<const index_t LO, const index_t HI>
142 {
return bitset_t::operator~(); }
145 template<const index_t LO, const index_t HI>
157 template<const index_t LO, const index_t HI>
170 template<const index_t LO, const index_t HI>
182 template<const index_t LO, const index_t HI>
190 typedef typename index_set_t::bitset_t bitset_t;
191 return static_cast<bitset_t
>(lhs) &
static_cast<bitset_t
>(rhs);
195 template<const index_t LO, const index_t HI>
207 template<const index_t LO, const index_t HI>
215 typedef typename index_set_t::bitset_t bitset_t;
216 return static_cast<bitset_t
>(lhs) |
static_cast<bitset_t
>(rhs);
220 template<const index_t LO, const index_t HI>
222 typename index_set<LO,HI>::reference
225 {
return reference(*
this, idx); }
228 template<const index_t LO, const index_t HI>
233 {
return this->test(idx); }
236 template<const index_t LO, const index_t HI>
244 ? bool(bitset_t::to_ulong() & (1UL << (idx - LO)))
246 ?
bool(bitset_t::to_ulong() & (1UL << (idx - LO - 1)))
251 template<const index_t LO, const index_t HI>
262 template<const index_t LO, const index_t HI>
269 bitset_t::set(idx-LO-1);
271 bitset_t::set(idx-LO);
276 template<const index_t LO, const index_t HI>
283 bitset_t::set(idx-LO-1, val);
285 bitset_t::set(idx-LO, val);
290 template<const index_t LO, const index_t HI>
301 template<const index_t LO, const index_t HI>
308 bitset_t::reset(idx-LO-1);
310 bitset_t::reset(idx-LO);
315 template<const index_t LO, const index_t HI>
326 template<const index_t LO, const index_t HI>
333 bitset_t::flip(idx-LO-1);
335 bitset_t::flip(idx-LO);
340 template<const index_t LO, const index_t HI>
346 unsigned long val = bitset_t::to_ulong();
360 template<const index_t LO, const index_t HI>
368 return neg_part.
count();
372 template<const index_t LO, const index_t HI>
380 return pos_part.
count();
383 #if (_GLUCAT_BITS_PER_ULONG == 64)
384 template<const index_t LO, const index_t HI>
392 unsigned long val = bitset_t::to_ulong();
397 val -= val & (val-1);
404 if (val & 0xffffffff00000000ul)
406 if (val & 0xffff0000ffff0000ul)
408 if (val & 0xff00ff00ff00ff00ul)
411 if (val & 0xf0f0f0f0f0f0f0f0ul)
413 if (val & 0xccccccccccccccccul)
415 if (val & 0xaaaaaaaaaaaaaaaaul)
418 return idx + ((idx < -LO) ? LO : LO+1);
421 #elif (_GLUCAT_BITS_PER_ULONG == 32)
422 template<const index_t LO, const index_t HI>
430 unsigned long val = bitset_t::to_ulong();
435 val -= val & (val-1);
441 if (val & 0xffff0000ul)
443 if (val & 0xff00ff00ul)
446 if (val & 0xf0f0f0f0ul)
448 if (val & 0xccccccccul)
450 if (val & 0xaaaaaaaaul)
453 return idx + ((idx < -LO) ? LO : LO+1);
457 template<const index_t LO, const index_t HI>
479 #if (_GLUCAT_BITS_PER_ULONG == 64)
480 template<const index_t LO, const index_t HI>
488 unsigned long val = bitset_t::to_ulong();
497 if (val & 0xffffffff00000000ul)
498 { val >>= 32; idx += 32; }
499 if (val & 0x00000000ffff0000ul)
500 { val >>= 16; idx += 16; }
501 if (val & 0x000000000000ff00ul)
502 { val >>= 8; idx += 8; }
504 if (val & 0x00000000000000f0ul)
505 { val >>= 4; idx += 4; }
506 if (val & 0x000000000000000cul)
507 { val >>= 2; idx += 2; }
508 if (val & 0x0000000000000002ul)
510 return idx + ((idx < -LO) ? LO : LO+1);
513 #elif (_GLUCAT_BITS_PER_ULONG == 32)
514 template<const index_t LO, const index_t HI>
522 unsigned long val = bitset_t::to_ulong();
531 if (val & 0xffff0000ul)
532 { val >>= 16; idx += 16; }
533 if (val & 0x0000ff00ul)
534 { val >>= 8; idx += 8; }
536 if (val & 0x000000f0ul)
537 { val >>= 4; idx += 4; }
538 if (val & 0x0000000cul)
539 { val >>= 2; idx += 2; }
540 if (val & 0x00000002ul)
542 return idx + ((idx < -LO) ? LO : LO+1);
546 template<const index_t LO, const index_t HI>
570 template<const index_t LO, const index_t HI>
573 compare(
const index_set<LO,HI>& a,
const index_set<LO,HI>& b)
584 template<const index_t LO, const index_t HI>
589 {
return bitset_t::to_ulong() < rhs.bitset_t::to_ulong(); }
593 template<const index_t LO, const index_t HI>
597 operator< (
const index_set_t rhs)
const
599 const index_t this_grade = this->count();
600 const index_t rhs_grade = rhs.count();
601 return (this_grade < rhs_grade)
603 : (this_grade > rhs_grade)
605 : this->lex_less_than(rhs);
609 template<const index_t LO, const index_t HI>
631 template<const index_t LO, const index_t HI>
640 bool parse_index_list =
true;
641 bool expect_closing_brace =
false;
642 bool expect_index =
false;
647 parse_index_list =
false;
650 expect_closing_brace = (c == int(
'{'));
651 if (expect_closing_brace)
657 if (s.good() && (c == int(
'}')))
659 expect_closing_brace =
false;
663 parse_index_list =
false;
667 if (s.good() && parse_index_list)
674 if ((
i < LO) || (
i > HI))
676 s.clear(std::istream::failbit);
682 expect_index =
false;
694 if (expect_closing_brace && (c ==
int(
'}')))
698 expect_closing_brace =
false;
711 s.clear(std::istream::failbit);
717 if (expect_index || expect_closing_brace)
718 s.clear(std::istream::failbit);
728 template<const index_t LO, const index_t HI>
732 is_contiguous ()
const
734 const index_t min_index = this->min();
735 const index_t max_index = this->max();
736 return (min_index < 0 && max_index > 0)
737 ? max_index - min_index == this->count()
738 : (min_index == 1 || max_index == -1) &&
739 (max_index - min_index == this->count() - 1);
743 template<const index_t LO, const index_t HI>
749 {
return this->fold(*
this,
true); }
752 template<const index_t LO, const index_t HI>
756 fold(
const index_set_t frm,
const bool prechecked)
const
758 if (!prechecked && ((*
this | frm) != frm))
759 throw error_t(
"fold(frm): cannot fold from outside of frame");
761 const index_t frm_max = frm.max();
765 for (unfold_idx = -1;
766 unfold_idx >= frm_min;
768 if (frm.test(unfold_idx))
771 if (this->test(unfold_idx))
772 result.
set(fold_idx);
777 unfold_idx <= frm_max;
779 if (frm.test(unfold_idx))
782 if (this->test(unfold_idx))
783 result.
set(fold_idx);
790 template<const index_t LO, const index_t HI>
794 unfold(
const index_set_t frm,
const bool prechecked)
const
797 "unfold(frm): cannot unfold into a smaller frame";
798 const index_t frm_min = frm.min();
799 const index_t frm_max = frm.max();
803 for (unfold_idx = -1;
804 unfold_idx >= frm_min;
806 if (frm.test(unfold_idx))
807 if (this->test(fold_idx--))
808 result.set(unfold_idx);
809 if (!prechecked && ((fold_idx+1) > this->min()))
813 unfold_idx <= frm_max;
815 if (frm.test(unfold_idx))
816 if (this->test(fold_idx++))
817 result.set(unfold_idx);
818 if (!prechecked && ((fold_idx-1) < this->max()))
824 template<const index_t LO, const index_t HI>
836 const index_t skip = min_index > 0 ? 1 : 0;
837 return folded_set.bitset_t::to_ulong() >> (min_index-LO-skip);
847 #if (_GLUCAT_BITS_PER_ULONG >= 64)
864 #if (_GLUCAT_BITS_PER_ULONG >= 64)
876 template<const index_t LO, const index_t HI>
879 sign_of_mult(
const index_set_t rhs)
const
884 const unsigned long uthis = this->bitset_t::to_ulong();
885 const unsigned long urhs = rhs.bitset_t::to_ulong();
887 unsigned long negative = 0;
898 const unsigned long q =
inverse_gray((uthis & urhs) >> -LO);
910 negative ^= h & (uthis >> j);
916 negative ^= h & (uthis >> j);
920 return 1 - int((negative & 1) << 1);
924 template<const index_t LO, const index_t HI>
930 int result = 1 - int((this->count_neg() % 2) << 1);
931 switch (this->count() % 4)
944 template<const index_t LO, const index_t HI>
950 static const unsigned long lo_mask = (1UL << -LO) - 1UL;
951 const unsigned long uthis = bitset_t::to_ulong();
952 const unsigned long neg_part = uthis & lo_mask;
953 const unsigned long pos_part = uthis >> -LO;
954 return size_t(neg_part ^ pos_part);
961 {
return (j < 0) ? -1 : 1; }
964 template<const index_t LO, const index_t HI>
968 {
return std::min(
ist.min(), 0); }
971 template<const index_t LO, const index_t HI>
975 {
return std::max(
ist.max(), 0); }
980 template<const index_t LO, const index_t HI>
989 template<const index_t LO, const index_t HI>
1003 template<const index_t LO, const index_t HI>
1009 if ( (j.m_pst)[j.m_idx] )
1012 m_pst->reset(m_idx);
1017 template<const index_t LO, const index_t HI>
1022 {
return !(m_pst->test(m_idx)); }
1025 template<const index_t LO, const index_t HI>
1028 operator bool ()
const
1029 {
return m_pst->test(m_idx); }
1032 template<const index_t LO, const index_t HI>
1042 #endif // _GLUCAT_INDEX_SET_IMP_H