summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/bitary.h
blob: 139950b051dd83ecb0b4dfd4cabb526131fa4b7f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/**
 * @file
 * @brief Bit array data type.
 *
 * Just contains the operations required by los.cc
 * for the moment.
**/

#ifndef BITARY_H
#define BITARY_H

#include "defines.h"

#include <bitset>

class bit_vector
{
public:
    bit_vector(unsigned long size = 0);
    bit_vector(const bit_vector& other);
    ~bit_vector();

    void reset();

    bool get(unsigned long index) const;
    void set(unsigned long index, bool value = true);

    bit_vector& operator |= (const bit_vector& other);
    bit_vector& operator &= (const bit_vector& other);
    bit_vector  operator & (const bit_vector& other) const;

protected:
    unsigned long size;
    int nwords;
    unsigned long *data;
};

#define LONGSIZE (sizeof(unsigned long)*8)
#ifndef ULONG_MAX
#define ULONG_MAX ((unsigned long)(-1))
#endif

template <unsigned int SIZE> class FixedBitVector
{
protected:
    bitset<SIZE> data;
public:
    void reset()
    {
        data.reset();
    }

    FixedBitVector()
    {
    }

    inline bool get(unsigned int i) const
    {
#ifdef ASSERTS
        // printed as signed, as in FixedVector
        if (i >= SIZE)
            die("bit vector range error: %d / %u", (int)i, SIZE);
#endif
        return data[i];
    }

    inline bool operator[](unsigned int i) const
    {
        return get(i);
    }

    inline void set(unsigned int i, bool value = true)
    {
#ifdef ASSERTS
        if (i >= SIZE)
            die("bit vector range error: %d / %u", (int)i, SIZE);
#endif
        data[i] = value;
    }

    inline unsigned int count() const
    {
        return data.count();
    }

    inline bool any() const
    {
        return data.any();
    }

    inline FixedBitVector<SIZE>& operator|=(const FixedBitVector<SIZE>&x)
    {
        data |= x.data;
        return *this;
    }

    inline FixedBitVector<SIZE>& operator&=(const FixedBitVector<SIZE>&x)
    {
        data &= x.data;
        return *this;
    }

    void init(bool value)
    {
        data.reset();
        if (value)
            data.flip();
    }
};

template <unsigned int SIZEX, unsigned int SIZEY> class FixedBitArray
{
protected:
    std::bitset<SIZEX*SIZEY> data;
public:
    void reset()
    {
        data.reset();
    }

    void init(bool def)
    {
        data.reset();
        if (def)
            data.flip();
    }

    FixedBitArray()
    {
        reset();
    }

    FixedBitArray(bool def)
    {
        init(def);
    }

    inline bool get(int x, int y) const
    {
#ifdef ASSERTS
        // printed as signed, as in FixedArray
        if (x < 0 || y < 0 || x >= (int)SIZEX || y >= (int)SIZEY)
            die("bit array range error: %d,%d / %u,%u", x, y, SIZEX, SIZEY);
#endif
        unsigned int i = y * SIZEX + x;
        return data[i];
    }

    template<class Indexer> inline bool get(const Indexer &i) const
    {
        return get(i.x, i.y);
    }

    inline bool operator () (int x, int y) const
    {
        return get(x, y);
    }

    template<class Indexer> inline bool operator () (const Indexer &i) const
    {
        return get(i.x, i.y);
    }

    inline void set(int x, int y, bool value = true)
    {
#ifdef ASSERTS
        if (x < 0 || y < 0 || x >= (int)SIZEX || y >= (int)SIZEY)
            die("bit array range error: %d,%d / %u,%u", x, y, SIZEX, SIZEY);
#endif
        unsigned int i = y * SIZEX + x;
        data[i] = value;
    }

    template<class Indexer> inline void set(const Indexer &i, bool value = true)
    {
        return set(i.x, i.y, value);
    }

    inline FixedBitArray<SIZEX, SIZEY>& operator|=(const FixedBitArray<SIZEX, SIZEY>&x)
    {
        data |= x.data;
        return *this;
    }

    inline FixedBitArray<SIZEX, SIZEY>& operator&=(const FixedBitArray<SIZEX, SIZEY>&x)
    {
        data &= x.data;
        return *this;
    }
};

#endif