@@ -7,6 +7,7 @@ A C++ header for Roaring Bitmaps.
7
7
#include < algorithm>
8
8
#include < cstdarg>
9
9
#include < initializer_list>
10
+ #include < limits>
10
11
#include < new>
11
12
#include < stdexcept>
12
13
#include < string>
@@ -39,7 +40,10 @@ A C++ header for Roaring Bitmaps.
39
40
40
41
namespace roaring {
41
42
42
- class RoaringSetBitForwardIterator ;
43
+ class RoaringSetBitBiDirectionalIterator ;
44
+
45
+ /* * DEPRECATED, use `RoaringSetBitBiDirectionalIterator`. */
46
+ using RoaringSetBitForwardIterator = RoaringSetBitBiDirectionalIterator;
43
47
44
48
/* *
45
49
* A bit of context usable with `*Bulk()` functions.
@@ -91,6 +95,16 @@ class Roaring {
91
95
addMany (l.size (), l.begin ());
92
96
}
93
97
98
+ /* *
99
+ * Construct a roaring object by taking control of a malloc()'d C struct.
100
+ *
101
+ * Passing a NULL pointer is unsafe.
102
+ * The pointer to the C struct will be invalid after the call.
103
+ */
104
+ explicit Roaring (roaring_bitmap_t *s) noexcept : roaring(*s) {
105
+ roaring_free (s); // deallocate the passed-in pointer
106
+ }
107
+
94
108
/* *
95
109
* Copy constructor.
96
110
* It may throw std::runtime_error if there is insufficient memory.
@@ -118,16 +132,6 @@ class Roaring {
118
132
api::roaring_bitmap_init_cleared (&r.roaring );
119
133
}
120
134
121
- /* *
122
- * Construct a roaring object by taking control of a malloc()'d C struct.
123
- *
124
- * Passing a NULL pointer is unsafe.
125
- * The pointer to the C struct will be invalid after the call.
126
- */
127
- explicit Roaring (roaring_bitmap_t *s) noexcept : roaring(*s) {
128
- roaring_free (s); // deallocate the passed-in pointer
129
- }
130
-
131
135
/* *
132
136
* Construct a bitmap from a list of uint32_t values.
133
137
*/
@@ -142,6 +146,44 @@ class Roaring {
142
146
return ans;
143
147
}
144
148
149
+ /* *
150
+ * Copies the content of the provided bitmap, and
151
+ * discard the current content.
152
+ * It may throw std::runtime_error if there is insufficient memory.
153
+ */
154
+ Roaring &operator =(const Roaring &r) {
155
+ if (!api::roaring_bitmap_overwrite (&roaring, &r.roaring )) {
156
+ ROARING_TERMINATE (" failed memory alloc in assignment" );
157
+ }
158
+ api::roaring_bitmap_set_copy_on_write (
159
+ &roaring, api::roaring_bitmap_get_copy_on_write (&r.roaring ));
160
+ return *this ;
161
+ }
162
+
163
+ /* *
164
+ * Moves the content of the provided bitmap, and
165
+ * discard the current content.
166
+ */
167
+ Roaring &operator =(Roaring &&r) noexcept {
168
+ api::roaring_bitmap_clear (&roaring); // free this class's allocations
169
+
170
+ // !!! See notes in the Move Constructor regarding roaring_bitmap_move()
171
+ //
172
+ roaring = r.roaring ;
173
+ api::roaring_bitmap_init_cleared (&r.roaring );
174
+
175
+ return *this ;
176
+ }
177
+
178
+ /* *
179
+ * Assignment from an initializer list.
180
+ */
181
+ Roaring &operator =(std::initializer_list<uint32_t > l) {
182
+ // Delegate to move assignment operator
183
+ *this = Roaring (l);
184
+ return *this ;
185
+ }
186
+
145
187
/* *
146
188
* Construct a bitmap from a list of uint32_t values.
147
189
* E.g., bitmapOfList({1,2,3}).
@@ -242,6 +284,11 @@ class Roaring {
242
284
return api::roaring_bitmap_remove_range_closed (&roaring, min, max);
243
285
}
244
286
287
+ /* *
288
+ * Clears the bitmap.
289
+ */
290
+ void clear () { api::roaring_bitmap_clear (&roaring); }
291
+
245
292
/* *
246
293
* Return the largest value (if not empty)
247
294
*/
@@ -270,63 +317,9 @@ class Roaring {
270
317
return api::roaring_bitmap_contains_range (&roaring, x, y);
271
318
}
272
319
273
- /* *
274
- * Destructor. By contract, calling roaring_bitmap_clear() is enough to
275
- * release all auxiliary memory used by the structure.
276
- */
277
- ~Roaring () {
278
- if (!(roaring.high_low_container .flags & ROARING_FLAG_FROZEN)) {
279
- api::roaring_bitmap_clear (&roaring);
280
- } else {
281
- // The roaring member variable copies the `roaring_bitmap_t` and
282
- // nested `roaring_array_t` structures by value and is freed in the
283
- // constructor, however the underlying memory arena used for the
284
- // container data is not freed with it. Here we derive the arena
285
- // pointer from the second arena allocation in
286
- // `roaring_bitmap_frozen_view` and free it as well.
287
- roaring_bitmap_free (
288
- (roaring_bitmap_t *)((char *)
289
- roaring.high_low_container .containers -
290
- sizeof (roaring_bitmap_t )));
291
- }
292
- }
293
-
294
- /* *
295
- * Copies the content of the provided bitmap, and
296
- * discard the current content.
297
- * It may throw std::runtime_error if there is insufficient memory.
298
- */
299
- Roaring &operator =(const Roaring &r) {
300
- if (!api::roaring_bitmap_overwrite (&roaring, &r.roaring )) {
301
- ROARING_TERMINATE (" failed memory alloc in assignment" );
302
- }
303
- api::roaring_bitmap_set_copy_on_write (
304
- &roaring, api::roaring_bitmap_get_copy_on_write (&r.roaring ));
305
- return *this ;
306
- }
307
-
308
- /* *
309
- * Moves the content of the provided bitmap, and
310
- * discard the current content.
311
- */
312
- Roaring &operator =(Roaring &&r) noexcept {
313
- api::roaring_bitmap_clear (&roaring); // free this class's allocations
314
-
315
- // !!! See notes in the Move Constructor regarding roaring_bitmap_move()
316
- //
317
- roaring = r.roaring ;
318
- api::roaring_bitmap_init_cleared (&r.roaring );
319
-
320
- return *this ;
321
- }
322
-
323
- /* *
324
- * Assignment from an initializer list.
325
- */
326
- Roaring &operator =(std::initializer_list<uint32_t > l) {
327
- // Delegate to move assignment operator
328
- *this = Roaring (l);
329
- return *this ;
320
+ bool containsRangeClosed (const uint32_t x,
321
+ const uint32_t y) const noexcept {
322
+ return api::roaring_bitmap_contains_range_closed (&roaring, x, y);
330
323
}
331
324
332
325
/* *
@@ -393,6 +386,16 @@ class Roaring {
393
386
return api::roaring_bitmap_is_empty (&roaring);
394
387
}
395
388
389
+ /* *
390
+ * Returns true if the bitmap is full (cardinality is uint32_t max + 1).
391
+ * we put std::numeric_limits<>::max/min in parentheses
392
+ * to avoid a clash with the Windows.h header under Windows.
393
+ */
394
+ bool isFull () const noexcept {
395
+ return api::roaring_bitmap_get_cardinality (&roaring) ==
396
+ ((uint64_t )(std::numeric_limits<uint32_t >::max)()) + 1 ;
397
+ }
398
+
396
399
/* *
397
400
* Returns true if the bitmap is subset of the other.
398
401
*/
@@ -443,8 +446,8 @@ class Roaring {
443
446
* [range_start, range_end]. Areas outside the interval are unchanged.
444
447
*/
445
448
void flipClosed (uint32_t range_start, uint32_t range_end) noexcept {
446
- api::roaring_bitmap_flip_inplace (&roaring, range_start,
447
- uint64_t (range_end) + 1 );
449
+ api::roaring_bitmap_flip_inplace_closed (&roaring, range_start,
450
+ range_end );
448
451
}
449
452
450
453
/* *
@@ -868,7 +871,30 @@ class Roaring {
868
871
return ans;
869
872
}
870
873
871
- typedef RoaringSetBitForwardIterator const_iterator;
874
+ /* *
875
+ * Destructor. By contract, calling roaring_bitmap_clear() is enough to
876
+ * release all auxiliary memory used by the structure.
877
+ */
878
+ ~Roaring () {
879
+ if (!(roaring.high_low_container .flags & ROARING_FLAG_FROZEN)) {
880
+ api::roaring_bitmap_clear (&roaring);
881
+ } else {
882
+ // The roaring member variable copies the `roaring_bitmap_t` and
883
+ // nested `roaring_array_t` structures by value and is freed in the
884
+ // constructor, however the underlying memory arena used for the
885
+ // container data is not freed with it. Here we derive the arena
886
+ // pointer from the second arena allocation in
887
+ // `roaring_bitmap_frozen_view` and free it as well.
888
+ roaring_bitmap_free (
889
+ (roaring_bitmap_t *)((char *)
890
+ roaring.high_low_container .containers -
891
+ sizeof (roaring_bitmap_t )));
892
+ }
893
+ }
894
+
895
+ friend class RoaringSetBitBiDirectionalIterator ;
896
+ typedef RoaringSetBitBiDirectionalIterator const_iterator;
897
+ typedef RoaringSetBitBiDirectionalIterator const_bidirectional_iterator;
872
898
873
899
/* *
874
900
* Returns an iterator that can be used to access the position of the set
@@ -893,14 +919,26 @@ class Roaring {
893
919
/* *
894
920
* Used to go through the set bits. Not optimally fast, but convenient.
895
921
*/
896
- class RoaringSetBitForwardIterator final {
922
+ class RoaringSetBitBiDirectionalIterator final {
897
923
public:
898
- typedef std::forward_iterator_tag iterator_category;
924
+ typedef std::bidirectional_iterator_tag iterator_category;
899
925
typedef uint32_t *pointer;
900
926
typedef uint32_t &reference_type;
901
927
typedef uint32_t value_type;
902
928
typedef int32_t difference_type;
903
- typedef RoaringSetBitForwardIterator type_of_iterator;
929
+ typedef RoaringSetBitBiDirectionalIterator type_of_iterator;
930
+
931
+ explicit RoaringSetBitBiDirectionalIterator (const Roaring &parent,
932
+ bool exhausted = false ) {
933
+ if (exhausted) {
934
+ i.parent = &parent.roaring ;
935
+ i.container_index = INT32_MAX;
936
+ i.has_value = false ;
937
+ i.current_value = UINT32_MAX;
938
+ } else {
939
+ api::roaring_iterator_init (&parent.roaring , &i);
940
+ }
941
+ }
904
942
905
943
/* *
906
944
* Provides the location of the set bit.
@@ -931,66 +969,60 @@ class RoaringSetBitForwardIterator final {
931
969
return i.current_value >= *o;
932
970
}
933
971
934
- /* *
935
- * Move the iterator to the first value >= val.
936
- */
937
- void equalorlarger (uint32_t val) {
938
- api::roaring_uint32_iterator_move_equalorlarger (&i, val);
939
- }
940
-
941
972
type_of_iterator &operator ++() { // ++i, must returned inc. value
942
973
api::roaring_uint32_iterator_advance (&i);
943
974
return *this ;
944
975
}
945
976
946
977
type_of_iterator operator ++(int ) { // i++, must return orig. value
947
- RoaringSetBitForwardIterator orig (*this );
978
+ RoaringSetBitBiDirectionalIterator orig (*this );
948
979
api::roaring_uint32_iterator_advance (&i);
949
980
return orig;
950
981
}
951
982
983
+ /* *
984
+ * Move the iterator to the first value >= val.
985
+ * Return true if there is such a value.
986
+ */
987
+ bool move_equalorlarger (value_type val) {
988
+ return api::roaring_uint32_iterator_move_equalorlarger (&i, val);
989
+ }
990
+
991
+ /* * DEPRECATED, use `move_equalorlarger`.*/
992
+ CROARING_DEPRECATED void equalorlarger (uint32_t val) {
993
+ api::roaring_uint32_iterator_move_equalorlarger (&i, val);
994
+ }
995
+
952
996
type_of_iterator &operator --() { // prefix --
953
997
api::roaring_uint32_iterator_previous (&i);
954
998
return *this ;
955
999
}
956
1000
957
1001
type_of_iterator operator --(int ) { // postfix --
958
- RoaringSetBitForwardIterator orig (*this );
1002
+ RoaringSetBitBiDirectionalIterator orig (*this );
959
1003
api::roaring_uint32_iterator_previous (&i);
960
1004
return orig;
961
1005
}
962
1006
963
- bool operator ==(const RoaringSetBitForwardIterator &o) const {
1007
+ bool operator ==(const RoaringSetBitBiDirectionalIterator &o) const {
964
1008
return i.current_value == *o && i.has_value == o.i .has_value ;
965
1009
}
966
1010
967
- bool operator !=(const RoaringSetBitForwardIterator &o) const {
1011
+ bool operator !=(const RoaringSetBitBiDirectionalIterator &o) const {
968
1012
return i.current_value != *o || i.has_value != o.i .has_value ;
969
1013
}
970
1014
971
- explicit RoaringSetBitForwardIterator (const Roaring &parent,
972
- bool exhausted = false ) {
973
- if (exhausted) {
974
- i.parent = &parent.roaring ;
975
- i.container_index = INT32_MAX;
976
- i.has_value = false ;
977
- i.current_value = UINT32_MAX;
978
- } else {
979
- api::roaring_iterator_init (&parent.roaring , &i);
980
- }
981
- }
982
-
983
1015
api::roaring_uint32_iterator_t
984
1016
i{}; // The empty constructor silences warnings from pedantic static
985
1017
// analyzers.
986
1018
};
987
1019
988
- inline RoaringSetBitForwardIterator Roaring::begin () const {
989
- return RoaringSetBitForwardIterator (*this );
1020
+ inline RoaringSetBitBiDirectionalIterator Roaring::begin () const {
1021
+ return RoaringSetBitBiDirectionalIterator (*this );
990
1022
}
991
1023
992
- inline RoaringSetBitForwardIterator &Roaring::end () const {
993
- static RoaringSetBitForwardIterator e (*this , true );
1024
+ inline RoaringSetBitBiDirectionalIterator &Roaring::end () const {
1025
+ static RoaringSetBitBiDirectionalIterator e (*this , true );
994
1026
return e;
995
1027
}
996
1028
0 commit comments