Developer documentation
Version 3.0.3-105-gd3941f44
bitset.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __misc_bitset_h__
18#define __misc_bitset_h__
19
20
21#include <atomic>
22#include <stdint.h>
23
24#include "mrtrix.h"
25
26
27
28namespace MR {
29
30
31
33
44
45 public:
46
50 public:
51 Value (BitSet& master, const size_t offset) : d (master), p (offset) { assert (p < d.size()); }
52 operator bool() const { return d.test (p); }
53 bool operator== (const bool i) const { return (i == d.test (p)); }
54 bool operator= (const bool i) { i ? d.set (p) : d.reset (p); return i; }
55 Value& operator|= (const bool i) { (i || bool(*this)) ? d.set (p) : d.reset (p); return *this; }
56 Value& operator&= (const bool i) { (i && bool(*this)) ? d.set (p) : d.reset (p); return *this; }
57 friend std::ostream& operator<< (std::ostream& stream, const Value& V) { stream << (bool(V) ? '1' : '0'); return stream; }
58 private:
59 BitSet& d;
60 const size_t p;
61 };
63 public:
64 ConstValue (const BitSet& master, const size_t offset) : d (master), p (offset) { assert (p < d.size()); }
65 operator bool() const { return d.test (p); }
66 bool operator== (const bool i) const { return (i == d.test (p)); }
67 friend std::ostream& operator<< (std::ostream& stream, const ConstValue& V) { stream << (bool(V) ? '1' : '0'); return stream; }
68 private:
69 const BitSet& d;
70 const size_t p;
71 };
72
73
75
78 BitSet (const size_t, const bool allocator = false);
79
81
85 BitSet (const BitSet&);
87
89
96 void resize (const size_t, const bool allocator = false);
97
99
102 void clear (const bool allocator = false);
103
105
113 ConstValue operator[] (const size_t i) const { assert (i < bits); return ConstValue (*this, i); }
114 Value operator[] (const size_t i) { assert (i < bits); return Value (*this, i); }
115
117
120 size_t size() const { return bits; }
121
123
130 bool full() const;
131
133
140 bool empty() const;
141
143
153 size_t count() const;
154
156
180 bool operator== (const BitSet&) const;
181 bool operator!= (const BitSet&) const;
185 BitSet operator| (const BitSet&) const;
186 BitSet operator& (const BitSet&) const;
187 BitSet operator^ (const BitSet&) const;
189
190 const uint8_t* get_data_ptr() const { return data; }
191
192 friend std::ostream& operator<< (std::ostream&, const BitSet&);
193
194
195 protected:
196 size_t bits;
197 size_t bytes;
198
199 bool have_excess_bits() const { return (bits & size_t(7)); }
200 size_t excess_bits() const { return (8*bytes - bits); }
201 uint8_t excess_bit_mask() const { assert (have_excess_bits()); return 0xFF << (8-excess_bits()); }
202
203 bool test (const size_t index) const
204 {
205 assert (index < bits);
206 return (data[index>>3] & masks[index&size_t(7)]);
207 }
208
209 void set (const size_t index)
210 {
211 assert (index < bits);
212 std::atomic<uint8_t>* at = reinterpret_cast<std::atomic<uint8_t>*> (((uint8_t*) data) + (index>>3));
213 uint8_t prev = *at, new_value;
214 do { new_value = prev | masks[index&size_t(7)]; } while (!at->compare_exchange_weak (prev, new_value));
215 }
216
217 void reset (const size_t index)
218 {
219 assert (index < bits);
220 std::atomic<uint8_t>* at = reinterpret_cast<std::atomic<uint8_t>*> (((uint8_t*) data) + (index>>3));
221 uint8_t prev = *at, new_value;
222 do { new_value = prev & ~masks[index&size_t(7)]; } while (!at->compare_exchange_weak (prev, new_value));
223 }
224
225
226 private:
227 uint8_t* data;
228
229 static const uint8_t masks[8];
230
231 };
232
233
234
235}
236
237#endif
ConstValue(const BitSet &master, const size_t offset)
Definition: bitset.h:64
friend std::ostream & operator<<(std::ostream &stream, const ConstValue &V)
Definition: bitset.h:67
bool operator==(const bool i) const
Definition: bitset.h:66
friend std::ostream & operator<<(std::ostream &stream, const Value &V)
Definition: bitset.h:57
Value & operator|=(const bool i)
Definition: bitset.h:55
Value(BitSet &master, const size_t offset)
Definition: bitset.h:51
bool operator==(const bool i) const
Definition: bitset.h:53
Value & operator&=(const bool i)
Definition: bitset.h:56
bool operator=(const bool i)
Definition: bitset.h:54
a class for storing bitwise information
Definition: bitset.h:43
uint8_t excess_bit_mask() const
Definition: bitset.h:201
BitSet & operator^=(const BitSet &)
size_t count() const
count the number of true entries in the set
void set(const size_t index)
Definition: bitset.h:209
bool have_excess_bits() const
Definition: bitset.h:199
BitSet operator^(const BitSet &) const
bool empty() const
whether or not the bitset is 'empty' i.e. all elements are false
BitSet operator~() const
void clear(const bool allocator=false)
clear the data
size_t size() const
the number of boolean elements in the set
Definition: bitset.h:120
BitSet operator&(const BitSet &) const
BitSet(const BitSet &)
copy-construct a bitset, with explicit copying of data into the new instance
size_t excess_bits() const
Definition: bitset.h:200
const uint8_t * get_data_ptr() const
Definition: bitset.h:190
BitSet & operator&=(const BitSet &)
BitSet operator|(const BitSet &) const
friend std::ostream & operator<<(std::ostream &, const BitSet &)
bool operator!=(const BitSet &) const
BitSet & operator=(const BitSet &)
convenience functions for performing boolean operations
bool operator==(const BitSet &) const
void reset(const size_t index)
Definition: bitset.h:217
size_t bytes
Definition: bitset.h:197
bool test(const size_t index) const
Definition: bitset.h:203
bool full() const
whether or not the bitset is 'full' i.e. all elements are true
BitSet & operator|=(const BitSet &)
size_t bits
Definition: bitset.h:196
void resize(const size_t, const bool allocator=false)
resize the bitset, retaining existing data
BitSet(const size_t, const bool allocator=false)
create a new bitset with the desired size.
ConstValue operator[](const size_t i) const
access boolean value at a given index
Definition: bitset.h:113
index_type offset
Definition: loop.h:33
#define NOMEMALIGN
Definition: memory.h:22
@ Value
Definition: linear.h:87
Definition: base.h:24
size_t index