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