source: trunk/lib/bitblock_iterator.hpp @ 1611

Last change on this file since 1611 was 1611, checked in by ksherdy, 7 years ago

Refactored iterator class to specialized on BitBlock? type and ScanBlock? type.

File size: 3.0 KB
Line 
1/*
2 * bitblock_iterator.hpp
3 */
4
5#ifndef BITBLOCK_ITERATOR_H_
6#define BITBLOCK_ITERATOR_H_
7
8#include <iterator>
9#include <iostream>
10using namespace std;
11
12#include "bitblock.hpp"
13
14template<class bitblock_t, class scanblock_t>
15class BitBlockIteratorBase: public iterator<input_iterator_tag, int>
16{
17public:
18        // equal position and stream
19        bool operator==(const BitBlockIteratorBase& iter)
20        {
21                return((strm = iter.strm) && (crt_pos == iter.crt_pos));
22        }
23
24        // not equal position and stream
25        bool operator!=(const BitBlockIteratorBase& iter)
26        {
27                return((strm != iter.strm) && (crt_pos != iter.crt_pos));
28        }
29
30        // Returns absolute position.
31        IDISA_ALWAYS_INLINE int operator*()
32        {
33                return crt_pos;
34        }
35
36protected:
37        // default constructor defines past-the-end of bit stream semantics, crt_pos == -1
38        BitBlockIteratorBase(): strm(NULL), crt_pos(-1), crt_blk(-1), scan_blk(-1){}
39        BitBlockIteratorBase(bitblock_t * s, uint32_t pos, uint32_t blk):  strm(s), crt_pos(pos), crt_blk(blk), scan_blk(*((scanblock_t *)s)) {}
40
41        bitblock_t * strm;
42        uint32_t crt_pos;
43        uint32_t crt_blk;
44        scanblock_t scan_blk;
45};
46
47class BitBlockForwardIterator : public BitBlockIteratorBase<BitBlock, unsigned long>
48{
49public:
50        BitBlockForwardIterator(): BitBlockIteratorBase<BitBlock, unsigned long>() {}
51
52        BitBlockForwardIterator(BitBlock * b): BitBlockIteratorBase<BitBlock, unsigned long>(b,0,0)
53        {
54                scan_forward();
55        }
56
57        // pre-increment
58        IDISA_ALWAYS_INLINE BitBlockForwardIterator& operator++()
59        {
60                scan_forward();
61                return(*this);
62        }
63
64        // post-increment
65        BitBlockForwardIterator& operator++(int)
66        {
67                BitBlockForwardIterator temp(*this);
68                ++(*this);
69                return(temp);
70        }
71
72private:
73
74        IDISA_ALWAYS_INLINE void scan_forward() {
75                while (crt_blk < (sizeof(BitBlock)/sizeof(unsigned long))){
76                        if(scan_blk > 0){
77                                crt_pos = cfzl(scan_blk) + (crt_blk * (sizeof(unsigned long)*8));
78                                scan_blk = scan_blk & (scan_blk-1);  // clear rightmost bit
79                                return;
80                        }
81
82                        crt_blk++;
83                        scan_blk = *((unsigned long *)strm + crt_blk);
84                };
85
86                crt_pos = -1;
87                return;
88        }
89
90};
91
92class BitBlockReverseIterator : public BitBlockIteratorBase<BitBlock, unsigned long>
93{
94public:
95        BitBlockReverseIterator(): BitBlockIteratorBase<BitBlock, unsigned long>() {}
96
97        BitBlockReverseIterator(BitBlock * b): BitBlockIteratorBase<BitBlock, unsigned long>(b,0,sizeof(BitBlock)/sizeof(unsigned long))
98        {
99                scan_reverse();
100        }
101
102        // pre-increment
103        IDISA_ALWAYS_INLINE BitBlockReverseIterator& operator--()
104        {
105                scan_reverse();
106                return(*this);
107        }
108
109        // post-increment
110        BitBlockReverseIterator& operator--(int)
111        {
112                BitBlockReverseIterator temp(*this);
113                --(*this);
114                return(temp);
115        }
116
117private:
118
119        IDISA_ALWAYS_INLINE void scan_reverse() {
120                while (crt_blk > 0){
121                        if(scan_blk > 0){
122                                crt_pos = ((sizeof(unsigned long)*8) - cbzl(scan_blk)) + (crt_blk * (sizeof(unsigned long)*8));
123                                scan_blk = scan_blk & (crt_pos-1);  // clear leftmost bit
124                                return;
125                        }
126
127                        crt_blk--;
128                        scan_blk = *((unsigned long *)strm + crt_blk);
129                };
130
131                crt_pos = -1;
132                return;
133        }
134
135};
136
137#endif /* BITBLOCK_ITERATOR_H_ */
138
Note: See TracBrowser for help on using the repository browser.