source: trunk/lib/bitblock_scan.hpp @ 1618

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

Created bit block scanner library to serve as a single location to contain bit block scan methods and classes.

File size: 2.6 KB
RevLine 
[1618]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 : Scanner<bitblock_t, scanblock_t> {
35
36public:
37
38        ForwardScanner(): Scanner<bitblock_t, scanblock_t>(){}
39        ForwardScanner(bitblock_t * s): Scanner<bitblock_t, scanblock_t>(s, 0, 0, *((scanblock_t *)s)){}
40
41        IDISA_ALWAYS_INLINE uint32_t scan_to_next() {
42                while (this->blk < (sizeof(bitblock_t)/sizeof(scanblock_t))){
43                        if(this->scan_blk > 0){
44                                this->pos = count_forward_zeroes(this->scan_blk) + (this->blk * (sizeof(scanblock_t)*8));
45                                this->scan_blk = this->scan_blk & (this->scan_blk-1);  // clear rightmost bit
46
47                                return (this->pos);
48                        }
49
50                        this->blk++;
51                        this->scan_blk = *((scanblock_t *)this->strm + this->blk);
52                };
53
54                this->pos = -1;
55                return (this->pos);
56        }
57
58        IDISA_ALWAYS_INLINE bitblock_t * get_strm() const {return this->strm;}
59        IDISA_ALWAYS_INLINE uint32_t get_pos() const {return this->pos;}
60
61};
62
63// Reverse
64template <class bitblock_t, class scanblock_t>
65class ReverseScanner : Scanner<bitblock_t, scanblock_t> {
66
67public:
68        ReverseScanner(): Scanner<bitblock_t, scanblock_t>(){}
69        ReverseScanner(bitblock_t * s): Scanner<bitblock_t, scanblock_t>(s, 0, BLOCK_COUNT, *((scanblock_t *)s + (BLOCK_COUNT-1))){}
70
71        IDISA_ALWAYS_INLINE uint32_t scan_to_next() {
72                while (this->blk > 0){
73                        if(this->scan_blk > 0){
74                                this->pos = (sizeof(scanblock_t)*8 - cbzl(this->scan_blk) -1) + ( (this->blk-1) * sizeof(scanblock_t)*8 );
75                                this->scan_blk = this->scan_blk & (SHIFT_MASK >> (sizeof(scanblock_t)*8 - this->pos));  // clear leftmost bit
76                                return (this->pos);
77                        }
78
79                        this->blk--;
80                        this->scan_blk = *((scanblock_t *)this->strm + this->blk-1);
81                };
82
83                this->pos = -1;
84                return (this->pos);
85        }
86
87        IDISA_ALWAYS_INLINE bitblock_t * get_strm() const {return this->strm;}
88        IDISA_ALWAYS_INLINE uint32_t get_pos() const {return this->pos;}
89
90        static const uint32_t BLOCK_COUNT = sizeof(bitblock_t)/sizeof(scanblock_t);
91        static const uint32_t SHIFT_MASK = -1;
92
93};
94
95
96#endif /* BITBLOCK_SCAN_H_ */
97
Note: See TracBrowser for help on using the repository browser.