source: trunk/lib/bitblock_scan.hpp @ 1753

Last change on this file since 1753 was 1680, checked in by ksherdy, 8 years ago

Renamed reset(), init().

File size: 2.6 KB
Line 
1/*
2 * bitblock_scan.hpp
3 */
4
5#ifndef BITBLOCK_SCAN_H_
6#define BITBLOCK_SCAN_H_
7
8#include <iterator>
9#include <iostream>
10using namespace std;
11
12#include "bitblock.hpp"
13
14/*
15 * Templated scanner forward and reverse scanner classes on biblock_t, scanblock_t.
16 */ 
17 
18// Base
19template <class bitblock_t, class scanblock_t>
20class Scanner {
21
22protected:
23        Scanner(): strm(NULL), pos(-1), blk(-1), scan_blk(-1) {}
24        Scanner(bitblock_t * s, uint32_t start_pos, uint32_t start_blk, scanblock_t start_scan_blk): strm(s), pos(start_pos), blk(start_blk), scan_blk(start_scan_blk) {}
25
26        bitblock_t * strm;
27        uint32_t pos;
28        uint32_t blk;
29        scanblock_t scan_blk;
30};
31
32// Forward
33template <class bitblock_t, class scanblock_t>
34class ForwardScanner: public Scanner<bitblock_t, scanblock_t> {
35
36public:
37
38        ForwardScanner(){}
39        ForwardScanner(bitblock_t * s) {
40                init(s);
41        }
42
43        IDISA_ALWAYS_INLINE void init(bitblock_t * s) {
44                this->strm = s;
45                this->pos = 0;
46                this->blk = 0;
47                this->scan_blk = *(scanblock_t *)s;
48        }
49
50        IDISA_ALWAYS_INLINE uint32_t scan_to_next() {
51                while (this->blk < (sizeof(bitblock_t)/sizeof(scanblock_t))){
52                        if(this->scan_blk > 0){
53                                this->pos = count_forward_zeroes(this->scan_blk) + (this->blk * (sizeof(scanblock_t)*8));
54                                this->scan_blk = this->scan_blk & (this->scan_blk-1);  // clear rightmost bit
55
56                                return (this->pos);
57                        }
58
59                        this->blk++;
60                        this->scan_blk = *((scanblock_t *)this->strm + this->blk);
61                };
62
63                this->pos = -1;
64                return (this->pos);
65        }
66
67        IDISA_ALWAYS_INLINE bitblock_t * get_strm() const {return this->strm;}
68        IDISA_ALWAYS_INLINE uint32_t get_pos() const {return this->pos;}
69
70};
71
72// Reverse
73template <class bitblock_t, class scanblock_t>
74class ReverseScanner: public Scanner<bitblock_t, scanblock_t> {
75
76public:
77        ReverseScanner(){}
78        ReverseScanner(bitblock_t * s) {
79                init(s);
80        }
81        IDISA_ALWAYS_INLINE void init(bitblock_t * s) {
82                this->strm = s;
83                this->pos = 0;
84                this->blk = BLOCK_COUNT;
85                this->scan_blk = *((scanblock_t *)s + (BLOCK_COUNT-1));
86        }
87
88        IDISA_ALWAYS_INLINE uint32_t scan_to_next() {
89                while (this->blk > 0){
90                        if(this->scan_blk > 0){
91                                this->pos = (sizeof(scanblock_t)*8 - count_reverse_zeroes(this->scan_blk) -1) + ( (this->blk-1) * sizeof(scanblock_t)*8 );
92                                this->scan_blk = this->scan_blk ^ (1 << this->pos); // clear leftmost bit
93                                return (this->pos);
94                        }
95
96                        this->blk--;
97                        this->scan_blk = *((scanblock_t *)this->strm + this->blk-1);
98                };
99
100                this->pos = -1;
101                return (this->pos);
102        }
103
104        IDISA_ALWAYS_INLINE bitblock_t * get_strm() const {return this->strm;}
105        IDISA_ALWAYS_INLINE uint32_t get_pos() const {return this->pos;}
106
107        static const uint32_t BLOCK_COUNT = sizeof(bitblock_t)/sizeof(scanblock_t);
108
109};
110
111
112#endif /* BITBLOCK_SCAN_H_ */
113
Note: See TracBrowser for help on using the repository browser.