@@ -7,6 +7,7 @@ A C++ header for Roaring Bitmaps.
77#include < algorithm>
88#include < cstdarg>
99#include < initializer_list>
10+ #include < limits>
1011#include < new>
1112#include < stdexcept>
1213#include < string>
@@ -39,7 +40,10 @@ A C++ header for Roaring Bitmaps.
3940
4041namespace roaring {
4142
42- class RoaringSetBitForwardIterator ;
43+ class RoaringSetBitBiDirectionalIterator ;
44+
45+ /* * DEPRECATED, use `RoaringSetBitBiDirectionalIterator`. */
46+ using RoaringSetBitForwardIterator = RoaringSetBitBiDirectionalIterator;
4347
4448/* *
4549 * A bit of context usable with `*Bulk()` functions.
@@ -91,6 +95,16 @@ class Roaring {
9195 addMany (l.size (), l.begin ());
9296 }
9397
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+
94108 /* *
95109 * Copy constructor.
96110 * It may throw std::runtime_error if there is insufficient memory.
@@ -118,16 +132,6 @@ class Roaring {
118132 api::roaring_bitmap_init_cleared (&r.roaring );
119133 }
120134
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-
131135 /* *
132136 * Construct a bitmap from a list of uint32_t values.
133137 */
@@ -142,6 +146,44 @@ class Roaring {
142146 return ans;
143147 }
144148
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+
145187 /* *
146188 * Construct a bitmap from a list of uint32_t values.
147189 * E.g., bitmapOfList({1,2,3}).
@@ -242,6 +284,11 @@ class Roaring {
242284 return api::roaring_bitmap_remove_range_closed (&roaring, min, max);
243285 }
244286
287+ /* *
288+ * Clears the bitmap.
289+ */
290+ void clear () { api::roaring_bitmap_clear (&roaring); }
291+
245292 /* *
246293 * Return the largest value (if not empty)
247294 */
@@ -270,63 +317,9 @@ class Roaring {
270317 return api::roaring_bitmap_contains_range (&roaring, x, y);
271318 }
272319
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);
330323 }
331324
332325 /* *
@@ -393,6 +386,16 @@ class Roaring {
393386 return api::roaring_bitmap_is_empty (&roaring);
394387 }
395388
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+
396399 /* *
397400 * Returns true if the bitmap is subset of the other.
398401 */
@@ -443,8 +446,8 @@ class Roaring {
443446 * [range_start, range_end]. Areas outside the interval are unchanged.
444447 */
445448 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 );
448451 }
449452
450453 /* *
@@ -868,7 +871,30 @@ class Roaring {
868871 return ans;
869872 }
870873
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;
872898
873899 /* *
874900 * Returns an iterator that can be used to access the position of the set
@@ -893,14 +919,26 @@ class Roaring {
893919/* *
894920 * Used to go through the set bits. Not optimally fast, but convenient.
895921 */
896- class RoaringSetBitForwardIterator final {
922+ class RoaringSetBitBiDirectionalIterator final {
897923 public:
898- typedef std::forward_iterator_tag iterator_category;
924+ typedef std::bidirectional_iterator_tag iterator_category;
899925 typedef uint32_t *pointer;
900926 typedef uint32_t &reference_type;
901927 typedef uint32_t value_type;
902928 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+ }
904942
905943 /* *
906944 * Provides the location of the set bit.
@@ -931,66 +969,60 @@ class RoaringSetBitForwardIterator final {
931969 return i.current_value >= *o;
932970 }
933971
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-
941972 type_of_iterator &operator ++() { // ++i, must returned inc. value
942973 api::roaring_uint32_iterator_advance (&i);
943974 return *this ;
944975 }
945976
946977 type_of_iterator operator ++(int ) { // i++, must return orig. value
947- RoaringSetBitForwardIterator orig (*this );
978+ RoaringSetBitBiDirectionalIterator orig (*this );
948979 api::roaring_uint32_iterator_advance (&i);
949980 return orig;
950981 }
951982
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+
952996 type_of_iterator &operator --() { // prefix --
953997 api::roaring_uint32_iterator_previous (&i);
954998 return *this ;
955999 }
9561000
9571001 type_of_iterator operator --(int ) { // postfix --
958- RoaringSetBitForwardIterator orig (*this );
1002+ RoaringSetBitBiDirectionalIterator orig (*this );
9591003 api::roaring_uint32_iterator_previous (&i);
9601004 return orig;
9611005 }
9621006
963- bool operator ==(const RoaringSetBitForwardIterator &o) const {
1007+ bool operator ==(const RoaringSetBitBiDirectionalIterator &o) const {
9641008 return i.current_value == *o && i.has_value == o.i .has_value ;
9651009 }
9661010
967- bool operator !=(const RoaringSetBitForwardIterator &o) const {
1011+ bool operator !=(const RoaringSetBitBiDirectionalIterator &o) const {
9681012 return i.current_value != *o || i.has_value != o.i .has_value ;
9691013 }
9701014
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-
9831015 api::roaring_uint32_iterator_t
9841016 i{}; // The empty constructor silences warnings from pedantic static
9851017 // analyzers.
9861018};
9871019
988- inline RoaringSetBitForwardIterator Roaring::begin () const {
989- return RoaringSetBitForwardIterator (*this );
1020+ inline RoaringSetBitBiDirectionalIterator Roaring::begin () const {
1021+ return RoaringSetBitBiDirectionalIterator (*this );
9901022}
9911023
992- inline RoaringSetBitForwardIterator &Roaring::end () const {
993- static RoaringSetBitForwardIterator e (*this , true );
1024+ inline RoaringSetBitBiDirectionalIterator &Roaring::end () const {
1025+ static RoaringSetBitBiDirectionalIterator e (*this , true );
9941026 return e;
9951027}
9961028
0 commit comments