1/* 2================================================================================ 3 PROJECT: 4 5 Eddy C++ Utilities Project 6 7 CONTENTS: 8 9 Inline methods of class bit_mask. 10 11 NOTES: 12 13 See notes of bit_mask.hpp. 14 15 PROGRAMMERS: 16 17 John Eddy (jpeddy@sandia.gov) (JE) 18 19 ORGANIZATION: 20 21 Sandia National Laboratories 22 23 COPYRIGHT: 24 25 See the LICENSE file in the top level JEGA directory. 26 27 VERSION: 28 29 1.0.0 30 31 CHANGES: 32 33 Tue Apr 18 09:41:35 2006 - Original Version (JE) 34 35================================================================================ 36*/ 37 38 39 40 41/* 42================================================================================ 43Document This File 44================================================================================ 45*/ 46/** \file 47 * \brief Contains the inline methods of the bit_mask class. 48 */ 49 50 51 52 53/* 54================================================================================ 55Includes 56================================================================================ 57*/ 58 59 60 61 62 63 64 65 66/* 67================================================================================ 68Begin Namespace 69================================================================================ 70*/ 71namespace eddy { 72 namespace utilities { 73 74 75 76 77 78/* 79================================================================================ 80Static Member Data Definitions 81================================================================================ 82*/ 83 84 85 86 87/* 88================================================================================ 89Facade Implementation 90================================================================================ 91*/ 92 93template <typename MDT, typename BS_T> 94inline 95MDT& 96bit_mask_facade<MDT, BS_T>::set( 97 ) 98{ 99 EDDY_FUNC_DEBUGSCOPE 100 this->casted().clear(true); 101 return this->casted(); 102} 103 104template <typename MDT, typename BS_T> 105inline 106MDT& 107bit_mask_facade<MDT, BS_T>::set( 108 const bit_index& bitloc, 109 bool to 110 ) 111{ 112 EDDY_FUNC_DEBUGSCOPE 113 this->casted().set_bit(bitloc, to); 114 return this->casted(); 115} 116 117template <typename MDT, typename BS_T> 118inline 119MDT& 120bit_mask_facade<MDT, BS_T>::reset( 121 ) 122{ 123 EDDY_FUNC_DEBUGSCOPE 124 this->casted().clear(); 125 return this->casted(); 126} 127 128template <typename MDT, typename BS_T> 129inline 130MDT& 131bit_mask_facade<MDT, BS_T>::reset( 132 const bit_index& bitloc 133 ) 134{ 135 EDDY_FUNC_DEBUGSCOPE 136 this->casted().set_bit(bitloc, false); 137 return casted(); 138} 139 140 141template <typename MDT, typename BS_T> 142inline 143typename bit_mask_facade<MDT, BS_T>::iterator 144bit_mask_facade<MDT, BS_T>::begin( 145 ) 146{ 147 EDDY_FUNC_DEBUGSCOPE 148 return iterator(this->casted(), 0); 149} 150 151template <typename MDT, typename BS_T> 152inline 153typename bit_mask_facade<MDT, BS_T>::const_iterator 154bit_mask_facade<MDT, BS_T>::begin( 155 ) const 156{ 157 EDDY_FUNC_DEBUGSCOPE 158 return const_iterator(this->casted(), 0); 159} 160 161template <typename MDT, typename BS_T> 162inline 163typename bit_mask_facade<MDT, BS_T>::iterator 164bit_mask_facade<MDT, BS_T>::end( 165 ) 166{ 167 EDDY_FUNC_DEBUGSCOPE 168 return iterator(this->casted(), this->casted().num_usable_bits()); 169} 170 171template <typename MDT, typename BS_T> 172inline 173typename bit_mask_facade<MDT, BS_T>::const_iterator 174bit_mask_facade<MDT, BS_T>::end( 175 ) const 176{ 177 EDDY_FUNC_DEBUGSCOPE 178 return const_iterator(this->casted(), this->casted().num_usable_bits()); 179} 180 181template <typename MDT, typename BS_T> 182inline 183typename bit_mask_facade<MDT, BS_T>::reverse_iterator 184bit_mask_facade<MDT, BS_T>::rbegin( 185 ) 186{ 187 EDDY_FUNC_DEBUGSCOPE 188 return reverse_iterator( 189 casted(), 190 static_cast<eddy::utilities::intmax_t>( 191 this->casted().num_usable_bits() 192 ) - 1 193 ); 194} 195 196template <typename MDT, typename BS_T> 197inline 198typename bit_mask_facade<MDT, BS_T>::const_reverse_iterator 199bit_mask_facade<MDT, BS_T>::rbegin( 200 ) const 201{ 202 EDDY_FUNC_DEBUGSCOPE 203 return const_reverse_iterator( 204 casted(), 205 static_cast<eddy::utilities::intmax_t>( 206 this->casted().num_usable_bits() 207 ) - 1 208 ); 209} 210 211template <typename MDT, typename BS_T> 212inline 213typename bit_mask_facade<MDT, BS_T>::reverse_iterator 214bit_mask_facade<MDT, BS_T>::rend( 215 ) 216{ 217 EDDY_FUNC_DEBUGSCOPE 218 return reverse_iterator(this->casted(), -1); 219} 220 221template <typename MDT, typename BS_T> 222inline 223typename bit_mask_facade<MDT, BS_T>::const_reverse_iterator 224bit_mask_facade<MDT, BS_T>::rend( 225 ) const 226{ 227 EDDY_FUNC_DEBUGSCOPE 228 return const_reverse_iterator(this->casted(), -1); 229} 230 231 232template <typename MDT, typename BS_T> 233inline 234MDT& 235bit_mask_facade<MDT, BS_T>::flip( 236 ) 237{ 238 EDDY_FUNC_DEBUGSCOPE 239 this->casted().toggle_all(); 240 return this->casted(); 241} 242 243template <typename MDT, typename BS_T> 244inline 245MDT& 246bit_mask_facade<MDT, BS_T>::flip( 247 const bit_index& bitloc 248 ) 249{ 250 EDDY_FUNC_DEBUGSCOPE 251 this->casted().toggle_bit(bitloc); 252 return this->casted(); 253} 254 255template <typename MDT, typename BS_T> 256inline 257typename bit_mask_facade<MDT, BS_T>::const_bit_location 258bit_mask_facade<MDT, BS_T>::get_bit_location( 259 const bit_index& bitloc 260 ) const 261{ 262 EDDY_FUNC_DEBUGSCOPE 263 EDDY_ASSERT(bitloc < this->casted().num_usable_bits()); 264 265 if(bitloc >= this->casted().num_usable_bits()) 266 throw std::out_of_range("invalid bit_mask position"); 267 268 return const_bit_location( 269 this->casted().member_at(bitloc), 270 this->to_bits(this->member_bit(bitloc)) 271 ); 272} 273 274template <typename MDT, typename BS_T> 275inline 276typename bit_mask_facade<MDT, BS_T>::bit_location 277bit_mask_facade<MDT, BS_T>::get_bit_location( 278 const bit_index& bitloc 279 ) 280{ 281 EDDY_FUNC_DEBUGSCOPE 282 EDDY_ASSERT(bitloc < this->casted().num_usable_bits()); 283 284 if(bitloc >= this->casted().num_usable_bits()) 285 throw std::out_of_range("invalid bit_mask position"); 286 287 return bit_location( 288 this->casted().member_at(bitloc), 289 this->to_bits(this->member_bit(bitloc)) 290 ); 291} 292 293template <typename MDT, typename BS_T> 294inline 295bool 296bit_mask_facade<MDT, BS_T>::contains( 297 const most_derived_type& other 298 ) const 299{ 300 EDDY_FUNC_DEBUGSCOPE 301 return (this == &other) ? true : ((*this & other) == other); 302} 303 304template <typename MDT, typename BS_T> 305inline 306typename bit_mask_facade<MDT, BS_T>::size_type 307bit_mask_facade<MDT, BS_T>::count( 308 bool val 309 ) const 310{ 311 EDDY_FUNC_DEBUGSCOPE 312 size_type ct = std::accumulate(this->begin(), this->end(), 0U); 313 return val ? ct : (this->casted().num_usable_bits() - ct); 314} 315 316template <typename MDT, typename BS_T> 317inline 318bool 319bit_mask_facade<MDT, BS_T>::any( 320 ) const 321{ 322 EDDY_FUNC_DEBUGSCOPE 323 return std::find(this->begin(), this->end(), true) != this->end(); 324} 325 326template <typename MDT, typename BS_T> 327inline 328bool 329bit_mask_facade<MDT, BS_T>::none( 330 ) const 331{ 332 EDDY_FUNC_DEBUGSCOPE 333 return !this->any(); 334} 335 336template <typename MDT, typename BS_T> 337inline 338typename bit_mask_facade<MDT, BS_T>::bit_index 339bit_mask_facade<MDT, BS_T>::size( 340 ) const 341{ 342 EDDY_FUNC_DEBUGSCOPE 343 return this->casted().num_usable_bits(); 344} 345 346template <typename MDT, typename BS_T> 347inline 348bool 349bit_mask_facade<MDT, BS_T>::test( 350 const bit_index& bitloc 351 ) const 352{ 353 EDDY_FUNC_DEBUGSCOPE 354 return this->casted().get_bit(bitloc); 355} 356 357template <typename MDT, typename BS_T> 358unsigned long 359bit_mask_facade<MDT, BS_T>::to_ulong( 360 ) const 361{ 362 EDDY_FUNC_DEBUGSCOPE 363 EDDY_ASSERT(this->casted().num_usable_bits() <= (sizeof(unsigned long)*8)); 364 365 if(this->casted().num_usable_bits() > (sizeof(unsigned long)*8)) 366 throw std::overflow_error("bit_mask overflow"); 367 368 // prepare a return value. Initialize it to the first array element. 369 unsigned long ret = 0; 370 371 // now iterate this bit mask and insert the bits to ret. 372 size_type num_bits = this->casted().num_usable_bits(); 373 for(bit_index i=0; i<num_bits; ++i) 374 ret |= (this->test(i) ? 1UL : 0UL) << i; 375 376 return ret; 377} 378 379template <typename MDT, typename BS_T> 380inline 381MDT 382bit_mask_facade<MDT, BS_T>::operator ~( 383 ) const 384{ 385 EDDY_FUNC_DEBUGSCOPE 386 return most_derived_type(this->casted()).flip(); 387} 388 389template <typename MDT, typename BS_T> 390inline 391typename bit_mask_facade<MDT, BS_T>::const_bit_location 392bit_mask_facade<MDT, BS_T>::operator []( 393 const bit_index& bitloc 394 ) const 395{ 396 EDDY_FUNC_DEBUGSCOPE 397 return this->get_bit_location(bitloc); 398} 399 400template <typename MDT, typename BS_T> 401inline 402typename bit_mask_facade<MDT, BS_T>::bit_location 403bit_mask_facade<MDT, BS_T>::operator []( 404 const bit_index& bitloc 405 ) 406{ 407 EDDY_FUNC_DEBUGSCOPE 408 return this->get_bit_location(bitloc); 409} 410 411template <typename MDT, typename BS_T> 412MDT& 413bit_mask_facade<MDT, BS_T>::operator >>=( 414 const bit_index& off 415 ) 416{ 417 EDDY_FUNC_DEBUGSCOPE 418 419 // if the ofset is greater than (or equal to) the number of useable 420 // bits, we can just clear the mask. 421 if(off >= this->casted().num_usable_bits()) 422 { this->reset(); return this->casted(); } 423 424 const_iterator from(this->casted().begin() + off); 425 iterator to(this->begin()); 426 const_iterator e(this->end()); 427 428 for(; from!=e; ++from, ++to) *to = *from; 429 for(; to!=e; ++to) *to = false; 430 return this->casted(); 431} 432 433template <typename MDT, typename BS_T> 434MDT 435bit_mask_facade<MDT, BS_T>::operator >>( 436 const bit_index& off 437 ) 438{ 439 EDDY_FUNC_DEBUGSCOPE 440 return most_derived_type(this->casted()) >>= off; 441} 442 443template <typename MDT, typename BS_T> 444MDT& 445bit_mask_facade<MDT, BS_T>::operator <<=( 446 const bit_index& off 447 ) 448{ 449 EDDY_FUNC_DEBUGSCOPE 450 451 // if the ofset is greater than (or equal to) the number of useable 452 // bits, we can just clear the mask. 453 if(off >= this->casted().num_usable_bits()) 454 { this->reset(); return this->casted(); } 455 456 const_reverse_iterator from(this->rbegin() + off); 457 reverse_iterator to(this->rbegin()); 458 const_reverse_iterator e(this->rend()); 459 460 for(; from!=e; ++from, ++to) *to = *from; 461 for(; to!=e; ++to) *to = false; 462 return this->casted(); 463} 464 465template <typename MDT, typename BS_T> 466MDT 467bit_mask_facade<MDT, BS_T>::operator <<( 468 const bit_index& off 469 ) 470{ 471 EDDY_FUNC_DEBUGSCOPE 472 return most_derived_type(this->casted()) <<= off; 473} 474 475 476template <typename MDT, typename BS_T> 477inline 478typename bit_mask_facade<MDT, BS_T>::bit_index 479bit_mask_facade<MDT, BS_T>::member_index( 480 const bit_index& bitloc 481 ) const 482{ 483 EDDY_FUNC_DEBUGSCOPE 484 EDDY_ASSERT(bitloc < this->casted().num_usable_bits()); 485 return bitloc/MEMBER_BIT_COUNT; 486} 487 488template <typename MDT, typename BS_T> 489inline 490typename bit_mask_facade<MDT, BS_T>::bit_index 491bit_mask_facade<MDT, BS_T>::member_bit( 492 const bit_index& bitloc 493 ) const 494{ 495 EDDY_FUNC_DEBUGSCOPE 496 EDDY_ASSERT(bitloc < this->casted().num_usable_bits()); 497 return bitloc%MEMBER_BIT_COUNT; 498} 499 500template <typename MDT, typename BS_T> 501inline 502typename bit_mask_facade<MDT, BS_T>::bit_store_type 503bit_mask_facade<MDT, BS_T>::to_bits( 504 bit_index memloc 505 ) 506{ 507 EDDY_FUNC_DEBUGSCOPE 508 EDDY_ASSERT(memloc < MEMBER_BIT_COUNT); 509 return static_cast<bit_store_type>(1 << memloc); 510} 511 512template <typename MDT, typename BS_T> 513inline 514MDT& 515bit_mask_facade<MDT, BS_T>::casted( 516 ) 517{ 518 return static_cast<MDT&>(*this); 519} 520 521template <typename MDT, typename BS_T> 522inline 523const MDT& 524bit_mask_facade<MDT, BS_T>::casted( 525 ) const 526{ 527 return static_cast<const MDT&>(*this); 528} 529 530 531 532 533 534/* 535================================================================================ 536Nested Utility Class Implementations 537================================================================================ 538*/ 539template <typename MDT, typename BS_T> 540inline 541bit_mask_facade<MDT, BS_T>::const_bit_location::operator bool( 542 ) const 543{ 544 EDDY_FUNC_DEBUGSCOPE 545 return (this->_maskElem & this->_locMask) != 0; 546} 547 548template <typename MDT, typename BS_T> 549inline 550bool 551bit_mask_facade<MDT, BS_T>::const_bit_location::operator ==( 552 bool lval 553 ) const 554{ 555 EDDY_FUNC_DEBUGSCOPE 556 return this->operator bool() == lval; 557} 558 559template <typename MDT, typename BS_T> 560inline 561bool 562bit_mask_facade<MDT, BS_T>::const_bit_location::operator ~( 563 ) const 564{ 565 EDDY_FUNC_DEBUGSCOPE 566 return !this->operator bool(); 567} 568 569template <typename MDT, typename BS_T> 570inline 571bool 572bit_mask_facade<MDT, BS_T>::const_bit_location::operator &( 573 bool rhs 574 ) const 575{ 576 EDDY_FUNC_DEBUGSCOPE 577 return this->operator bool() && rhs; 578} 579 580template <typename MDT, typename BS_T> 581inline 582bool 583bit_mask_facade<MDT, BS_T>::const_bit_location::operator |( 584 bool rhs 585 ) const 586{ 587 EDDY_FUNC_DEBUGSCOPE 588 return this->operator bool() || rhs; 589} 590 591template <typename MDT, typename BS_T> 592inline 593bool 594bit_mask_facade<MDT, BS_T>::const_bit_location::operator ^( 595 bool rhs 596 ) const 597{ 598 EDDY_FUNC_DEBUGSCOPE 599 // can I us ^ here??? Depends on if a bool can ever have bits other 600 // than 00000000 or 00000001. 601 bool me = this->operator bool(); 602 return me || rhs && me != rhs; 603} 604 605template <typename MDT, typename BS_T> 606inline 607bool 608bit_mask_facade<MDT, BS_T>::const_bit_location::operator -( 609 bool rhs 610 ) const 611{ 612 EDDY_FUNC_DEBUGSCOPE 613 return !this->operator bool(); 614} 615 616template <typename MDT, typename BS_T> 617inline 618typename bit_mask_facade<MDT, BS_T>::bit_store_type& 619bit_mask_facade<MDT, BS_T>::const_bit_location::my_mask_elem( 620 ) 621{ 622 EDDY_FUNC_DEBUGSCOPE 623 return const_cast<bit_store_type&>(this->_maskElem); 624} 625 626template <typename MDT, typename BS_T> 627inline 628const typename bit_mask_facade<MDT, BS_T>::bit_store_type& 629bit_mask_facade<MDT, BS_T>::const_bit_location::my_loc_mask( 630 ) 631{ 632 EDDY_FUNC_DEBUGSCOPE 633 return this->_locMask; 634} 635 636 637template <typename MDT, typename BS_T> 638inline 639bit_mask_facade<MDT, BS_T>::const_bit_location::const_bit_location( 640 const const_bit_location& copy 641 ) : 642 _maskElem(copy._maskElem), 643 _locMask(copy._locMask) 644{ 645 EDDY_FUNC_DEBUGSCOPE 646} 647 648template <typename MDT, typename BS_T> 649inline 650bit_mask_facade<MDT, BS_T>::const_bit_location::const_bit_location( 651 const bit_store_type& maskmem, 652 bit_store_type locmask 653 ) : 654 _maskElem(maskmem), 655 _locMask(locmask) 656{ 657 EDDY_FUNC_DEBUGSCOPE 658} 659 660template <typename MDT, typename BS_T> 661inline 662typename bit_mask_facade<MDT, BS_T>::bit_location& 663bit_mask_facade<MDT, BS_T>::bit_location::flip( 664 ) 665{ 666 EDDY_FUNC_DEBUGSCOPE 667 this->my_mask_elem() ^= this->my_loc_mask(); 668 return *this; 669} 670 671template <typename MDT, typename BS_T> 672inline 673typename bit_mask_facade<MDT, BS_T>::bit_location& 674bit_mask_facade<MDT, BS_T>::bit_location::operator =( 675 bool rhs 676 ) 677{ 678 EDDY_FUNC_DEBUGSCOPE 679 bit_store_type& me = this->my_mask_elem(); 680 rhs ? me |= this->my_loc_mask() : me &= ~this->my_loc_mask(); 681 return *this; 682} 683 684template <typename MDT, typename BS_T> 685inline 686typename bit_mask_facade<MDT, BS_T>::bit_location& 687bit_mask_facade<MDT, BS_T>::bit_location::operator &=( 688 bool rhs 689 ) 690{ 691 EDDY_FUNC_DEBUGSCOPE 692 if(!rhs) this->operator =(false); 693 return *this; 694} 695 696template <typename MDT, typename BS_T> 697inline 698typename bit_mask_facade<MDT, BS_T>::bit_location& 699bit_mask_facade<MDT, BS_T>::bit_location::operator |=( 700 bool rhs 701 ) 702{ 703 EDDY_FUNC_DEBUGSCOPE 704 if(rhs) this->operator =(true); 705 return *this; 706} 707 708template <typename MDT, typename BS_T> 709inline 710typename bit_mask_facade<MDT, BS_T>::bit_location& 711bit_mask_facade<MDT, BS_T>::bit_location::operator ^=( 712 bool rhs 713 ) 714{ 715 EDDY_FUNC_DEBUGSCOPE 716 if(rhs) this->flip(); 717 return *this; 718} 719 720template <typename MDT, typename BS_T> 721inline 722typename bit_mask_facade<MDT, BS_T>::bit_location& 723bit_mask_facade<MDT, BS_T>::bit_location::operator -=( 724 bool rhs 725 ) 726{ 727 EDDY_FUNC_DEBUGSCOPE 728 return this->flip(); 729} 730 731template <typename MDT, typename BS_T> 732inline 733bit_mask_facade<MDT, BS_T>::bit_location::bit_location( 734 const bit_location& copy 735 ) : 736 const_bit_location(copy) 737{ 738 EDDY_FUNC_DEBUGSCOPE 739} 740 741template <typename MDT, typename BS_T> 742inline 743bit_mask_facade<MDT, BS_T>::bit_location::bit_location( 744 const bit_store_type& maskmem, 745 bit_store_type locmask 746 ) : 747 const_bit_location(maskmem, locmask) 748{ 749 EDDY_FUNC_DEBUGSCOPE 750} 751 752 753 754 755 756 757 758template <typename MDT, typename BS_T> 759inline 760const typename bit_mask_facade<MDT, BS_T>::const_iterator& 761bit_mask_facade<MDT, BS_T>::const_iterator::operator =( 762 const const_iterator& rhs 763 ) 764{ 765 EDDY_FUNC_DEBUGSCOPE 766 if(&rhs == this) return rhs; 767 768 this->_theMask = rhs._theMask; 769 this->_bitloc = rhs._bitloc; 770 771 return *this; 772} 773 774template <typename MDT, typename BS_T> 775inline 776bool 777bit_mask_facade<MDT, BS_T>::const_iterator::operator ==( 778 const const_iterator& rhs 779 ) const 780{ 781 EDDY_FUNC_DEBUGSCOPE 782 return (this->_bitloc == rhs._bitloc) && 783 (this->_theMask == rhs._theMask); 784} 785 786template <typename MDT, typename BS_T> 787inline 788bool 789bit_mask_facade<MDT, BS_T>::const_iterator::operator <( 790 const const_iterator& rhs 791 ) const 792{ 793 EDDY_FUNC_DEBUGSCOPE 794 EDDY_ASSERT(rhs._theMask == this->_theMask); 795 return this->_bitloc < rhs._bitloc; 796} 797 798template <typename MDT, typename BS_T> 799inline 800bool 801bit_mask_facade<MDT, BS_T>::const_iterator::operator >( 802 const const_iterator& rhs 803 ) const 804{ 805 EDDY_FUNC_DEBUGSCOPE 806 EDDY_ASSERT(rhs._theMask == this->_theMask); 807 return this->_bitloc > rhs._bitloc; 808} 809 810template <typename MDT, typename BS_T> 811inline 812typename bit_mask_facade<MDT, BS_T>::const_iterator& 813bit_mask_facade<MDT, BS_T>::const_iterator::operator ++( 814 ) 815{ 816 EDDY_FUNC_DEBUGSCOPE 817 ++this->_bitloc; 818 return *this; 819} 820 821template <typename MDT, typename BS_T> 822inline 823typename bit_mask_facade<MDT, BS_T>::const_iterator& 824bit_mask_facade<MDT, BS_T>::const_iterator::operator --( 825 ) 826{ 827 EDDY_FUNC_DEBUGSCOPE 828 --this->_bitloc; 829 return *this; 830} 831 832template <typename MDT, typename BS_T> 833inline 834typename bit_mask_facade<MDT, BS_T>::const_iterator::difference_type 835bit_mask_facade<MDT, BS_T>::const_iterator::operator -( 836 const const_iterator& rhs 837 ) const 838{ 839 EDDY_FUNC_DEBUGSCOPE 840 EDDY_ASSERT(rhs._theMask == this->_theMask); 841 if(rhs._theMask != this->_theMask) 842 throw std::logic_error( 843 "subtraction of iterators to different bit masks" 844 ); 845 846 return this->_bitloc - rhs._bitloc; 847} 848 849template <typename MDT, typename BS_T> 850inline 851typename bit_mask_facade<MDT, BS_T>::const_iterator& 852bit_mask_facade<MDT, BS_T>::const_iterator::operator +=( 853 difference_type diff 854 ) 855{ 856 EDDY_FUNC_DEBUGSCOPE 857 this->_bitloc += diff; 858 return *this; 859} 860 861template <typename MDT, typename BS_T> 862inline 863typename bit_mask_facade<MDT, BS_T>::const_iterator& 864bit_mask_facade<MDT, BS_T>::const_iterator::operator -=( 865 difference_type diff 866 ) 867{ 868 EDDY_FUNC_DEBUGSCOPE 869 this->_bitloc -= diff; 870 return *this; 871} 872 873template <typename MDT, typename BS_T> 874inline 875typename bit_mask_facade<MDT, BS_T>::const_bit_location 876bit_mask_facade<MDT, BS_T>::const_iterator::operator *( 877 ) const 878{ 879 EDDY_FUNC_DEBUGSCOPE 880 return this->_theMask->get_bit_location(this->_bitloc); 881} 882 883template <typename MDT, typename BS_T> 884inline 885bit_mask_facade<MDT, BS_T>::const_iterator::const_iterator( 886 ) : 887 _theMask(0x0), 888 _bitloc(0) 889{ 890 EDDY_FUNC_DEBUGSCOPE 891} // const_iterator::const_iterator 892 893template <typename MDT, typename BS_T> 894inline 895bit_mask_facade<MDT, BS_T>::const_iterator::const_iterator( 896 const const_iterator& copy 897 ) : 898 _theMask(copy._theMask), 899 _bitloc(copy._bitloc) 900{ 901 EDDY_FUNC_DEBUGSCOPE 902} // const_iterator::const_iterator 903 904template <typename MDT, typename BS_T> 905inline 906bit_mask_facade<MDT, BS_T>::const_iterator::const_iterator( 907 const bit_mask_type& mask, 908 const bit_index& bitloc 909 ) : 910 _theMask(const_cast<bit_mask_type*>(&mask)), 911 _bitloc(bitloc) 912{ 913 EDDY_FUNC_DEBUGSCOPE 914} // const_iterator::const_iterator 915 916 917template <typename MDT, typename BS_T> 918inline 919const typename bit_mask_facade<MDT, BS_T>::iterator& 920bit_mask_facade<MDT, BS_T>::iterator::operator =( 921 const iterator& rhs 922 ) 923{ 924 EDDY_FUNC_DEBUGSCOPE 925 this->const_iterator::operator =(rhs); 926 return *this; 927} 928 929template <typename MDT, typename BS_T> 930inline 931typename bit_mask_facade<MDT, BS_T>::iterator& 932bit_mask_facade<MDT, BS_T>::iterator::operator ++( 933 ) 934{ 935 EDDY_FUNC_DEBUGSCOPE 936 this->const_iterator::operator ++(); 937 return *this; 938} 939 940template <typename MDT, typename BS_T> 941inline 942typename bit_mask_facade<MDT, BS_T>::iterator& 943bit_mask_facade<MDT, BS_T>::iterator::operator --( 944 ) 945{ 946 EDDY_FUNC_DEBUGSCOPE 947 this->const_iterator::operator --(); 948 return *this; 949} 950 951template <typename MDT, typename BS_T> 952inline 953typename bit_mask_facade<MDT, BS_T>::iterator& 954bit_mask_facade<MDT, BS_T>::iterator::operator +=( 955 typename const_iterator::difference_type diff 956 ) 957{ 958 EDDY_FUNC_DEBUGSCOPE 959 this->const_iterator::operator +=(diff); 960 return *this; 961} 962// 963//template <typename MDT, typename BS_T> 964//inline 965//typename bit_mask_facade<MDT, BS_T>::const_iterator::difference_type 966//bit_mask_facade<MDT, BS_T>::iterator::operator -( 967// const const_iterator& rhs 968// ) const 969//{ 970// EDDY_FUNC_DEBUGSCOPE 971// return this->const_iterator::operator -(rhs); 972//} 973 974template <typename MDT, typename BS_T> 975inline 976typename bit_mask_facade<MDT, BS_T>::iterator& 977bit_mask_facade<MDT, BS_T>::iterator::operator -=( 978 typename const_iterator::difference_type diff 979 ) 980{ 981 EDDY_FUNC_DEBUGSCOPE 982 this->const_iterator::operator -=(diff); 983 return *this; 984} 985 986template <typename MDT, typename BS_T> 987inline 988typename bit_mask_facade<MDT, BS_T>::bit_location 989bit_mask_facade<MDT, BS_T>::iterator::operator *( 990 ) const 991{ 992 EDDY_FUNC_DEBUGSCOPE 993 return this->_theMask->get_bit_location(this->_bitloc); 994} 995 996template <typename MDT, typename BS_T> 997inline 998bit_mask_facade<MDT, BS_T>::iterator::iterator( 999 ) : 1000 const_iterator() 1001{ 1002 EDDY_FUNC_DEBUGSCOPE 1003} // iterator::iterator 1004 1005template <typename MDT, typename BS_T> 1006inline 1007bit_mask_facade<MDT, BS_T>::iterator::iterator( 1008 const iterator& copy 1009 ) : 1010 const_iterator(copy) 1011{ 1012 EDDY_FUNC_DEBUGSCOPE 1013} // iterator::iterator 1014 1015template <typename MDT, typename BS_T> 1016inline 1017bit_mask_facade<MDT, BS_T>::iterator::iterator( 1018 const bit_mask_type& mask, 1019 const bit_index& bitloc 1020 ) : 1021 const_iterator(mask, bitloc) 1022{ 1023 EDDY_FUNC_DEBUGSCOPE 1024} // iterator::iterator 1025 1026 1027 1028/* 1029================================================================================ 1030Inline Mutators 1031================================================================================ 1032*/ 1033 1034 1035 1036 1037 1038 1039 1040 1041/* 1042================================================================================ 1043Inline Accessors 1044================================================================================ 1045*/ 1046 1047 1048 1049 1050 1051 1052 1053 1054/* 1055================================================================================ 1056Inline Public Methods 1057================================================================================ 1058*/ 1059 1060template <std::size_t NBITS, typename BS_T> 1061inline 1062void 1063bit_mask<NBITS, BS_T>::clear( 1064 bool to 1065 ) 1066{ 1067 EDDY_FUNC_DEBUGSCOPE 1068 ::memset(this->_bits, to ? ~0 : 0, ARRAY_SIZE*sizeof(bit_store_type)); 1069} 1070 1071template <std::size_t NBITS, typename BS_T> 1072inline 1073bool 1074bit_mask<NBITS, BS_T>::toggle_bit( 1075 const bit_index& bitloc 1076 ) 1077{ 1078 EDDY_FUNC_DEBUGSCOPE 1079 EDDY_ASSERT(bitloc < this->num_usable_bits()); 1080 1081 // First, determine the individual bit location within the relevant member 1082 // to be modified. The "xor" the relevant member with the to_bits of that. 1083 this->member_at(bitloc) ^= this->to_bits(this->member_bit(bitloc)); 1084 1085 // now return the resulting value of that bit. 1086 return this->get_bit(bitloc); 1087} 1088 1089template <std::size_t NBITS, typename BS_T> 1090inline 1091void 1092bit_mask<NBITS, BS_T>::toggle_all( 1093 ) 1094{ 1095 EDDY_FUNC_DEBUGSCOPE 1096 for(bit_index m=0; m<ARRAY_SIZE; ++m) this->_bits[m] = ~this->_bits[m]; 1097} 1098 1099 1100template <std::size_t NBITS, typename BS_T> 1101bool 1102bit_mask<NBITS, BS_T>::set_bit( 1103 const bit_index& bitloc, 1104 bool to 1105 ) 1106{ 1107 EDDY_FUNC_DEBUGSCOPE 1108 EDDY_ASSERT(bitloc < this->num_usable_bits()); 1109 1110 // begin by determining which member of the array will be modified. 1111 bit_store_type& toMod = this->member_at(bitloc); 1112 1113 // duplicate that value so we can determine if this changes the mask at all 1114 bit_store_type oldVal = toMod; 1115 1116 // store the modifier computed using to_bits. 1117 bit_store_type mod = this->to_bits(this->member_bit(bitloc)); 1118 1119 // now use the "or" operator to modify the bit at the bitloc location. 1120 (to) ? (toMod |= mod) : (toMod &= ~mod); 1121 1122 // return true if _bits changed and false otherwise 1123 return (toMod != oldVal); 1124} 1125 1126template <std::size_t NBITS, typename BS_T> 1127inline 1128bool 1129bit_mask<NBITS, BS_T>::get_bit( 1130 const bit_index& bitloc 1131 ) const 1132{ 1133 EDDY_FUNC_DEBUGSCOPE 1134 EDDY_ASSERT(bitloc < this->num_usable_bits()); 1135 1136 return (this->member_at(bitloc) & 1137 this->to_bits(this->member_bit(bitloc))) != 0; 1138} 1139 1140template <std::size_t NBITS, typename BS_T> 1141inline 1142typename bit_mask<NBITS, BS_T>::size_type 1143bit_mask<NBITS, BS_T>::num_usable_bits( 1144 ) const 1145{ 1146 EDDY_FUNC_DEBUGSCOPE 1147 return USABLE_BITS; 1148} 1149 1150/* 1151================================================================================ 1152Inline Subclass Visible Methods 1153================================================================================ 1154*/ 1155 1156 1157 1158 1159 1160 1161 1162 1163/* 1164================================================================================ 1165Inline Private Methods 1166================================================================================ 1167*/ 1168 1169template <std::size_t NBITS, typename BS_T> 1170inline 1171typename bit_mask<NBITS, BS_T>::bit_store_type& 1172bit_mask<NBITS, BS_T>::member_at( 1173 const bit_index& bitloc 1174 ) 1175{ 1176 EDDY_FUNC_DEBUGSCOPE 1177 return this->_bits[this->member_index(bitloc)]; 1178} 1179 1180template <std::size_t NBITS, typename BS_T> 1181inline 1182const typename bit_mask<NBITS, BS_T>::bit_store_type& 1183bit_mask<NBITS, BS_T>::member_at( 1184 const bit_index& bitloc 1185 ) const 1186{ 1187 EDDY_FUNC_DEBUGSCOPE 1188 return this->_bits[this->member_index(bitloc)]; 1189} 1190 1191 1192/* 1193================================================================================ 1194Inline Structors 1195================================================================================ 1196*/ 1197 1198template <std::size_t NBITS, typename BS_T> 1199bit_mask<NBITS, BS_T>::bit_mask( 1200 ) 1201{ 1202 EDDY_FUNC_DEBUGSCOPE 1203 clear(); 1204} 1205 1206 1207template <std::size_t NBITS, typename BS_T> 1208bit_mask<NBITS, BS_T>::bit_mask( 1209 const my_type& copy 1210 ) 1211{ 1212 EDDY_FUNC_DEBUGSCOPE 1213 ::memcpy(this->_bits, copy._bits, ARRAY_SIZE*sizeof(bit_store_type)); 1214} 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231template <typename BS_T> 1232void 1233dynamic_bit_mask<BS_T>::grow( 1234 size_type nbits 1235 ) 1236{ 1237 EDDY_FUNC_DEBUGSCOPE 1238 1239 if(nbits <= this->capacity()) return; 1240 1241 // compute the new capacity. 1242 size_type newarrsz = required_array_size(nbits); 1243 1244 // create a new set of bits to take the place of the old one. 1245 bit_store_type* newbits = new bit_store_type[newarrsz]; 1246 1247 // now copy all the old bits into the newbits buffer. 1248 for(size_type i=0; i<this->_array_size; ++i) newbits[i] = this->_bits[i]; 1249 1250 // now update the array size. 1251 this->_array_size = newarrsz; 1252 1253 // finally, destroy the old bits and adopt the new ones. 1254 delete [] this->_bits; 1255 this->_bits = newbits; 1256} 1257 1258 1259 1260 1261template <typename BS_T> 1262void 1263dynamic_bit_mask<BS_T>::resize( 1264 size_type nbits, 1265 bool lval 1266 ) 1267{ 1268 EDDY_FUNC_DEBUGSCOPE 1269 1270 // make sure our capacity is sufficient for this resize. 1271 this->grow(nbits); 1272 1273 // prepare an iterator to the first location to which we wish 1274 // to do assigning. 1275 iterator f(eddy::utilities::advance(this->begin(), this->_nbits)); 1276 1277 // now update the number of bits _nbits. 1278 this->_nbits = nbits; 1279 1280 // now do the assignment of the lval to all new bits. 1281 std::fill(f, this->end(), lval); 1282} 1283 1284template <typename BS_T> 1285inline 1286void 1287dynamic_bit_mask<BS_T>::reserve( 1288 size_type nbits 1289 ) 1290{ 1291 EDDY_FUNC_DEBUGSCOPE 1292 this->grow(nbits); 1293} 1294 1295template <typename BS_T> 1296inline 1297typename dynamic_bit_mask<BS_T>::size_type 1298dynamic_bit_mask<BS_T>::capacity( 1299 ) const 1300{ 1301 EDDY_FUNC_DEBUGSCOPE 1302 return this->array_size() * base_type::MEMBER_BIT_COUNT; 1303} 1304 1305 1306 1307template <typename BS_T> 1308inline 1309void 1310dynamic_bit_mask<BS_T>::clear( 1311 bool to 1312 ) 1313{ 1314 EDDY_FUNC_DEBUGSCOPE 1315 ::memset( 1316 this->_bits, to ? ~0 : 0, 1317 required_array_size(this->size())*sizeof(bit_store_type) 1318 ); 1319} 1320 1321template <typename BS_T> 1322inline 1323bool 1324dynamic_bit_mask<BS_T>::toggle_bit( 1325 const bit_index& bitloc 1326 ) 1327{ 1328 EDDY_FUNC_DEBUGSCOPE 1329 EDDY_ASSERT(bitloc < this->num_usable_bits()); 1330 1331 // First, determine the individual bit location within the relevant member 1332 // to be modified. Then "xor" the relevant member with the to_bits value. 1333 this->member_at(bitloc) ^= this->to_bits(this->member_bit(bitloc)); 1334 1335 // now return the resulting value of that bit. 1336 return this->get_bit(bitloc); 1337} 1338 1339template <typename BS_T> 1340inline 1341void 1342dynamic_bit_mask<BS_T>::toggle_all( 1343 ) 1344{ 1345 EDDY_FUNC_DEBUGSCOPE 1346 size_type nelems = required_array_size(this->size()); 1347 for(size_type m=0; m<nelems; ++m) this->_bits[m] = ~this->_bits[m]; 1348} 1349 1350template <typename BS_T> 1351bool 1352dynamic_bit_mask<BS_T>::set_bit( 1353 const bit_index& bitloc, 1354 bool to 1355 ) 1356{ 1357 EDDY_FUNC_DEBUGSCOPE 1358 EDDY_ASSERT(bitloc < this->num_usable_bits()); 1359 1360 // begin by determining which member of the array will be modified. 1361 bit_store_type& toMod = this->member_at(bitloc); 1362 1363 // duplicate that value so we can determine if this changes the mask at all 1364 bit_store_type oldVal = toMod; 1365 1366 // store the modifier computed using to_bits. 1367 bit_store_type mod = this->to_bits(this->member_bit(bitloc)); 1368 1369 // now use the "or" operator to modify the bit at the bitloc location. 1370 (to) ? (toMod |= mod) : (toMod &= ~mod); 1371 1372 // return true if _bits changed and false otherwise 1373 return (toMod != oldVal); 1374} 1375 1376template <typename BS_T> 1377inline 1378bool 1379dynamic_bit_mask<BS_T>::get_bit( 1380 const bit_index& bitloc 1381 ) const 1382{ 1383 EDDY_FUNC_DEBUGSCOPE 1384 EDDY_ASSERT(bitloc < this->num_usable_bits()); 1385 1386 return (this->member_at(bitloc) & 1387 this->to_bits(this->member_bit(bitloc))) != 0; 1388} 1389 1390template <typename BS_T> 1391inline 1392typename dynamic_bit_mask<BS_T>::bit_index 1393dynamic_bit_mask<BS_T>::num_usable_bits( 1394 ) const 1395{ 1396 EDDY_FUNC_DEBUGSCOPE 1397 return this->_nbits; 1398} 1399 1400template <typename BS_T> 1401inline 1402typename dynamic_bit_mask<BS_T>::size_type 1403dynamic_bit_mask<BS_T>::fully_utilized_array_elements( 1404 ) const 1405{ 1406 EDDY_FUNC_DEBUGSCOPE 1407 return this->num_usable_bits() / base_type::MEMBER_BIT_COUNT; 1408} 1409 1410template <typename BS_T> 1411inline 1412typename dynamic_bit_mask<BS_T>::size_type 1413dynamic_bit_mask<BS_T>::array_size( 1414 ) const 1415{ 1416 EDDY_FUNC_DEBUGSCOPE 1417 return this->_array_size;// required_array_size(this->size()); 1418} 1419 1420template <typename BS_T> 1421inline 1422typename dynamic_bit_mask<BS_T>::size_type 1423dynamic_bit_mask<BS_T>::required_array_size( 1424 size_type nbits 1425 ) 1426{ 1427 EDDY_FUNC_DEBUGSCOPE 1428 // This calculates the required size of an array to hold the supplied 1429 // number of bits. When we divide nbits by the number of bits/array 1430 // member and truncate, we get an initial cut at our answer. Now, if 1431 // there are still unaccounted for bits, which is the case if nbits does 1432 // not evenly divide by bits/member, then we need to add 1 more member. 1433 return (nbits / base_type::MEMBER_BIT_COUNT) + 1434 ((nbits % base_type::MEMBER_BIT_COUNT) != 0 ? 1 : 0); 1435} 1436 1437template <typename BS_T> 1438inline 1439typename dynamic_bit_mask<BS_T>::bit_store_type& 1440dynamic_bit_mask<BS_T>::member_at( 1441 const bit_index& bitloc 1442 ) 1443{ 1444 EDDY_FUNC_DEBUGSCOPE 1445 return this->_bits[this->member_index(bitloc)]; 1446} 1447 1448template <typename BS_T> 1449inline 1450const typename dynamic_bit_mask<BS_T>::bit_store_type& 1451dynamic_bit_mask<BS_T>::member_at( 1452 const bit_index& bitloc 1453 ) const 1454{ 1455 EDDY_FUNC_DEBUGSCOPE 1456 return this->_bits[this->member_index(bitloc)]; 1457} 1458 1459template <typename BS_T> 1460dynamic_bit_mask<BS_T>::dynamic_bit_mask( 1461 ) : 1462 _nbits(0), 1463 _array_size(0), 1464 _bits(0x0) 1465{ 1466 EDDY_FUNC_DEBUGSCOPE 1467} 1468 1469template <typename BS_T> 1470dynamic_bit_mask<BS_T>::dynamic_bit_mask( 1471 size_type nbits 1472 ) : 1473 _nbits(nbits), 1474 _array_size(required_array_size(nbits)), 1475 _bits(new bit_store_type[required_array_size(nbits)]) 1476{ 1477 EDDY_FUNC_DEBUGSCOPE 1478 this->clear(); 1479} 1480 1481 1482template <typename BS_T> 1483dynamic_bit_mask<BS_T>::dynamic_bit_mask( 1484 const my_type& copy 1485 ) : 1486 _nbits(copy._nbits), 1487 _array_size(required_array_size(copy.size())), 1488 _bits(new bit_store_type[required_array_size(copy.size())]) 1489{ 1490 EDDY_FUNC_DEBUGSCOPE 1491 ::memcpy( 1492 this->_bits, copy._bits, this->array_size()*sizeof(bit_store_type) 1493 ); 1494} 1495 1496template <typename BS_T> 1497dynamic_bit_mask<BS_T>::~dynamic_bit_mask( 1498 ) 1499{ 1500 EDDY_FUNC_DEBUGSCOPE 1501 delete [] this->_bits; 1502} 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517/* 1518================================================================================ 1519Utility Functions & Operators 1520================================================================================ 1521*/ 1522template <typename BM_T, typename BS_T> 1523inline 1524BM_T 1525operator &( 1526 const bit_mask_facade<BM_T, BS_T>& lhs, 1527 const bit_mask_facade<BM_T, BS_T>& rhs 1528 ) 1529{ 1530 EDDY_FUNC_DEBUGSCOPE 1531 return BM_T(lhs.casted()) &= rhs; 1532} 1533 1534template <typename BM_T, typename BS_T, typename OSET_T> 1535inline 1536BM_T 1537operator &( 1538 const bit_mask_facade<BM_T, BS_T>& lhs, 1539 const OSET_T& rhs 1540 ) 1541{ 1542 EDDY_FUNC_DEBUGSCOPE 1543 return BM_T(lhs.casted()) &= rhs; 1544} 1545 1546template <typename BM_T, typename BS_T> 1547inline 1548BM_T 1549operator |( 1550 const bit_mask_facade<BM_T, BS_T>& lhs, 1551 const bit_mask_facade<BM_T, BS_T>& rhs 1552 ) 1553{ 1554 EDDY_FUNC_DEBUGSCOPE 1555 return BM_T(lhs.casted()) |= rhs; 1556} 1557 1558template <typename BM_T, typename BS_T, typename OSET_T> 1559inline 1560BM_T 1561operator |( 1562 const bit_mask_facade<BM_T, BS_T>& lhs, 1563 const OSET_T& rhs 1564 ) 1565{ 1566 EDDY_FUNC_DEBUGSCOPE 1567 return BM_T(lhs.casted()) |= rhs; 1568} 1569 1570template <typename BM_T, typename BS_T> 1571inline 1572BM_T 1573operator ^( 1574 const bit_mask_facade<BM_T, BS_T>& lhs, 1575 const bit_mask_facade<BM_T, BS_T>& rhs 1576 ) 1577{ 1578 EDDY_FUNC_DEBUGSCOPE 1579 return BM_T(lhs.casted()) ^= rhs; 1580} 1581 1582template <typename BM_T, typename BS_T, typename OSET_T> 1583inline 1584BM_T 1585operator ^( 1586 const bit_mask_facade<BM_T, BS_T>& lhs, 1587 const OSET_T& rhs 1588 ) 1589{ 1590 EDDY_FUNC_DEBUGSCOPE 1591 return BM_T(lhs.casted()) ^= rhs; 1592} 1593 1594template <typename Elem, typename Traits, typename BM_T, typename BS_T> 1595inline 1596std::basic_istream<Elem, Traits>& 1597operator >> ( 1598 std::basic_istream<Elem, Traits>& stream, 1599 bit_mask_facade<BM_T, BS_T>& mask 1600 ) 1601{ 1602 EDDY_FUNC_DEBUGSCOPE 1603 return mask.read_bits(stream); 1604} 1605 1606template <typename Elem, typename Traits, typename BM_T, typename BS_T> 1607inline 1608std::basic_ostream<Elem, Traits>& 1609operator << ( 1610 std::basic_ostream<Elem, Traits>& stream, 1611 const bit_mask_facade<BM_T, BS_T>& mask 1612 ) 1613{ 1614 EDDY_FUNC_DEBUGSCOPE 1615 return mask.print_bits(stream); 1616} 1617 1618 1619/* 1620================================================================================ 1621End Namespace 1622================================================================================ 1623*/ 1624 } // namespace utilities 1625} // namespace eddy 1626 1627 1628