_ZN7roaring7RoaringC2EmPKj:
   85|  14.3k|    Roaring(size_t n, const uint32_t *data) : Roaring() {
   86|  14.3k|        api::roaring_bitmap_add_many(&roaring, n, data);
   87|  14.3k|    }
_ZN7roaring7RoaringC2Ev:
   76|  21.5k|    Roaring() : roaring{} {
   77|       |        // The empty constructor roaring{} silences warnings from pedantic
   78|       |        // static analyzers.
   79|  21.5k|        api::roaring_bitmap_init_cleared(&roaring);
   80|  21.5k|    }
_ZN7roaring7RoaringD2Ev:
  921|  64.6k|    ~Roaring() {
  922|  64.6k|        if (!(roaring.high_low_container.flags & ROARING_FLAG_FROZEN)) {
  ------------------
  |  |   47|  64.6k|#define ROARING_FLAG_FROZEN UINT8_C(0x2)
  ------------------
  |  Branch (922:13): [True: 64.6k, False: 0]
  ------------------
  923|  64.6k|            api::roaring_bitmap_clear(&roaring);
  924|  64.6k|        } else {
  925|       |            // The roaring member variable copies the `roaring_bitmap_t` and
  926|       |            // nested `roaring_array_t` structures by value and is freed in the
  927|       |            // constructor, however the underlying memory arena used for the
  928|       |            // container data is not freed with it. Here we derive the arena
  929|       |            // pointer from the second arena allocation in
  930|       |            // `roaring_bitmap_frozen_view` and free it as well.
  931|      0|            roaring_bitmap_free(
  932|      0|                (roaring_bitmap_t *)((char *)
  933|      0|                                         roaring.high_low_container.containers -
  934|      0|                                     sizeof(roaring_bitmap_t)));
  935|      0|        }
  936|  64.6k|    }
_ZN7roaring7Roaring11runOptimizeEv:
  501|  14.3k|    bool runOptimize() noexcept {
  502|  14.3k|        return api::roaring_bitmap_run_optimize(&roaring);
  503|  14.3k|    }
_ZN7roaring7Roaring11shrinkToFitEv:
  509|  7.18k|    size_t shrinkToFit() noexcept {
  510|  7.18k|        return api::roaring_bitmap_shrink_to_fit(&roaring);
  511|  7.18k|    }
_ZN7roaring7Roaring3addEj:
  198|  7.18k|    void add(uint32_t x) noexcept { api::roaring_bitmap_add(&roaring, x); }
_ZN7roaring7Roaring10addCheckedEj:
  205|  7.18k|    bool addChecked(uint32_t x) noexcept {
  206|  7.18k|        return api::roaring_bitmap_add_checked(&roaring, x);
  207|  7.18k|    }
_ZN7roaring7Roaring8addRangeEmm:
  212|  7.18k|    void addRange(const uint64_t min, const uint64_t max) noexcept {
  213|  7.18k|        return api::roaring_bitmap_add_range(&roaring, min, max);
  214|  7.18k|    }
_ZN7roaring7Roaring7addManyEmPKj:
  226|  7.18k|    void addMany(size_t n_args, const uint32_t *vals) noexcept {
  227|  7.18k|        api::roaring_bitmap_add_many(&roaring, n_args, vals);
  228|  7.18k|    }
_ZN7roaring7Roaring6removeEj:
  258|  7.18k|    void remove(uint32_t x) noexcept {
  259|  7.18k|        api::roaring_bitmap_remove(&roaring, x);
  260|  7.18k|    }
_ZN7roaring7Roaring13removeCheckedEj:
  267|  7.18k|    bool removeChecked(uint32_t x) noexcept {
  268|  7.18k|        return api::roaring_bitmap_remove_checked(&roaring, x);
  269|  7.18k|    }
_ZN7roaring7Roaring11removeRangeEmm:
  274|  7.18k|    void removeRange(uint64_t min, uint64_t max) noexcept {
  275|  7.18k|        return api::roaring_bitmap_remove_range(&roaring, min, max);
  276|  7.18k|    }
_ZN7roaring7Roaring17removeRangeClosedEjj:
  281|  7.18k|    void removeRangeClosed(uint32_t min, uint32_t max) noexcept {
  282|  7.18k|        return api::roaring_bitmap_remove_range_closed(&roaring, min, max);
  283|  7.18k|    }
_ZNK7roaring7Roaring7maximumEv:
  315|  7.18k|    uint32_t maximum() const noexcept {
  316|  7.18k|        return api::roaring_bitmap_maximum(&roaring);
  317|  7.18k|    }
_ZNK7roaring7Roaring7minimumEv:
  322|  7.18k|    uint32_t minimum() const noexcept {
  323|  7.18k|        return api::roaring_bitmap_minimum(&roaring);
  324|  7.18k|    }
_ZNK7roaring7Roaring8containsEj:
  329|  7.18k|    bool contains(uint32_t x) const noexcept {
  330|  7.18k|        return api::roaring_bitmap_contains(&roaring, x);
  331|  7.18k|    }
_ZNK7roaring7Roaring13containsRangeEmm:
  336|  7.18k|    bool containsRange(const uint64_t x, const uint64_t y) const noexcept {
  337|  7.18k|        return api::roaring_bitmap_contains_range(&roaring, x, y);
  338|  7.18k|    }
_ZNK7roaring7Roaring6selectEjPj:
  534|  7.18k|    bool select(uint32_t rnk, uint32_t *element) const noexcept {
  535|  7.18k|        return api::roaring_bitmap_select(&roaring, rnk, element);
  536|  7.18k|    }
_ZNK7roaring7Roaring9intersectERKS0_:
  548|  7.18k|    bool intersect(const Roaring &r) const noexcept {
  549|  7.18k|        return api::roaring_bitmap_intersect(&roaring, &r.roaring);
  550|  7.18k|    }
_ZNK7roaring7Roaring13jaccard_indexERKS0_:
  559|  7.18k|    double jaccard_index(const Roaring &r) const noexcept {
  560|  7.18k|        return api::roaring_bitmap_jaccard_index(&roaring, &r.roaring);
  561|  7.18k|    }
_ZNK7roaring7Roaring14or_cardinalityERKS0_:
  566|  7.18k|    uint64_t or_cardinality(const Roaring &r) const noexcept {
  567|  7.18k|        return api::roaring_bitmap_or_cardinality(&roaring, &r.roaring);
  568|  7.18k|    }
_ZNK7roaring7Roaring18andnot_cardinalityERKS0_:
  573|  7.18k|    uint64_t andnot_cardinality(const Roaring &r) const noexcept {
  574|  7.18k|        return api::roaring_bitmap_andnot_cardinality(&roaring, &r.roaring);
  575|  7.18k|    }
_ZNK7roaring7Roaring15xor_cardinalityERKS0_:
  581|  7.18k|    uint64_t xor_cardinality(const Roaring &r) const noexcept {
  582|  7.18k|        return api::roaring_bitmap_xor_cardinality(&roaring, &r.roaring);
  583|  7.18k|    }
_ZNK7roaring7Roaring4rankEj:
  593|  7.18k|    uint64_t rank(uint32_t x) const noexcept {
  594|  7.18k|        return api::roaring_bitmap_rank(&roaring, x);
  595|  7.18k|    }
_ZNK7roaring7Roaring14getSizeInBytesEb:
  740|  14.3k|    size_t getSizeInBytes(bool portable = true) const noexcept {
  741|  14.3k|        if (portable) {
  ------------------
  |  Branch (741:13): [True: 14.3k, False: 0]
  ------------------
  742|  14.3k|            return api::roaring_bitmap_portable_size_in_bytes(&roaring);
  743|  14.3k|        } else {
  744|      0|            return api::roaring_bitmap_size_in_bytes(&roaring);
  745|      0|        }
  746|  14.3k|    }
_ZNK7roaring7RoaringanERKS0_:
  802|  7.18k|    Roaring operator&(const Roaring &o) const {
  803|  7.18k|        roaring_bitmap_t *r = api::roaring_bitmap_and(&roaring, &o.roaring);
  804|  7.18k|        if (r == NULL) {
  ------------------
  |  Branch (804:13): [True: 0, False: 7.18k]
  ------------------
  805|      0|            ROARING_TERMINATE("failed materialization in and");
  ------------------
  |  |   27|      0|#define ROARING_TERMINATE(_s) throw std::runtime_error(_s)
  ------------------
  806|      0|        }
  807|  7.18k|        return Roaring(r);
  808|  7.18k|    }
_ZN7roaring7RoaringC2EPNS_3api16roaring_bitmap_sE:
  102|  35.9k|    explicit Roaring(roaring_bitmap_t *s) noexcept : roaring(*s) {
  103|  35.9k|        roaring_free(s);  // deallocate the passed-in pointer
  104|  35.9k|    }
_ZNK7roaring7RoaringmiERKS0_:
  815|  7.18k|    Roaring operator-(const Roaring &o) const {
  816|  7.18k|        roaring_bitmap_t *r = api::roaring_bitmap_andnot(&roaring, &o.roaring);
  817|  7.18k|        if (r == NULL) {
  ------------------
  |  Branch (817:13): [True: 0, False: 7.18k]
  ------------------
  818|      0|            ROARING_TERMINATE("failed materialization in andnot");
  ------------------
  |  |   27|      0|#define ROARING_TERMINATE(_s) throw std::runtime_error(_s)
  ------------------
  819|      0|        }
  820|  7.18k|        return Roaring(r);
  821|  7.18k|    }
_ZNK7roaring7RoaringorERKS0_:
  828|  7.18k|    Roaring operator|(const Roaring &o) const {
  829|  7.18k|        roaring_bitmap_t *r = api::roaring_bitmap_or(&roaring, &o.roaring);
  830|  7.18k|        if (r == NULL) {
  ------------------
  |  Branch (830:13): [True: 0, False: 7.18k]
  ------------------
  831|      0|            ROARING_TERMINATE("failed materialization in or");
  ------------------
  |  |   27|      0|#define ROARING_TERMINATE(_s) throw std::runtime_error(_s)
  ------------------
  832|      0|        }
  833|  7.18k|        return Roaring(r);
  834|  7.18k|    }
_ZNK7roaring7RoaringeoERKS0_:
  841|  7.18k|    Roaring operator^(const Roaring &o) const {
  842|  7.18k|        roaring_bitmap_t *r = api::roaring_bitmap_xor(&roaring, &o.roaring);
  843|  7.18k|        if (r == NULL) {
  ------------------
  |  Branch (843:13): [True: 0, False: 7.18k]
  ------------------
  844|      0|            ROARING_TERMINATE("failed materialization in xor");
  ------------------
  |  |   27|      0|#define ROARING_TERMINATE(_s) throw std::runtime_error(_s)
  ------------------
  845|      0|        }
  846|  7.18k|        return Roaring(r);
  847|  7.18k|    }
_ZN7roaring7RoaringoRERKS0_:
  378|  7.18k|    Roaring &operator|=(const Roaring &r) noexcept {
  379|  7.18k|        api::roaring_bitmap_or_inplace(&roaring, &r.roaring);
  380|  7.18k|        return *this;
  381|  7.18k|    }
_ZN7roaring7RoaringaNERKS0_:
  356|  7.18k|    Roaring &operator&=(const Roaring &r) noexcept {
  357|  7.18k|        api::roaring_bitmap_and_inplace(&roaring, &r.roaring);
  358|  7.18k|        return *this;
  359|  7.18k|    }
_ZN7roaring7RoaringmIERKS0_:
  366|  7.18k|    Roaring &operator-=(const Roaring &r) noexcept {
  367|  7.18k|        api::roaring_bitmap_andnot_inplace(&roaring, &r.roaring);
  368|  7.18k|        return *this;
  369|  7.18k|    }
_ZN7roaring7RoaringeOERKS0_:
  388|  7.18k|    Roaring &operator^=(const Roaring &r) noexcept {
  389|  7.18k|        api::roaring_bitmap_xor_inplace(&roaring, &r.roaring);
  390|  7.18k|        return *this;
  391|  7.18k|    }
_ZNK7roaring7RoaringeqERKS0_:
  458|  14.3k|    bool operator==(const Roaring &r) const noexcept {
  459|  14.3k|        return api::roaring_bitmap_equals(&roaring, &r.roaring);
  460|  14.3k|    }
_ZNK7roaring7Roaring11cardinalityEv:
  401|  7.18k|    uint64_t cardinality() const noexcept {
  402|  7.18k|        return api::roaring_bitmap_get_cardinality(&roaring);
  403|  7.18k|    }
_ZNK7roaring7Roaring7isEmptyEv:
  408|  14.3k|    bool isEmpty() const noexcept {
  409|  14.3k|        return api::roaring_bitmap_is_empty(&roaring);
  410|  14.3k|    }
_ZNK7roaring7Roaring13toUint32ArrayEPj:
  441|  7.18k|    void toUint32Array(uint32_t *ans) const noexcept {
  442|  7.18k|        api::roaring_bitmap_to_uint32_array(&roaring, ans);
  443|  7.18k|    }
_ZNK7roaring7Roaring8isSubsetERKS0_:
  425|  7.18k|    bool isSubset(const Roaring &r) const noexcept {
  426|  7.18k|        return api::roaring_bitmap_is_subset(&roaring, &r.roaring);
  427|  7.18k|    }
_ZNK7roaring7Roaring14isStrictSubsetERKS0_:
  432|  7.18k|    bool isStrictSubset(const Roaring &r) const noexcept {
  433|  7.18k|        return api::roaring_bitmap_is_strict_subset(&roaring, &r.roaring);
  434|  7.18k|    }
_ZN7roaring7Roaring4flipEmm:
  466|  7.18k|    void flip(uint64_t range_start, uint64_t range_end) noexcept {
  467|  7.18k|        api::roaring_bitmap_flip_inplace(&roaring, range_start, range_end);
  468|  7.18k|    }
_ZN7roaring7Roaring10flipClosedEjj:
  474|  7.18k|    void flipClosed(uint32_t range_start, uint32_t range_end) noexcept {
  475|  7.18k|        api::roaring_bitmap_flip_inplace_closed(&roaring, range_start,
  476|  7.18k|                                                range_end);
  477|  7.18k|    }
_ZN7roaring7Roaring20removeRunCompressionEv:
  483|  7.18k|    bool removeRunCompression() noexcept {
  484|  7.18k|        return api::roaring_bitmap_remove_run_compression(&roaring);
  485|  7.18k|    }
_ZN7roaring7RoaringC2ERKS0_:
  110|  7.18k|    Roaring(const Roaring &r) : Roaring() {
  111|  7.18k|        if (!api::roaring_bitmap_overwrite(&roaring, &r.roaring)) {
  ------------------
  |  Branch (111:13): [True: 0, False: 7.18k]
  ------------------
  112|      0|            ROARING_TERMINATE("failed roaring_bitmap_overwrite in constructor");
  ------------------
  |  |   27|      0|#define ROARING_TERMINATE(_s) throw std::runtime_error(_s)
  ------------------
  113|      0|        }
  114|  7.18k|        api::roaring_bitmap_set_copy_on_write(
  115|  7.18k|            &roaring, api::roaring_bitmap_get_copy_on_write(&r.roaring));
  116|  7.18k|    }
_ZN7roaring7RoaringC2EOS0_:
  122|  7.18k|    Roaring(Roaring &&r) noexcept : roaring(r.roaring) {
  123|       |        //
  124|       |        // !!! This clones the bits of the roaring structure to a new location
  125|       |        // and then overwrites the old bits...assuming that this will still
  126|       |        // work.  There are scenarios where this could break; e.g. if some of
  127|       |        // those bits were pointers into the structure memory itself.  If such
  128|       |        // things were possible, a roaring_bitmap_move() API would be needed.
  129|       |        //
  130|  7.18k|        api::roaring_bitmap_init_cleared(&r.roaring);
  131|  7.18k|    }
_ZN7roaring7RoaringaSERKS0_:
  152|  7.18k|    Roaring &operator=(const Roaring &r) {
  153|  7.18k|        if (!api::roaring_bitmap_overwrite(&roaring, &r.roaring)) {
  ------------------
  |  Branch (153:13): [True: 0, False: 7.18k]
  ------------------
  154|      0|            ROARING_TERMINATE("failed memory alloc in assignment");
  ------------------
  |  |   27|      0|#define ROARING_TERMINATE(_s) throw std::runtime_error(_s)
  ------------------
  155|      0|        }
  156|  7.18k|        api::roaring_bitmap_set_copy_on_write(
  157|  7.18k|            &roaring, api::roaring_bitmap_get_copy_on_write(&r.roaring));
  158|  7.18k|        return *this;
  159|  7.18k|    }
_ZN7roaring7RoaringaSEOS0_:
  165|  7.18k|    Roaring &operator=(Roaring &&r) noexcept {
  166|  7.18k|        api::roaring_bitmap_clear(&roaring);  // free this class's allocations
  167|       |
  168|       |        // !!! See notes in the Move Constructor regarding roaring_bitmap_move()
  169|       |        //
  170|  7.18k|        roaring = r.roaring;
  171|  7.18k|        api::roaring_bitmap_init_cleared(&r.roaring);
  172|       |
  173|  7.18k|        return *this;
  174|  7.18k|    }
_ZN7roaring7Roaring8readSafeEPKcm:
  714|  14.3k|    static Roaring readSafe(const char *buf, size_t maxbytes) {
  715|  14.3k|        roaring_bitmap_t *r =
  716|  14.3k|            api::roaring_bitmap_portable_deserialize_safe(buf, maxbytes);
  717|  14.3k|        if (r == NULL) {
  ------------------
  |  Branch (717:13): [True: 7.17k, False: 7.20k]
  ------------------
  718|  7.17k|            ROARING_TERMINATE("failed alloc while reading");
  ------------------
  |  |   27|  7.17k|#define ROARING_TERMINATE(_s) throw std::runtime_error(_s)
  ------------------
  719|  7.17k|        }
  720|  7.20k|        return Roaring(r);
  721|  14.3k|    }
_ZNK7roaring7Roaring5writeEPcb:
  657|  7.18k|    size_t write(char *buf, bool portable = true) const noexcept {
  658|  7.18k|        if (portable) {
  ------------------
  |  Branch (658:13): [True: 7.18k, False: 0]
  ------------------
  659|  7.18k|            return api::roaring_bitmap_portable_serialize(&roaring, buf);
  660|  7.18k|        } else {
  661|      0|            return api::roaring_bitmap_serialize(&roaring, buf);
  662|      0|        }
  663|  7.18k|    }
_ZNK7roaring7Roaring8toStringEv:
  864|  7.18k|    std::string toString() const noexcept {
  865|  7.18k|        struct iter_data {
  866|  7.18k|            std::string str{};  // The empty constructor silences warnings from
  867|       |                                // pedantic static analyzers.
  868|  7.18k|            char first_char = '{';
  869|  7.18k|        } outer_iter_data;
  870|  7.18k|        if (!isEmpty()) {
  ------------------
  |  Branch (870:13): [True: 7.17k, False: 13]
  ------------------
  871|  7.17k|            iterate(
  872|  7.17k|                [](uint32_t value, void *inner_iter_data) -> bool {
  873|  7.17k|                    ((iter_data *)inner_iter_data)->str +=
  874|  7.17k|                        ((iter_data *)inner_iter_data)->first_char;
  875|  7.17k|                    ((iter_data *)inner_iter_data)->str +=
  876|  7.17k|                        std::to_string(value);
  877|  7.17k|                    ((iter_data *)inner_iter_data)->first_char = ',';
  878|  7.17k|                    return true;
  879|  7.17k|                },
  880|  7.17k|                (void *)&outer_iter_data);
  881|  7.17k|        } else
  882|     13|            outer_iter_data.str = '{';
  883|  7.18k|        outer_iter_data.str += '}';
  884|  7.18k|        return outer_iter_data.str;
  885|  7.18k|    }
_ZNK7roaring7Roaring7iterateEPFbjPvES1_:
  522|  7.17k|    void iterate(api::roaring_iterator iterator, void *ptr) const {
  523|  7.17k|        api::roaring_iterate(&roaring, iterator, ptr);
  524|  7.17k|    }
_ZZNK7roaring7Roaring8toStringEvENKUljPvE_clEjS1_:
  872|  3.48G|                [](uint32_t value, void *inner_iter_data) -> bool {
  873|  3.48G|                    ((iter_data *)inner_iter_data)->str +=
  874|  3.48G|                        ((iter_data *)inner_iter_data)->first_char;
  875|  3.48G|                    ((iter_data *)inner_iter_data)->str +=
  876|  3.48G|                        std::to_string(value);
  877|  3.48G|                    ((iter_data *)inner_iter_data)->first_char = ',';
  878|  3.48G|                    return true;
  879|  3.48G|                },
_ZNK7roaring7Roaring5beginEv:
 1081|  14.3k|inline RoaringSetBitBiDirectionalIterator Roaring::begin() const {
 1082|  14.3k|    return RoaringSetBitBiDirectionalIterator(*this);
 1083|  14.3k|}
_ZN7roaring34RoaringSetBitBiDirectionalIteratorC2ERKNS_7RoaringEb:
  975|  14.3k|                                                bool exhausted = false) {
  976|  14.3k|        if (exhausted) {
  ------------------
  |  Branch (976:13): [True: 1, False: 14.3k]
  ------------------
  977|      1|            i.parent = &parent.roaring;
  978|      1|            i.container_index = INT32_MAX;
  979|      1|            i.has_value = false;
  980|      1|            i.current_value = UINT32_MAX;
  981|  14.3k|        } else {
  982|  14.3k|            api::roaring_iterator_init(&parent.roaring, &i);
  983|  14.3k|        }
  984|  14.3k|    }
_ZNK7roaring34RoaringSetBitBiDirectionalIteratorneERKS0_:
 1072|   344k|    bool operator!=(const RoaringSetBitBiDirectionalIterator &o) const {
 1073|   344k|        return i.current_value != *o || i.has_value != o.i.has_value;
  ------------------
  |  Branch (1073:16): [True: 337k, False: 7.18k]
  |  Branch (1073:41): [True: 0, False: 7.18k]
  ------------------
 1074|   344k|    }
_ZNK7roaring34RoaringSetBitBiDirectionalIteratordeEv:
  989|   344k|    value_type operator*() const { return i.current_value; }
_ZNK7roaring7Roaring3endEv:
 1085|   344k|inline RoaringSetBitBiDirectionalIterator &Roaring::end() const {
 1086|   344k|    static RoaringSetBitBiDirectionalIterator e(*this, true);
 1087|   344k|    return e;
 1088|   344k|}
_ZN7roaring34RoaringSetBitBiDirectionalIteratorppEi:
 1020|   337k|    type_of_iterator operator++(int) {  // i++, must return orig. value
 1021|   337k|        RoaringSetBitBiDirectionalIterator orig(*this);
 1022|   337k|        api::roaring_uint32_iterator_advance(&i);
 1023|   337k|        return orig;
 1024|   337k|    }
_ZN7roaring34RoaringSetBitBiDirectionalIterator13equalorlargerEj:
 1035|  7.18k|    CROARING_DEPRECATED void equalorlarger(uint32_t val) {
 1036|  7.18k|        api::roaring_uint32_iterator_move_equalorlarger(&i, val);
 1037|  7.18k|    }

binarySearch:
   53|  8.34M|                            uint16_t ikey) {
   54|  8.34M|    const int32_t gap = 16;
   55|  8.34M|    if (lenarray < gap) {
  ------------------
  |  Branch (55:9): [True: 3.81M, False: 4.52M]
  ------------------
   56|  5.59M|        for (int32_t j = 0; j < lenarray; j++) {
  ------------------
  |  Branch (56:29): [True: 5.58M, False: 7.25k]
  ------------------
   57|  5.58M|            if (array[j] >= ikey) {
  ------------------
  |  Branch (57:17): [True: 3.81M, False: 1.77M]
  ------------------
   58|  3.81M|                return (array[j] == ikey) ? j : -(j + 1);
  ------------------
  |  Branch (58:24): [True: 3.64M, False: 164k]
  ------------------
   59|  3.81M|            }
   60|  5.58M|        }
   61|  7.25k|        return -(lenarray + 1);
   62|  3.81M|    }
   63|  4.52M|    const int32_t num_blocks = lenarray / gap;
   64|  4.52M|    int32_t base = 0;
   65|  4.52M|    int32_t n = num_blocks;
   66|  8.80M|    while (n > 3) {
  ------------------
  |  Branch (66:12): [True: 4.27M, False: 4.52M]
  ------------------
   67|  4.27M|        int32_t quarter = n >> 2;
   68|       |
   69|  4.27M|        int32_t k1 = array[(base + quarter + 1) * gap - 1];
   70|  4.27M|        int32_t k2 = array[(base + 2 * quarter + 1) * gap - 1];
   71|  4.27M|        int32_t k3 = array[(base + 3 * quarter + 1) * gap - 1];
   72|       |
   73|  4.27M|        int32_t c1 = (k1 < ikey);
   74|  4.27M|        int32_t c2 = (k2 < ikey);
   75|  4.27M|        int32_t c3 = (k3 < ikey);
   76|       |
   77|  4.27M|        base += (c1 + c2 + c3) * quarter;
   78|  4.27M|        n -= 3 * quarter;
   79|  4.27M|    }
   80|  8.31M|    while (n > 1) {
  ------------------
  |  Branch (80:12): [True: 3.79M, False: 4.52M]
  ------------------
   81|  3.79M|        int32_t half = n >> 1;
   82|  3.79M|        base = (array[(base + half + 1) * gap - 1] < ikey) ? base + half : base;
  ------------------
  |  Branch (82:16): [True: 501k, False: 3.29M]
  ------------------
   83|  3.79M|        n -= half;
   84|  3.79M|    }
   85|  4.52M|    int32_t lo = (array[(base + 1) * gap - 1] < ikey) ? base + 1 : base;
  ------------------
  |  Branch (85:18): [True: 1.95M, False: 2.57M]
  ------------------
   86|       |
   87|  4.52M|    if (lo < num_blocks) {
  ------------------
  |  Branch (87:9): [True: 4.21M, False: 307k]
  ------------------
   88|  4.21M|        const int32_t start = lo * gap;
   89|  4.21M|#if defined(CROARING_IS_X64)
   90|       |        // SSE2: subs_epu16 yields zero where lane >= ikey. movemask of an
   91|       |        // epi16 compare gives 2 bits per lane; ctz>>1 = lane index. Scan
   92|       |        // the first 8 lanes first and exit early when they contain the
   93|       |        // answer; otherwise the block-narrowing invariant guarantees the
   94|       |        // second-half mask is non-zero.
   95|  4.21M|        __m128i needle = _mm_set1_epi16((short)ikey);
   96|  4.21M|        __m128i zero = _mm_setzero_si128();
   97|  4.21M|        __m128i v0 = _mm_loadu_si128((const __m128i *)(array + start));
   98|  4.21M|        __m128i ge0 = _mm_cmpeq_epi16(_mm_subs_epu16(needle, v0), zero);
   99|  4.21M|        unsigned m0 = (unsigned)_mm_movemask_epi8(ge0);
  100|  4.21M|        if (m0 != 0) {
  ------------------
  |  Branch (100:13): [True: 3.08M, False: 1.12M]
  ------------------
  101|  3.08M|            int32_t j = start + (int32_t)(roaring_trailing_zeroes(m0) >> 1);
  102|  3.08M|            return (array[j] == ikey) ? j : -(j + 1);
  ------------------
  |  Branch (102:20): [True: 2.37M, False: 718k]
  ------------------
  103|  3.08M|        }
  104|  1.12M|        __m128i v1 = _mm_loadu_si128((const __m128i *)(array + start + 8));
  105|  1.12M|        __m128i ge1 = _mm_cmpeq_epi16(_mm_subs_epu16(needle, v1), zero);
  106|  1.12M|        unsigned m1 = (unsigned)_mm_movemask_epi8(ge1);
  107|  1.12M|        int32_t j = start + 8 + (int32_t)(roaring_trailing_zeroes(m1) >> 1);
  108|  1.12M|        return (array[j] == ikey) ? j : -(j + 1);
  ------------------
  |  Branch (108:16): [True: 486k, False: 640k]
  ------------------
  109|       |#else
  110|       |        const int32_t end = start + gap;
  111|       |        for (int32_t j = start; j < end; j++) {
  112|       |            if (array[j] >= ikey) {
  113|       |                return (array[j] == ikey) ? j : -(j + 1);
  114|       |            }
  115|       |        }
  116|       |        // Unreachable: the narrowing guarantees the last element of the
  117|       |        // selected block is >= ikey.
  118|       |        return -(end + 1);
  119|       |#endif
  120|  4.21M|    }
  121|       |
  122|  1.75M|    for (int32_t j = num_blocks * gap; j < lenarray; j++) {
  ------------------
  |  Branch (122:40): [True: 1.74M, False: 10.7k]
  ------------------
  123|  1.74M|        if (array[j] >= ikey) {
  ------------------
  |  Branch (123:13): [True: 296k, False: 1.44M]
  ------------------
  124|   296k|            return (array[j] == ikey) ? j : -(j + 1);
  ------------------
  |  Branch (124:20): [True: 161k, False: 134k]
  ------------------
  125|   296k|        }
  126|  1.74M|    }
  127|  10.7k|    return -(lenarray + 1);
  128|   307k|}
roaring.c:advanceUntil:
  138|    399|                                   int32_t length, uint16_t min) {
  139|    399|    int32_t lower = pos + 1;
  140|       |
  141|    399|    if ((lower >= length) || (array[lower] >= min)) {
  ------------------
  |  Branch (141:9): [True: 399, False: 0]
  |  Branch (141:30): [True: 0, False: 0]
  ------------------
  142|    399|        return lower;
  143|    399|    }
  144|       |
  145|      0|    int32_t spansize = 1;
  146|       |
  147|      0|    while ((lower + spansize < length) && (array[lower + spansize] < min)) {
  ------------------
  |  Branch (147:12): [True: 0, False: 0]
  |  Branch (147:43): [True: 0, False: 0]
  ------------------
  148|      0|        spansize <<= 1;
  149|      0|    }
  150|      0|    int32_t upper = (lower + spansize < length) ? lower + spansize : length - 1;
  ------------------
  |  Branch (150:21): [True: 0, False: 0]
  ------------------
  151|       |
  152|      0|    if (array[upper] == min) {
  ------------------
  |  Branch (152:9): [True: 0, False: 0]
  ------------------
  153|      0|        return upper;
  154|      0|    }
  155|      0|    if (array[upper] < min) {
  ------------------
  |  Branch (155:9): [True: 0, False: 0]
  ------------------
  156|       |        // means
  157|       |        // array
  158|       |        // has no
  159|       |        // item
  160|       |        // >= min
  161|       |        // pos = array.length;
  162|      0|        return length;
  163|      0|    }
  164|       |
  165|       |    // we know that the next-smallest span was too small
  166|      0|    lower += (spansize >> 1);
  167|       |
  168|      0|    int32_t mid = 0;
  169|      0|    while (lower + 1 != upper) {
  ------------------
  |  Branch (169:12): [True: 0, False: 0]
  ------------------
  170|      0|        mid = (lower + upper) >> 1;
  171|      0|        if (array[mid] == min) {
  ------------------
  |  Branch (171:13): [True: 0, False: 0]
  ------------------
  172|      0|            return mid;
  173|      0|        } else if (array[mid] < min) {
  ------------------
  |  Branch (173:20): [True: 0, False: 0]
  ------------------
  174|      0|            lower = mid;
  175|      0|        } else {
  176|      0|            upper = mid;
  177|      0|        }
  178|      0|    }
  179|      0|    return upper;
  180|      0|}
roaring.c:count_greater:
  198|  9.87k|                                    uint16_t ikey) {
  199|  9.87k|    if (lenarray == 0) return 0;
  ------------------
  |  Branch (199:9): [True: 0, False: 9.87k]
  ------------------
  200|  9.87k|    int32_t pos = binarySearch(array, lenarray, ikey);
  201|  9.87k|    if (pos >= 0) {
  ------------------
  |  Branch (201:9): [True: 1.94k, False: 7.93k]
  ------------------
  202|  1.94k|        return lenarray - (pos + 1);
  203|  7.93k|    } else {
  204|  7.93k|        return lenarray - (-pos - 1);
  205|  7.93k|    }
  206|  9.87k|}
roaring.c:count_less:
  187|  17.2k|                                 uint16_t ikey) {
  188|  17.2k|    if (lenarray == 0) return 0;
  ------------------
  |  Branch (188:9): [True: 3.93k, False: 13.3k]
  ------------------
  189|  13.3k|    int32_t pos = binarySearch(array, lenarray, ikey);
  190|  13.3k|    return pos >= 0 ? pos : -(pos + 1);
  ------------------
  |  Branch (190:12): [True: 10.4k, False: 2.86k]
  ------------------
  191|  17.2k|}
array_util.c:advanceUntil:
  138|  16.6k|                                   int32_t length, uint16_t min) {
  139|  16.6k|    int32_t lower = pos + 1;
  140|       |
  141|  16.6k|    if ((lower >= length) || (array[lower] >= min)) {
  ------------------
  |  Branch (141:9): [True: 25, False: 16.6k]
  |  Branch (141:30): [True: 5.31k, False: 11.3k]
  ------------------
  142|  5.33k|        return lower;
  143|  5.33k|    }
  144|       |
  145|  11.3k|    int32_t spansize = 1;
  146|       |
  147|  51.8k|    while ((lower + spansize < length) && (array[lower + spansize] < min)) {
  ------------------
  |  Branch (147:12): [True: 50.6k, False: 1.21k]
  |  Branch (147:43): [True: 40.5k, False: 10.1k]
  ------------------
  148|  40.5k|        spansize <<= 1;
  149|  40.5k|    }
  150|  11.3k|    int32_t upper = (lower + spansize < length) ? lower + spansize : length - 1;
  ------------------
  |  Branch (150:21): [True: 10.1k, False: 1.21k]
  ------------------
  151|       |
  152|  11.3k|    if (array[upper] == min) {
  ------------------
  |  Branch (152:9): [True: 2.48k, False: 8.87k]
  ------------------
  153|  2.48k|        return upper;
  154|  2.48k|    }
  155|  8.87k|    if (array[upper] < min) {
  ------------------
  |  Branch (155:9): [True: 213, False: 8.66k]
  ------------------
  156|       |        // means
  157|       |        // array
  158|       |        // has no
  159|       |        // item
  160|       |        // >= min
  161|       |        // pos = array.length;
  162|    213|        return length;
  163|    213|    }
  164|       |
  165|       |    // we know that the next-smallest span was too small
  166|  8.66k|    lower += (spansize >> 1);
  167|       |
  168|  8.66k|    int32_t mid = 0;
  169|  28.0k|    while (lower + 1 != upper) {
  ------------------
  |  Branch (169:12): [True: 24.2k, False: 3.74k]
  ------------------
  170|  24.2k|        mid = (lower + upper) >> 1;
  171|  24.2k|        if (array[mid] == min) {
  ------------------
  |  Branch (171:13): [True: 4.91k, False: 19.3k]
  ------------------
  172|  4.91k|            return mid;
  173|  19.3k|        } else if (array[mid] < min) {
  ------------------
  |  Branch (173:20): [True: 9.44k, False: 9.92k]
  ------------------
  174|  9.44k|            lower = mid;
  175|  9.92k|        } else {
  176|  9.92k|            upper = mid;
  177|  9.92k|        }
  178|  24.2k|    }
  179|  3.74k|    return upper;
  180|  8.66k|}
array_util.c:croaring_skewed_sizes:
  282|  72.1k|static inline bool croaring_skewed_sizes(size_t size_small, size_t size_large) {
  283|  72.1k|    return size_small * CROARING_SKEWED_MERGE_RATIO < size_large;
  ------------------
  |  |  273|  72.1k|#define CROARING_SKEWED_MERGE_RATIO 8
  ------------------
  284|  72.1k|}
mixed_intersection.c:advanceUntil:
  138|   113k|                                   int32_t length, uint16_t min) {
  139|   113k|    int32_t lower = pos + 1;
  140|       |
  141|   113k|    if ((lower >= length) || (array[lower] >= min)) {
  ------------------
  |  Branch (141:9): [True: 502, False: 112k]
  |  Branch (141:30): [True: 62.9k, False: 49.6k]
  ------------------
  142|  63.4k|        return lower;
  143|  63.4k|    }
  144|       |
  145|  49.6k|    int32_t spansize = 1;
  146|       |
  147|   122k|    while ((lower + spansize < length) && (array[lower + spansize] < min)) {
  ------------------
  |  Branch (147:12): [True: 121k, False: 1.22k]
  |  Branch (147:43): [True: 72.5k, False: 48.4k]
  ------------------
  148|  72.5k|        spansize <<= 1;
  149|  72.5k|    }
  150|  49.6k|    int32_t upper = (lower + spansize < length) ? lower + spansize : length - 1;
  ------------------
  |  Branch (150:21): [True: 48.4k, False: 1.22k]
  ------------------
  151|       |
  152|  49.6k|    if (array[upper] == min) {
  ------------------
  |  Branch (152:9): [True: 22.8k, False: 26.8k]
  ------------------
  153|  22.8k|        return upper;
  154|  22.8k|    }
  155|  26.8k|    if (array[upper] < min) {
  ------------------
  |  Branch (155:9): [True: 485, False: 26.3k]
  ------------------
  156|       |        // means
  157|       |        // array
  158|       |        // has no
  159|       |        // item
  160|       |        // >= min
  161|       |        // pos = array.length;
  162|    485|        return length;
  163|    485|    }
  164|       |
  165|       |    // we know that the next-smallest span was too small
  166|  26.3k|    lower += (spansize >> 1);
  167|       |
  168|  26.3k|    int32_t mid = 0;
  169|  48.9k|    while (lower + 1 != upper) {
  ------------------
  |  Branch (169:12): [True: 33.5k, False: 15.3k]
  ------------------
  170|  33.5k|        mid = (lower + upper) >> 1;
  171|  33.5k|        if (array[mid] == min) {
  ------------------
  |  Branch (171:13): [True: 10.9k, False: 22.5k]
  ------------------
  172|  10.9k|            return mid;
  173|  22.5k|        } else if (array[mid] < min) {
  ------------------
  |  Branch (173:20): [True: 8.68k, False: 13.9k]
  ------------------
  174|  8.68k|            lower = mid;
  175|  13.9k|        } else {
  176|  13.9k|            upper = mid;
  177|  13.9k|        }
  178|  33.5k|    }
  179|  15.3k|    return upper;
  180|  26.3k|}
mixed_subset.c:advanceUntil:
  138|    422|                                   int32_t length, uint16_t min) {
  139|    422|    int32_t lower = pos + 1;
  140|       |
  141|    422|    if ((lower >= length) || (array[lower] >= min)) {
  ------------------
  |  Branch (141:9): [True: 0, False: 422]
  |  Branch (141:30): [True: 224, False: 198]
  ------------------
  142|    224|        return lower;
  143|    224|    }
  144|       |
  145|    198|    int32_t spansize = 1;
  146|       |
  147|    904|    while ((lower + spansize < length) && (array[lower + spansize] < min)) {
  ------------------
  |  Branch (147:12): [True: 816, False: 88]
  |  Branch (147:43): [True: 706, False: 110]
  ------------------
  148|    706|        spansize <<= 1;
  149|    706|    }
  150|    198|    int32_t upper = (lower + spansize < length) ? lower + spansize : length - 1;
  ------------------
  |  Branch (150:21): [True: 110, False: 88]
  ------------------
  151|       |
  152|    198|    if (array[upper] == min) {
  ------------------
  |  Branch (152:9): [True: 0, False: 198]
  ------------------
  153|      0|        return upper;
  154|      0|    }
  155|    198|    if (array[upper] < min) {
  ------------------
  |  Branch (155:9): [True: 6, False: 192]
  ------------------
  156|       |        // means
  157|       |        // array
  158|       |        // has no
  159|       |        // item
  160|       |        // >= min
  161|       |        // pos = array.length;
  162|      6|        return length;
  163|      6|    }
  164|       |
  165|       |    // we know that the next-smallest span was too small
  166|    192|    lower += (spansize >> 1);
  167|       |
  168|    192|    int32_t mid = 0;
  169|    642|    while (lower + 1 != upper) {
  ------------------
  |  Branch (169:12): [True: 450, False: 192]
  ------------------
  170|    450|        mid = (lower + upper) >> 1;
  171|    450|        if (array[mid] == min) {
  ------------------
  |  Branch (171:13): [True: 0, False: 450]
  ------------------
  172|      0|            return mid;
  173|    450|        } else if (array[mid] < min) {
  ------------------
  |  Branch (173:20): [True: 212, False: 238]
  ------------------
  174|    212|            lower = mid;
  175|    238|        } else {
  176|    238|            upper = mid;
  177|    238|        }
  178|    450|    }
  179|    192|    return upper;
  180|    192|}
mixed_andnot.c:advanceUntil:
  138|  79.4k|                                   int32_t length, uint16_t min) {
  139|  79.4k|    int32_t lower = pos + 1;
  140|       |
  141|  79.4k|    if ((lower >= length) || (array[lower] >= min)) {
  ------------------
  |  Branch (141:9): [True: 3.74k, False: 75.7k]
  |  Branch (141:30): [True: 64.0k, False: 11.6k]
  ------------------
  142|  67.8k|        return lower;
  143|  67.8k|    }
  144|       |
  145|  11.6k|    int32_t spansize = 1;
  146|       |
  147|  24.6k|    while ((lower + spansize < length) && (array[lower + spansize] < min)) {
  ------------------
  |  Branch (147:12): [True: 24.1k, False: 467]
  |  Branch (147:43): [True: 12.9k, False: 11.1k]
  ------------------
  148|  12.9k|        spansize <<= 1;
  149|  12.9k|    }
  150|  11.6k|    int32_t upper = (lower + spansize < length) ? lower + spansize : length - 1;
  ------------------
  |  Branch (150:21): [True: 11.1k, False: 467]
  ------------------
  151|       |
  152|  11.6k|    if (array[upper] == min) {
  ------------------
  |  Branch (152:9): [True: 5.36k, False: 6.29k]
  ------------------
  153|  5.36k|        return upper;
  154|  5.36k|    }
  155|  6.29k|    if (array[upper] < min) {
  ------------------
  |  Branch (155:9): [True: 413, False: 5.88k]
  ------------------
  156|       |        // means
  157|       |        // array
  158|       |        // has no
  159|       |        // item
  160|       |        // >= min
  161|       |        // pos = array.length;
  162|    413|        return length;
  163|    413|    }
  164|       |
  165|       |    // we know that the next-smallest span was too small
  166|  5.88k|    lower += (spansize >> 1);
  167|       |
  168|  5.88k|    int32_t mid = 0;
  169|  9.52k|    while (lower + 1 != upper) {
  ------------------
  |  Branch (169:12): [True: 5.74k, False: 3.78k]
  ------------------
  170|  5.74k|        mid = (lower + upper) >> 1;
  171|  5.74k|        if (array[mid] == min) {
  ------------------
  |  Branch (171:13): [True: 2.10k, False: 3.64k]
  ------------------
  172|  2.10k|            return mid;
  173|  3.64k|        } else if (array[mid] < min) {
  ------------------
  |  Branch (173:20): [True: 1.42k, False: 2.22k]
  ------------------
  174|  1.42k|            lower = mid;
  175|  2.22k|        } else {
  176|  2.22k|            upper = mid;
  177|  2.22k|        }
  178|  5.74k|    }
  179|  3.78k|    return upper;
  180|  5.88k|}

roaring.c:bitset_lenrange_cardinality:
   63|  1.29k|                                              uint32_t lenminusone) {
   64|  1.29k|    uint32_t firstword = start / 64;
   65|  1.29k|    uint32_t endword = (start + lenminusone) / 64;
   66|  1.29k|    if (firstword == endword) {
  ------------------
  |  Branch (66:9): [True: 892, False: 399]
  ------------------
   67|    892|        return roaring_hamming(words[firstword] &
   68|    892|                               ((~UINT64_C(0)) >> ((63 - lenminusone) % 64))
   69|    892|                                   << (start % 64));
   70|    892|    }
   71|    399|    int answer =
   72|    399|        roaring_hamming(words[firstword] & ((~UINT64_C(0)) << (start % 64)));
   73|   192k|    for (uint32_t i = firstword + 1; i < endword; i++) {
  ------------------
  |  Branch (73:38): [True: 192k, False: 399]
  ------------------
   74|   192k|        answer += roaring_hamming(words[i]);
   75|   192k|    }
   76|    399|    answer += roaring_hamming(words[endword] &
   77|       |                              (~UINT64_C(0)) >>
   78|    399|                                  (((~start + 1) - lenminusone - 1) % 64));
   79|    399|    return answer;
   80|  1.29k|}
roaring.c:bitset_reset_range:
  147|  1.25k|                                      uint32_t end) {
  148|  1.25k|    if (start == end) return;
  ------------------
  |  Branch (148:9): [True: 0, False: 1.25k]
  ------------------
  149|  1.25k|    uint32_t firstword = start / 64;
  150|  1.25k|    uint32_t endword = (end - 1) / 64;
  151|  1.25k|    if (firstword == endword) {
  ------------------
  |  Branch (151:9): [True: 892, False: 365]
  ------------------
  152|    892|        words[firstword] &= ~(((~UINT64_C(0)) << (start % 64)) &
  153|    892|                              ((~UINT64_C(0)) >> ((~end + 1) % 64)));
  154|    892|        return;
  155|    892|    }
  156|    365|    words[firstword] &= ~((~UINT64_C(0)) << (start % 64));
  157|   163k|    for (uint32_t i = firstword + 1; i < endword; i++) {
  ------------------
  |  Branch (157:38): [True: 163k, False: 365]
  ------------------
  158|   163k|        words[i] = UINT64_C(0);
  159|   163k|    }
  160|       |    words[endword] &= ~((~UINT64_C(0)) >> ((~end + 1) % 64));
  161|    365|}
roaring.c:bitset_set_lenrange:
  112|  1.46k|                                       uint32_t lenminusone) {
  113|  1.46k|    uint32_t firstword = start / 64;
  114|  1.46k|    uint32_t endword = (start + lenminusone) / 64;
  115|  1.46k|    if (firstword == endword) {
  ------------------
  |  Branch (115:9): [True: 0, False: 1.46k]
  ------------------
  116|      0|        words[firstword] |= ((~UINT64_C(0)) >> ((63 - lenminusone) % 64))
  117|      0|                            << (start % 64);
  118|      0|        return;
  119|      0|    }
  120|  1.46k|    uint64_t temp = words[endword];
  121|  1.46k|    words[firstword] |= (~UINT64_C(0)) << (start % 64);
  122|   465k|    for (uint32_t i = firstword + 1; i < endword; i += 2)
  ------------------
  |  Branch (122:38): [True: 464k, False: 1.46k]
  ------------------
  123|   464k|        words[i] = words[i + 1] = ~UINT64_C(0);
  124|  1.46k|    words[endword] =
  125|       |        temp | (~UINT64_C(0)) >> (((~start + 1) - lenminusone - 1) % 64);
  126|  1.46k|}
bitset.c:avx2_harley_seal_popcount256:
  377|  3.12k|                                                    const uint64_t size) {
  378|  3.12k|    __m256i total = _mm256_setzero_si256();
  379|  3.12k|    __m256i ones = _mm256_setzero_si256();
  380|  3.12k|    __m256i twos = _mm256_setzero_si256();
  381|  3.12k|    __m256i fours = _mm256_setzero_si256();
  382|  3.12k|    __m256i eights = _mm256_setzero_si256();
  383|  3.12k|    __m256i sixteens = _mm256_setzero_si256();
  384|  3.12k|    __m256i twosA, twosB, foursA, foursB, eightsA, eightsB;
  385|       |
  386|  3.12k|    const uint64_t limit = size - size % 16;
  387|  3.12k|    uint64_t i = 0;
  388|       |
  389|  53.1k|    for (; i < limit; i += 16) {
  ------------------
  |  Branch (389:12): [True: 50.0k, False: 3.12k]
  ------------------
  390|  50.0k|        CSA(&twosA, &ones, ones, _mm256_loadu_si256(data + i),
  391|  50.0k|            _mm256_loadu_si256(data + i + 1));
  392|  50.0k|        CSA(&twosB, &ones, ones, _mm256_loadu_si256(data + i + 2),
  393|  50.0k|            _mm256_loadu_si256(data + i + 3));
  394|  50.0k|        CSA(&foursA, &twos, twos, twosA, twosB);
  395|  50.0k|        CSA(&twosA, &ones, ones, _mm256_loadu_si256(data + i + 4),
  396|  50.0k|            _mm256_loadu_si256(data + i + 5));
  397|  50.0k|        CSA(&twosB, &ones, ones, _mm256_loadu_si256(data + i + 6),
  398|  50.0k|            _mm256_loadu_si256(data + i + 7));
  399|  50.0k|        CSA(&foursB, &twos, twos, twosA, twosB);
  400|  50.0k|        CSA(&eightsA, &fours, fours, foursA, foursB);
  401|  50.0k|        CSA(&twosA, &ones, ones, _mm256_loadu_si256(data + i + 8),
  402|  50.0k|            _mm256_loadu_si256(data + i + 9));
  403|  50.0k|        CSA(&twosB, &ones, ones, _mm256_loadu_si256(data + i + 10),
  404|  50.0k|            _mm256_loadu_si256(data + i + 11));
  405|  50.0k|        CSA(&foursA, &twos, twos, twosA, twosB);
  406|  50.0k|        CSA(&twosA, &ones, ones, _mm256_loadu_si256(data + i + 12),
  407|  50.0k|            _mm256_loadu_si256(data + i + 13));
  408|  50.0k|        CSA(&twosB, &ones, ones, _mm256_loadu_si256(data + i + 14),
  409|  50.0k|            _mm256_loadu_si256(data + i + 15));
  410|  50.0k|        CSA(&foursB, &twos, twos, twosA, twosB);
  411|  50.0k|        CSA(&eightsB, &fours, fours, foursA, foursB);
  412|  50.0k|        CSA(&sixteens, &eights, eights, eightsA, eightsB);
  413|       |
  414|  50.0k|        total = _mm256_add_epi64(total, popcount256(sixteens));
  415|  50.0k|    }
  416|       |
  417|  3.12k|    total = _mm256_slli_epi64(total, 4);  // * 16
  418|  3.12k|    total = _mm256_add_epi64(
  419|  3.12k|        total, _mm256_slli_epi64(popcount256(eights), 3));  // += 8 * ...
  420|  3.12k|    total = _mm256_add_epi64(
  421|  3.12k|        total, _mm256_slli_epi64(popcount256(fours), 2));  // += 4 * ...
  422|  3.12k|    total = _mm256_add_epi64(
  423|  3.12k|        total, _mm256_slli_epi64(popcount256(twos), 1));  // += 2 * ...
  424|  3.12k|    total = _mm256_add_epi64(total, popcount256(ones));
  425|  3.12k|    for (; i < size; i++)
  ------------------
  |  Branch (425:12): [True: 0, False: 3.12k]
  ------------------
  426|      0|        total =
  427|      0|            _mm256_add_epi64(total, popcount256(_mm256_loadu_si256(data + i)));
  428|       |
  429|  3.12k|    return (uint64_t)(_mm256_extract_epi64(total, 0)) +
  430|  3.12k|           (uint64_t)(_mm256_extract_epi64(total, 1)) +
  431|  3.12k|           (uint64_t)(_mm256_extract_epi64(total, 2)) +
  432|       |           (uint64_t)(_mm256_extract_epi64(total, 3));
  433|  3.12k|}
bitset.c:CSA:
  365|  1.41M|                       __m256i c) {
  366|  1.41M|    const __m256i u = _mm256_xor_si256(a, b);
  367|  1.41M|    *h = _mm256_or_si256(_mm256_and_si256(a, b), _mm256_and_si256(u, c));
  368|  1.41M|    *l = _mm256_xor_si256(u, c);
  369|  1.41M|}
bitset.c:popcount256:
  329|   117k|static inline __m256i popcount256(__m256i v) {
  330|   117k|    const __m256i lookuppos = _mm256_setr_epi8(
  331|   117k|        /* 0 */ 4 + 0, /* 1 */ 4 + 1, /* 2 */ 4 + 1, /* 3 */ 4 + 2,
  332|   117k|        /* 4 */ 4 + 1, /* 5 */ 4 + 2, /* 6 */ 4 + 2, /* 7 */ 4 + 3,
  333|   117k|        /* 8 */ 4 + 1, /* 9 */ 4 + 2, /* a */ 4 + 2, /* b */ 4 + 3,
  334|   117k|        /* c */ 4 + 2, /* d */ 4 + 3, /* e */ 4 + 3, /* f */ 4 + 4,
  335|       |
  336|       |        /* 0 */ 4 + 0, /* 1 */ 4 + 1, /* 2 */ 4 + 1, /* 3 */ 4 + 2,
  337|   117k|        /* 4 */ 4 + 1, /* 5 */ 4 + 2, /* 6 */ 4 + 2, /* 7 */ 4 + 3,
  338|   117k|        /* 8 */ 4 + 1, /* 9 */ 4 + 2, /* a */ 4 + 2, /* b */ 4 + 3,
  339|   117k|        /* c */ 4 + 2, /* d */ 4 + 3, /* e */ 4 + 3, /* f */ 4 + 4);
  340|   117k|    const __m256i lookupneg = _mm256_setr_epi8(
  341|   117k|        /* 0 */ 4 - 0, /* 1 */ 4 - 1, /* 2 */ 4 - 1, /* 3 */ 4 - 2,
  342|   117k|        /* 4 */ 4 - 1, /* 5 */ 4 - 2, /* 6 */ 4 - 2, /* 7 */ 4 - 3,
  343|   117k|        /* 8 */ 4 - 1, /* 9 */ 4 - 2, /* a */ 4 - 2, /* b */ 4 - 3,
  344|   117k|        /* c */ 4 - 2, /* d */ 4 - 3, /* e */ 4 - 3, /* f */ 4 - 4,
  345|       |
  346|       |        /* 0 */ 4 - 0, /* 1 */ 4 - 1, /* 2 */ 4 - 1, /* 3 */ 4 - 2,
  347|   117k|        /* 4 */ 4 - 1, /* 5 */ 4 - 2, /* 6 */ 4 - 2, /* 7 */ 4 - 3,
  348|   117k|        /* 8 */ 4 - 1, /* 9 */ 4 - 2, /* a */ 4 - 2, /* b */ 4 - 3,
  349|   117k|        /* c */ 4 - 2, /* d */ 4 - 3, /* e */ 4 - 3, /* f */ 4 - 4);
  350|   117k|    const __m256i low_mask = _mm256_set1_epi8(0x0f);
  351|       |
  352|   117k|    const __m256i lo = _mm256_and_si256(v, low_mask);
  353|   117k|    const __m256i hi = _mm256_and_si256(_mm256_srli_epi16(v, 4), low_mask);
  354|   117k|    const __m256i popcnt1 = _mm256_shuffle_epi8(lookuppos, lo);
  355|   117k|    const __m256i popcnt2 = _mm256_shuffle_epi8(lookupneg, hi);
  356|   117k|    return _mm256_sad_epu8(popcnt1, popcnt2);
  357|   117k|}
convert.c:bitset_set_lenrange:
  112|   116k|                                       uint32_t lenminusone) {
  113|   116k|    uint32_t firstword = start / 64;
  114|   116k|    uint32_t endword = (start + lenminusone) / 64;
  115|   116k|    if (firstword == endword) {
  ------------------
  |  Branch (115:9): [True: 48.6k, False: 67.5k]
  ------------------
  116|  48.6k|        words[firstword] |= ((~UINT64_C(0)) >> ((63 - lenminusone) % 64))
  117|  48.6k|                            << (start % 64);
  118|  48.6k|        return;
  119|  48.6k|    }
  120|  67.5k|    uint64_t temp = words[endword];
  121|  67.5k|    words[firstword] |= (~UINT64_C(0)) << (start % 64);
  122|  32.9M|    for (uint32_t i = firstword + 1; i < endword; i += 2)
  ------------------
  |  Branch (122:38): [True: 32.9M, False: 67.5k]
  ------------------
  123|  32.9M|        words[i] = words[i + 1] = ~UINT64_C(0);
  124|  67.5k|    words[endword] =
  125|       |        temp | (~UINT64_C(0)) >> (((~start + 1) - lenminusone - 1) % 64);
  126|  67.5k|}
mixed_intersection.c:bitset_lenrange_cardinality:
   63|   183k|                                              uint32_t lenminusone) {
   64|   183k|    uint32_t firstword = start / 64;
   65|   183k|    uint32_t endword = (start + lenminusone) / 64;
   66|   183k|    if (firstword == endword) {
  ------------------
  |  Branch (66:9): [True: 179k, False: 4.82k]
  ------------------
   67|   179k|        return roaring_hamming(words[firstword] &
   68|   179k|                               ((~UINT64_C(0)) >> ((63 - lenminusone) % 64))
   69|   179k|                                   << (start % 64));
   70|   179k|    }
   71|  4.82k|    int answer =
   72|  4.82k|        roaring_hamming(words[firstword] & ((~UINT64_C(0)) << (start % 64)));
   73|  5.11k|    for (uint32_t i = firstword + 1; i < endword; i++) {
  ------------------
  |  Branch (73:38): [True: 288, False: 4.82k]
  ------------------
   74|    288|        answer += roaring_hamming(words[i]);
   75|    288|    }
   76|  4.82k|    answer += roaring_hamming(words[endword] &
   77|       |                              (~UINT64_C(0)) >>
   78|  4.82k|                                  (((~start + 1) - lenminusone - 1) % 64));
   79|  4.82k|    return answer;
   80|   183k|}
mixed_intersection.c:bitset_lenrange_empty:
   86|  3.74k|                                         uint32_t lenminusone) {
   87|  3.74k|    uint32_t firstword = start / 64;
   88|  3.74k|    uint32_t endword = (start + lenminusone) / 64;
   89|  3.74k|    if (firstword == endword) {
  ------------------
  |  Branch (89:9): [True: 3.43k, False: 302]
  ------------------
   90|  3.43k|        return (words[firstword] & ((~UINT64_C(0)) >> ((63 - lenminusone) % 64))
   91|  3.43k|                                       << (start % 64)) == 0;
   92|  3.43k|    }
   93|    302|    if (((words[firstword] & ((~UINT64_C(0)) << (start % 64)))) != 0) {
  ------------------
  |  Branch (93:9): [True: 106, False: 196]
  ------------------
   94|    106|        return false;
   95|    106|    }
   96|    207|    for (uint32_t i = firstword + 1; i < endword; i++) {
  ------------------
  |  Branch (96:38): [True: 12, False: 195]
  ------------------
   97|     12|        if (words[i] != 0) {
  ------------------
  |  Branch (97:13): [True: 1, False: 11]
  ------------------
   98|      1|            return false;
   99|      1|        }
  100|     12|    }
  101|    195|    if ((words[endword] &
  ------------------
  |  Branch (101:9): [True: 107, False: 88]
  ------------------
  102|    195|         (~UINT64_C(0)) >> (((~start + 1) - lenminusone - 1) % 64)) != 0) {
  103|    107|        return false;
  104|    107|    }
  105|     88|    return true;
  106|    195|}
mixed_union.c:bitset_set_lenrange:
  112|  91.9k|                                       uint32_t lenminusone) {
  113|  91.9k|    uint32_t firstword = start / 64;
  114|  91.9k|    uint32_t endword = (start + lenminusone) / 64;
  115|  91.9k|    if (firstword == endword) {
  ------------------
  |  Branch (115:9): [True: 89.5k, False: 2.41k]
  ------------------
  116|  89.5k|        words[firstword] |= ((~UINT64_C(0)) >> ((63 - lenminusone) % 64))
  117|  89.5k|                            << (start % 64);
  118|  89.5k|        return;
  119|  89.5k|    }
  120|  2.41k|    uint64_t temp = words[endword];
  121|  2.41k|    words[firstword] |= (~UINT64_C(0)) << (start % 64);
  122|  2.52k|    for (uint32_t i = firstword + 1; i < endword; i += 2)
  ------------------
  |  Branch (122:38): [True: 106, False: 2.41k]
  ------------------
  123|    106|        words[i] = words[i + 1] = ~UINT64_C(0);
  124|  2.41k|    words[endword] =
  125|       |        temp | (~UINT64_C(0)) >> (((~start + 1) - lenminusone - 1) % 64);
  126|  2.41k|}
mixed_negation.c:bitset_flip_range:
  132|  1.30k|                                     uint32_t end) {
  133|  1.30k|    if (start == end) return;
  ------------------
  |  Branch (133:9): [True: 0, False: 1.30k]
  ------------------
  134|  1.30k|    uint32_t firstword = start / 64;
  135|  1.30k|    uint32_t endword = (end - 1) / 64;
  136|  1.30k|    words[firstword] ^= ~((~UINT64_C(0)) << (start % 64));
  137|  86.5k|    for (uint32_t i = firstword; i < endword; i++) {
  ------------------
  |  Branch (137:34): [True: 85.2k, False: 1.30k]
  ------------------
  138|  85.2k|        words[i] = ~words[i];
  139|  85.2k|    }
  140|       |    words[endword] ^= ((~UINT64_C(0)) >> ((~end + 1) % 64));
  141|  1.30k|}
mixed_xor.c:bitset_flip_range:
  132|  49.3k|                                     uint32_t end) {
  133|  49.3k|    if (start == end) return;
  ------------------
  |  Branch (133:9): [True: 0, False: 49.3k]
  ------------------
  134|  49.3k|    uint32_t firstword = start / 64;
  135|  49.3k|    uint32_t endword = (end - 1) / 64;
  136|  49.3k|    words[firstword] ^= ~((~UINT64_C(0)) << (start % 64));
  137|   115k|    for (uint32_t i = firstword; i < endword; i++) {
  ------------------
  |  Branch (137:34): [True: 65.7k, False: 49.3k]
  ------------------
  138|  65.7k|        words[i] = ~words[i];
  139|  65.7k|    }
  140|       |    words[endword] ^= ((~UINT64_C(0)) >> ((~end + 1) % 64));
  141|  49.3k|}

array_container_contains:
  345|  4.31k|                                     uint16_t pos) {
  346|       |    /**
  347|       |     * SIMD Quad algorithm
  348|       |     * Daniel Lemire, "You can beat the binary search," in Daniel Lemire's blog,
  349|       |     *  April 27, 2026,
  350|       |     * https://lemire.me/blog/2026/04/27/you-can-beat-the-binary-search/.
  351|       |     */
  352|  4.31k|    const int32_t gap = 16;
  353|  4.31k|    const uint16_t *carr = arr->array;
  354|  4.31k|    int32_t cardinality = arr->cardinality;
  355|  4.31k|    if (cardinality < gap) {
  ------------------
  |  Branch (355:9): [True: 1.65k, False: 2.65k]
  ------------------
  356|  1.78k|        for (int32_t j = 0; j < cardinality; j++) {
  ------------------
  |  Branch (356:29): [True: 1.75k, False: 29]
  ------------------
  357|  1.75k|            if (carr[j] >= pos) return carr[j] == pos;
  ------------------
  |  Branch (357:17): [True: 1.63k, False: 123]
  ------------------
  358|  1.75k|        }
  359|     29|        return false;
  360|  1.65k|    }
  361|  2.65k|    int32_t num_blocks = cardinality / gap;
  362|  2.65k|    int32_t base = 0;
  363|  2.65k|    int32_t n = num_blocks;
  364|  5.77k|    while (n > 3) {
  ------------------
  |  Branch (364:12): [True: 3.11k, False: 2.65k]
  ------------------
  365|  3.11k|        int32_t quarter = n >> 2;
  366|       |
  367|  3.11k|        int32_t k1 = carr[(base + quarter + 1) * gap - 1];
  368|  3.11k|        int32_t k2 = carr[(base + 2 * quarter + 1) * gap - 1];
  369|  3.11k|        int32_t k3 = carr[(base + 3 * quarter + 1) * gap - 1];
  370|       |
  371|  3.11k|        int32_t c1 = (k1 < pos);
  372|  3.11k|        int32_t c2 = (k2 < pos);
  373|  3.11k|        int32_t c3 = (k3 < pos);
  374|       |
  375|  3.11k|        base += (c1 + c2 + c3) * quarter;
  376|  3.11k|        n -= 3 * quarter;
  377|  3.11k|    }
  378|  4.73k|    while (n > 1) {
  ------------------
  |  Branch (378:12): [True: 2.08k, False: 2.65k]
  ------------------
  379|  2.08k|        int32_t half = n >> 1;
  380|  2.08k|        base = (carr[(base + half + 1) * gap - 1] < pos) ? base + half : base;
  ------------------
  |  Branch (380:16): [True: 69, False: 2.01k]
  ------------------
  381|  2.08k|        n -= half;
  382|  2.08k|    }
  383|  2.65k|    int32_t lo = (carr[(base + 1) * gap - 1] < pos) ? base + 1 : base;
  ------------------
  |  Branch (383:18): [True: 113, False: 2.54k]
  ------------------
  384|       |
  385|  2.65k|    if (lo < num_blocks) {
  ------------------
  |  Branch (385:9): [True: 2.58k, False: 73]
  ------------------
  386|  2.58k|        const uint16_t *blk = carr + lo * gap;
  387|       |#ifdef CROARING_USENEON
  388|       |        uint16x8_t needle = vdupq_n_u16(pos);
  389|       |        uint16x8_t v0 = vld1q_u16(blk);
  390|       |        uint16x8_t v1 = vld1q_u16(blk + 8);
  391|       |        uint16x8_t hit =
  392|       |            vorrq_u16(vceqq_u16(v0, needle), vceqq_u16(v1, needle));
  393|       |#ifdef __arm__
  394|       |        uint16x4_t hit8 = vmax_u16(vget_low_u16(hit), vget_high_u16(hit));
  395|       |        uint16x4_t hit4 = vpmax_u16(hit8, hit8);
  396|       |        return vget_lane_u32(hit4, 0) != 0;
  397|       |#else /* __aarch64__ */
  398|       |        return vmaxvq_u16(hit) != 0;
  399|       |#endif
  400|       |#elif defined(CROARING_IS_X64)
  401|       |        __m128i needle = _mm_set1_epi16((short)pos);
  402|  2.58k|        __m128i v0 = _mm_loadu_si128((const __m128i *)blk);
  403|  2.58k|        __m128i v1 = _mm_loadu_si128((const __m128i *)(blk + 8));
  404|  2.58k|        __m128i hit = _mm_or_si128(_mm_cmpeq_epi16(v0, needle),
  405|  2.58k|                                   _mm_cmpeq_epi16(v1, needle));
  406|  2.58k|        return _mm_movemask_epi8(hit) != 0;
  407|       |#else
  408|       |        for (int32_t j = 0; j < gap; j++) {
  409|       |            if (blk[j] >= pos) return blk[j] == pos;
  410|       |        }
  411|       |        return false;
  412|       |#endif
  413|  2.58k|    }
  414|       |
  415|    466|    for (int32_t j = num_blocks * gap; j < cardinality; j++) {
  ------------------
  |  Branch (415:40): [True: 423, False: 43]
  ------------------
  416|    423|        uint16_t v = carr[j];
  417|    423|        if (v >= pos) return (v == pos);
  ------------------
  |  Branch (417:13): [True: 30, False: 393]
  ------------------
  418|    423|    }
  419|     43|    return false;
  420|     73|}
array_container_minimum:
  454|  4.58k|inline uint16_t array_container_minimum(const array_container_t *arr) {
  455|  4.58k|    if (arr->cardinality == 0) return 0;
  ------------------
  |  Branch (455:9): [True: 0, False: 4.58k]
  ------------------
  456|  4.58k|    return arr->array[0];
  457|  4.58k|}
array_container_maximum:
  461|  15.8k|inline uint16_t array_container_maximum(const array_container_t *arr) {
  462|  15.8k|    if (arr->cardinality == 0) return 0;
  ------------------
  |  Branch (462:9): [True: 0, False: 15.8k]
  ------------------
  463|  15.8k|    return arr->array[arr->cardinality - 1];
  464|  15.8k|}
array_container_rank:
  467|  4.76k|inline int array_container_rank(const array_container_t *arr, uint16_t x) {
  468|  4.76k|    const int32_t idx = binarySearch(arr->array, arr->cardinality, x);
  469|  4.76k|    const bool is_present = idx >= 0;
  470|  4.76k|    if (is_present) {
  ------------------
  |  Branch (470:9): [True: 4.11k, False: 659]
  ------------------
  471|  4.11k|        return idx + 1;
  472|  4.11k|    } else {
  473|    659|        return -idx - 1;
  474|    659|    }
  475|  4.76k|}
array_container_index_equalorlarger:
  517|  5.31k|                                               uint16_t x) {
  518|  5.31k|    const int32_t idx = binarySearch(arr->array, arr->cardinality, x);
  519|  5.31k|    const bool is_present = idx >= 0;
  520|  5.31k|    if (is_present) {
  ------------------
  |  Branch (520:9): [True: 4.94k, False: 364]
  ------------------
  521|  4.94k|        return idx;
  522|  4.94k|    } else {
  523|    364|        int32_t candidate = -idx - 1;
  524|    364|        if (candidate < arr->cardinality) return candidate;
  ------------------
  |  Branch (524:13): [True: 364, False: 0]
  ------------------
  525|      0|        return -1;
  526|    364|    }
  527|  5.31k|}
roaring.c:array_container_add_range_nvals:
  537|    642|                                                   int32_t nvals_greater) {
  538|    642|    int32_t union_cardinality = nvals_less + (max - min + 1) + nvals_greater;
  539|    642|    if (union_cardinality > array->capacity) {
  ------------------
  |  Branch (539:9): [True: 598, False: 44]
  ------------------
  540|    598|        array_container_grow(array, union_cardinality, true);
  541|    598|    }
  542|    642|    memmove(&(array->array[union_cardinality - nvals_greater]),
  543|    642|            &(array->array[array->cardinality - nvals_greater]),
  544|    642|            nvals_greater * sizeof(uint16_t));
  545|  1.56M|    for (uint32_t i = 0; i <= max - min; i++) {
  ------------------
  |  Branch (545:26): [True: 1.55M, False: 642]
  ------------------
  546|  1.55M|        array->array[nvals_less + i] = (uint16_t)(min + i);
  547|  1.55M|    }
  548|    642|    array->cardinality = union_cardinality;
  549|    642|}
roaring.c:array_container_remove_range:
  567|  4.15k|                                                uint32_t pos, uint32_t count) {
  568|  4.15k|    if (count != 0) {
  ------------------
  |  Branch (568:9): [True: 334, False: 3.81k]
  ------------------
  569|    334|        memmove(&(array->array[pos]), &(array->array[pos + count]),
  570|    334|                (array->cardinality - pos - count) * sizeof(uint16_t));
  571|    334|        array->cardinality -= count;
  572|    334|    }
  573|  4.15k|}
roaring.c:array_container_cardinality:
   82|  85.4k|static inline int array_container_cardinality(const array_container_t *array) {
   83|  85.4k|    return array->cardinality;
   84|  85.4k|}
roaring.c:array_container_try_add:
  294|  8.32M|                                          int32_t max_cardinality) {
  295|  8.32M|    const int32_t cardinality = arr->cardinality;
  296|       |
  297|       |    // best case, we can append.
  298|  8.32M|    if ((array_container_empty(arr) || arr->array[cardinality - 1] < value) &&
  ------------------
  |  Branch (298:10): [True: 17.3k, False: 8.30M]
  |  Branch (298:40): [True: 55.8k, False: 8.24M]
  ------------------
  299|  73.2k|        cardinality < max_cardinality) {
  ------------------
  |  Branch (299:9): [True: 73.2k, False: 0]
  ------------------
  300|  73.2k|        array_container_append(arr, value);
  301|  73.2k|        return 1;
  302|  73.2k|    }
  303|       |
  304|  8.24M|    const int32_t loc = binarySearch(arr->array, cardinality, value);
  305|       |
  306|  8.24M|    if (loc >= 0) {
  ------------------
  |  Branch (306:9): [True: 6.61M, False: 1.62M]
  ------------------
  307|  6.61M|        return 0;
  308|  6.61M|    } else if (cardinality < max_cardinality) {
  ------------------
  |  Branch (308:16): [True: 1.62M, False: 162]
  ------------------
  309|  1.62M|        if (array_container_full(arr)) {
  ------------------
  |  Branch (309:13): [True: 78.6k, False: 1.55M]
  ------------------
  310|  78.6k|            array_container_grow(arr, arr->capacity + 1, true);
  311|  78.6k|        }
  312|  1.62M|        const int32_t insert_idx = -loc - 1;
  313|  1.62M|        memmove(arr->array + insert_idx + 1, arr->array + insert_idx,
  314|  1.62M|                (cardinality - insert_idx) * sizeof(uint16_t));
  315|  1.62M|        arr->array[insert_idx] = value;
  316|  1.62M|        arr->cardinality++;
  317|  1.62M|        return 1;
  318|  1.62M|    } else {
  319|    162|        return -1;
  320|    162|    }
  321|  8.24M|}
roaring.c:array_container_empty:
  100|  8.32M|static inline bool array_container_empty(const array_container_t *array) {
  101|  8.32M|    return array->cardinality == 0;
  102|  8.32M|}
roaring.c:array_container_append:
  275|  73.2k|                                          uint16_t pos) {
  276|  73.2k|    const int32_t capacity = arr->capacity;
  277|       |
  278|  73.2k|    if (array_container_full(arr)) {
  ------------------
  |  Branch (278:9): [True: 36.4k, False: 36.8k]
  ------------------
  279|  36.4k|        array_container_grow(arr, capacity + 1, true);
  280|  36.4k|    }
  281|       |
  282|  73.2k|    arr->array[arr->cardinality++] = pos;
  283|  73.2k|}
roaring.c:array_container_full:
  106|  1.70M|static inline bool array_container_full(const array_container_t *array) {
  107|  1.70M|    return array->cardinality == array->capacity;
  108|  1.70M|}
roaring.c:array_container_remove:
  330|  7.93k|                                          uint16_t pos) {
  331|  7.93k|    const int32_t idx = binarySearch(arr->array, arr->cardinality, pos);
  332|  7.93k|    const bool is_present = idx >= 0;
  333|  7.93k|    if (is_present) {
  ------------------
  |  Branch (333:9): [True: 3.97k, False: 3.96k]
  ------------------
  334|  3.97k|        memmove(arr->array + idx, arr->array + idx + 1,
  335|  3.97k|                (arr->cardinality - idx - 1) * sizeof(uint16_t));
  336|  3.97k|        arr->cardinality--;
  337|  3.97k|    }
  338|       |
  339|  7.93k|    return is_present;
  340|  7.93k|}
roaring.c:array_container_nonzero_cardinality:
   87|   105k|    const array_container_t *array) {
   88|   105k|    return array->cardinality > 0;
   89|   105k|}
roaring.c:array_container_equals:
  230|  11.1k|                                          const array_container_t *container2) {
  231|  11.1k|    if (container1->cardinality != container2->cardinality) {
  ------------------
  |  Branch (231:9): [True: 3.27k, False: 7.83k]
  ------------------
  232|  3.27k|        return false;
  233|  3.27k|    }
  234|  7.83k|    return memequals(container1->array, container2->array,
  235|  7.83k|                     container1->cardinality * 2);
  236|  11.1k|}
roaring.c:array_container_select:
  253|  4.76k|                                          uint32_t *element) {
  254|  4.76k|    int card = array_container_cardinality(container);
  255|  4.76k|    if (*start_rank + card <= rank) {
  ------------------
  |  Branch (255:9): [True: 349, False: 4.42k]
  ------------------
  256|    349|        *start_rank += card;
  257|    349|        return false;
  258|  4.42k|    } else {
  259|  4.42k|        *element = container->array[rank - *start_rank];
  260|       |        return true;
  261|  4.42k|    }
  262|  4.76k|}
roaring.c:array_container_contains_range:
  429|     69|                                                  uint32_t range_end) {
  430|     69|    const int32_t range_count = range_end - range_start;
  431|     69|    const uint16_t rs_included = (uint16_t)range_start;
  432|     69|    const uint16_t re_included = (uint16_t)(range_end - 1);
  433|       |
  434|       |    // Empty range is always included
  435|     69|    if (range_count <= 0) {
  ------------------
  |  Branch (435:9): [True: 0, False: 69]
  ------------------
  436|      0|        return true;
  437|      0|    }
  438|     69|    if (range_count > arr->cardinality) {
  ------------------
  |  Branch (438:9): [True: 27, False: 42]
  ------------------
  439|     27|        return false;
  440|     27|    }
  441|       |
  442|     42|    const int32_t start =
  443|     42|        binarySearch(arr->array, arr->cardinality, rs_included);
  444|       |    // If this sorted array contains all items in the range:
  445|       |    // * the start item must be found
  446|       |    // * the last item in range range_count must exist, and be the expected end
  447|       |    // value
  448|     42|    return (start >= 0) && (arr->cardinality >= start + range_count) &&
  ------------------
  |  Branch (448:12): [True: 33, False: 9]
  |  Branch (448:28): [True: 31, False: 2]
  ------------------
  449|     31|           (arr->array[start + range_count - 1] == re_included);
  ------------------
  |  Branch (449:12): [True: 6, False: 25]
  ------------------
  450|     69|}
roaring_array.c:array_container_size_in_bytes:
  221|  20.0k|    const array_container_t *container) {
  222|  20.0k|    return container->cardinality * sizeof(uint16_t);
  223|  20.0k|}
roaring_array.c:array_container_cardinality:
   82|  7.66k|static inline int array_container_cardinality(const array_container_t *array) {
   83|  7.66k|    return array->cardinality;
   84|  7.66k|}
array.c:array_container_size_in_bytes:
  221|  15.3k|    const array_container_t *container) {
  222|  15.3k|    return container->cardinality * sizeof(uint16_t);
  223|  15.3k|}
convert.c:array_container_cardinality:
   82|  16.6k|static inline int array_container_cardinality(const array_container_t *array) {
   83|  16.6k|    return array->cardinality;
   84|  16.6k|}
convert.c:array_container_serialized_size_in_bytes:
  173|   139k|static inline int32_t array_container_serialized_size_in_bytes(int32_t card) {
  174|   139k|    return card * sizeof(uint16_t);
  175|   139k|}
mixed_intersection.c:array_container_empty:
  100|     16|static inline bool array_container_empty(const array_container_t *array) {
  101|     16|    return array->cardinality == 0;
  102|     16|}
mixed_andnot.c:array_container_cardinality:
   82|    340|static inline int array_container_cardinality(const array_container_t *array) {
   83|    340|    return array->cardinality;
   84|    340|}

bitset_container_get:
  199|   503k|                                 uint16_t pos) {
  200|   503k|    const uint64_t word = bitset->words[pos >> 6];
  201|   503k|    return (word >> (pos & 63)) & 1;
  202|   503k|}
bitset_container_contains:
  239|   379k|                                      uint16_t pos) {
  240|   379k|    return bitset_container_get(bitset, pos);
  241|   379k|}
roaring.c:bitset_container_cardinality:
  255|  10.5k|    const bitset_container_t *bitset) {
  256|  10.5k|    return bitset->cardinality;
  257|  10.5k|}
roaring.c:bitset_container_set:
  152|   313k|                                        uint16_t pos) {
  153|   313k|    const uint64_t old_word = bitset->words[pos >> 6];
  154|   313k|    const int index = pos & 63;
  155|       |    const uint64_t new_word = old_word | (UINT64_C(1) << index);
  156|   313k|    bitset->cardinality += (uint32_t)((old_word ^ new_word) >> index);
  157|   313k|    bitset->words[pos >> 6] = new_word;
  158|   313k|}
roaring.c:bitset_container_add:
  173|    162|                                        uint16_t pos) {
  174|    162|    const uint64_t old_word = bitset->words[pos >> 6];
  175|    162|    const int index = pos & 63;
  176|       |    const uint64_t new_word = old_word | (UINT64_C(1) << index);
  177|    162|    const uint64_t increment = (old_word ^ new_word) >> index;
  178|    162|    bitset->cardinality += (uint32_t)increment;
  179|    162|    bitset->words[pos >> 6] = new_word;
  180|    162|    return increment > 0;
  181|    162|}
roaring.c:bitset_container_remove:
  186|  2.21k|                                           uint16_t pos) {
  187|  2.21k|    const uint64_t old_word = bitset->words[pos >> 6];
  188|  2.21k|    const int index = pos & 63;
  189|       |    const uint64_t new_word = old_word & (~(UINT64_C(1) << index));
  190|  2.21k|    const uint64_t increment = (old_word ^ new_word) >> index;
  191|  2.21k|    bitset->cardinality -= (uint32_t)increment;
  192|  2.21k|    bitset->words[pos >> 6] = new_word;
  193|  2.21k|    return increment > 0;
  194|  2.21k|}
roaring.c:bitset_container_const_nonzero_cardinality:
  288|  6.18k|    const bitset_container_t *bitset) {
  289|  6.18k|    return !bitset_container_empty(bitset);
  290|  6.18k|}
roaring.c:bitset_container_empty:
  275|  6.18k|static inline bool bitset_container_empty(const bitset_container_t *bitset) {
  276|  6.18k|    if (bitset->cardinality == BITSET_UNKNOWN_CARDINALITY) {
  ------------------
  |  Branch (276:9): [True: 0, False: 6.18k]
  ------------------
  277|      0|        for (int i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; i++) {
  ------------------
  |  Branch (277:25): [True: 0, False: 0]
  ------------------
  278|      0|            if ((bitset->words[i]) != 0) return false;
  ------------------
  |  Branch (278:17): [True: 0, False: 0]
  ------------------
  279|      0|        }
  280|      0|        return true;
  281|      0|    }
  282|  6.18k|    return bitset->cardinality == 0;
  283|  6.18k|}
roaring.c:bitset_container_get_range:
  213|    237|                                              uint32_t pos_end) {
  214|    237|    const uint32_t start = pos_start >> 6;
  215|    237|    const uint32_t end = pos_end >> 6;
  216|       |
  217|    237|    const uint64_t first = ~((1ULL << (pos_start & 0x3F)) - 1);
  218|    237|    const uint64_t last = (1ULL << (pos_end & 0x3F)) - 1;
  219|       |
  220|    237|    if (start == end)
  ------------------
  |  Branch (220:9): [True: 41, False: 196]
  ------------------
  221|     41|        return ((bitset->words[end] & first & last) == (first & last));
  222|    196|    if ((bitset->words[start] & first) != first) return false;
  ------------------
  |  Branch (222:9): [True: 75, False: 121]
  ------------------
  223|       |
  224|    121|    if ((end < BITSET_CONTAINER_SIZE_IN_WORDS) &&
  ------------------
  |  Branch (224:9): [True: 111, False: 10]
  ------------------
  225|    111|        ((bitset->words[end] & last) != last)) {
  ------------------
  |  Branch (225:9): [True: 94, False: 17]
  ------------------
  226|     94|        return false;
  227|     94|    }
  228|       |
  229|     27|    for (uint32_t i = start + 1;
  230|  11.0k|         (i < BITSET_CONTAINER_SIZE_IN_WORDS) && (i < end); ++i) {
  ------------------
  |  Branch (230:10): [True: 11.0k, False: 9]
  |  Branch (230:50): [True: 10.9k, False: 15]
  ------------------
  231|  10.9k|        if (bitset->words[i] != UINT64_C(0xFFFFFFFFFFFFFFFF)) return false;
  ------------------
  |  Branch (231:13): [True: 3, False: 10.9k]
  ------------------
  232|  10.9k|    }
  233|       |
  234|     24|    return true;
  235|     27|}
roaring_array.c:bitset_container_size_in_bytes:
  475|   132k|    const bitset_container_t *container) {
  476|   132k|    (void)container;
  477|   132k|    return BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t);
  478|   132k|}
roaring_array.c:bitset_container_cardinality:
  255|  66.2k|    const bitset_container_t *bitset) {
  256|  66.2k|    return bitset->cardinality;
  257|  66.2k|}
bitset.c:bitset_container_size_in_bytes:
  475|   132k|    const bitset_container_t *container) {
  476|   132k|    (void)container;
  477|   132k|    return BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t);
  478|   132k|}
convert.c:bitset_container_set:
  152|  2.71M|                                        uint16_t pos) {
  153|  2.71M|    const uint64_t old_word = bitset->words[pos >> 6];
  154|  2.71M|    const int index = pos & 63;
  155|       |    const uint64_t new_word = old_word | (UINT64_C(1) << index);
  156|  2.71M|    bitset->cardinality += (uint32_t)((old_word ^ new_word) >> index);
  157|  2.71M|    bitset->words[pos >> 6] = new_word;
  158|  2.71M|}
convert.c:bitset_container_serialized_size_in_bytes:
  434|   125k|static inline int32_t bitset_container_serialized_size_in_bytes(void) {
  435|   125k|    return BITSET_CONTAINER_SIZE_IN_WORDS * 8;
  436|   125k|}

container_iterator_next:
 2451|   337k|                                    uint16_t *value) {
 2452|   337k|    switch (typecode) {
 2453|      0|        case BITSET_CONTAINER_TYPE: {
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (2453:9): [True: 0, False: 337k]
  ------------------
 2454|      0|            const bitset_container_t *bc = const_CAST_bitset(c);
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2455|      0|            it->index++;
 2456|       |
 2457|      0|            uint32_t wordindex = it->index / 64;
 2458|      0|            if (wordindex >= BITSET_CONTAINER_SIZE_IN_WORDS) {
  ------------------
  |  Branch (2458:17): [True: 0, False: 0]
  ------------------
 2459|      0|                return false;
 2460|      0|            }
 2461|       |
 2462|      0|            uint64_t word =
 2463|      0|                bc->words[wordindex] & (UINT64_MAX << (it->index % 64));
 2464|       |            // next part could be optimized/simplified
 2465|      0|            while (word == 0 &&
  ------------------
  |  Branch (2465:20): [True: 0, False: 0]
  ------------------
 2466|      0|                   (wordindex + 1 < BITSET_CONTAINER_SIZE_IN_WORDS)) {
  ------------------
  |  Branch (2466:20): [True: 0, False: 0]
  ------------------
 2467|      0|                wordindex++;
 2468|      0|                word = bc->words[wordindex];
 2469|      0|            }
 2470|      0|            if (word != 0) {
  ------------------
  |  Branch (2470:17): [True: 0, False: 0]
  ------------------
 2471|      0|                it->index = wordindex * 64 + roaring_trailing_zeroes(word);
 2472|      0|                *value = it->index;
 2473|      0|                return true;
 2474|      0|            }
 2475|      0|            return false;
 2476|      0|        }
 2477|   300k|        case ARRAY_CONTAINER_TYPE: {
  ------------------
  |  |   49|   300k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (2477:9): [True: 300k, False: 36.3k]
  ------------------
 2478|   300k|            const array_container_t *ac = const_CAST_array(c);
  ------------------
  |  |   55|   300k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|   300k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2479|   300k|            it->index++;
 2480|   300k|            if (it->index < ac->cardinality) {
  ------------------
  |  Branch (2480:17): [True: 294k, False: 6.51k]
  ------------------
 2481|   294k|                *value = ac->array[it->index];
 2482|   294k|                return true;
 2483|   294k|            }
 2484|  6.51k|            return false;
 2485|   300k|        }
 2486|  36.3k|        case RUN_CONTAINER_TYPE: {
  ------------------
  |  |   50|  36.3k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (2486:9): [True: 36.3k, False: 300k]
  ------------------
 2487|  36.3k|            if (*value == UINT16_MAX) {  // Avoid overflow to zero
  ------------------
  |  Branch (2487:17): [True: 0, False: 36.3k]
  ------------------
 2488|      0|                return false;
 2489|      0|            }
 2490|       |
 2491|  36.3k|            const run_container_t *rc = const_CAST_run(c);
  ------------------
  |  |   78|  36.3k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  36.3k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2492|  36.3k|            uint32_t limit =
 2493|  36.3k|                rc->runs[it->index].value + rc->runs[it->index].length;
 2494|  36.3k|            if (*value < limit) {
  ------------------
  |  Branch (2494:17): [True: 23.7k, False: 12.6k]
  ------------------
 2495|  23.7k|                (*value)++;
 2496|  23.7k|                return true;
 2497|  23.7k|            }
 2498|       |
 2499|  12.6k|            it->index++;
 2500|  12.6k|            if (it->index < rc->n_runs) {
  ------------------
  |  Branch (2500:17): [True: 12.2k, False: 435]
  ------------------
 2501|  12.2k|                *value = rc->runs[it->index].value;
 2502|  12.2k|                return true;
 2503|  12.2k|            }
 2504|    435|            return false;
 2505|  12.6k|        }
 2506|      0|        default:
  ------------------
  |  Branch (2506:9): [True: 0, False: 337k]
  ------------------
 2507|      0|            assert(false);
 2508|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2509|      0|            return false;
 2510|   337k|    }
 2511|   337k|}
roaring.c:container_from_range:
  317|  65.5k|                                                uint32_t max, uint16_t step) {
  318|  65.5k|    if (step == 0) return NULL;  // being paranoid
  ------------------
  |  Branch (318:9): [True: 0, False: 65.5k]
  ------------------
  319|  65.5k|    if (step == 1) {
  ------------------
  |  Branch (319:9): [True: 65.5k, False: 0]
  ------------------
  320|  65.5k|        return container_range_of_ones(min, max, type);
  321|       |        // Note: the result is not always a run (need to check the cardinality)
  322|       |        //*type = RUN_CONTAINER_TYPE;
  323|       |        // return run_container_create_range(min, max);
  324|  65.5k|    }
  325|      0|    int size = (max - min + step - 1) / step;
  326|      0|    if (size <= DEFAULT_MAX_SIZE) {  // array container
  ------------------
  |  Branch (326:9): [True: 0, False: 0]
  ------------------
  327|      0|        *type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  328|      0|        array_container_t *array = array_container_create_given_capacity(size);
  329|      0|        array_container_add_from_range(array, min, max, step);
  330|      0|        assert(array->cardinality == size);
  331|      0|        return array;
  332|      0|    } else {  // bitset container
  333|      0|        *type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  334|      0|        bitset_container_t *bitset = bitset_container_create();
  335|      0|        bitset_container_add_from_range(bitset, min, max, step);
  336|       |        assert(bitset->cardinality == size);
  337|      0|        return bitset;
  338|      0|    }
  339|      0|}
roaring.c:container_range_of_ones:
  302|  83.5k|                                                   uint8_t *result_type) {
  303|  83.5k|    assert(range_end >= range_start);
  304|  83.5k|    uint64_t cardinality = range_end - range_start + 1;
  305|  83.5k|    if (cardinality <= 2) {
  ------------------
  |  Branch (305:9): [True: 124, False: 83.4k]
  ------------------
  306|    124|        *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|    124|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  307|    124|        return array_container_create_range(range_start, range_end);
  308|  83.4k|    } else {
  309|  83.4k|        *result_type = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|  83.4k|#define RUN_CONTAINER_TYPE 3
  ------------------
  310|  83.4k|        return run_container_create_range(range_start, range_end);
  311|  83.4k|    }
  312|  83.5k|}
roaring.c:container_add_range:
 2276|  3.08k|                                               uint8_t *result_type) {
 2277|       |    // NB: when selecting new container type, we perform only inexpensive checks
 2278|  3.08k|    switch (type) {
 2279|      0|        case BITSET_CONTAINER_TYPE: {
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (2279:9): [True: 0, False: 3.08k]
  ------------------
 2280|      0|            bitset_container_t *bitset = CAST_bitset(c);
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2281|       |
 2282|      0|            int32_t union_cardinality = 0;
 2283|      0|            union_cardinality += bitset->cardinality;
 2284|      0|            union_cardinality += max - min + 1;
 2285|      0|            union_cardinality -=
 2286|      0|                bitset_lenrange_cardinality(bitset->words, min, max - min);
 2287|       |
 2288|      0|            if (union_cardinality == INT32_C(0x10000)) {
  ------------------
  |  Branch (2288:17): [True: 0, False: 0]
  ------------------
 2289|      0|                *result_type = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
 2290|      0|                return run_container_create_range(0, INT32_C(0x10000));
 2291|      0|            } else {
 2292|      0|                *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 2293|      0|                bitset_set_lenrange(bitset->words, min, max - min);
 2294|      0|                bitset->cardinality = union_cardinality;
 2295|      0|                return bitset;
 2296|      0|            }
 2297|      0|        }
 2298|  2.67k|        case ARRAY_CONTAINER_TYPE: {
  ------------------
  |  |   49|  2.67k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (2298:9): [True: 2.67k, False: 413]
  ------------------
 2299|  2.67k|            array_container_t *array = CAST_array(c);
  ------------------
  |  |   54|  2.67k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  2.67k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2300|       |
 2301|  2.67k|            int32_t nvals_greater =
 2302|  2.67k|                count_greater(array->array, array->cardinality, (uint16_t)max);
 2303|  2.67k|            int32_t nvals_less =
 2304|  2.67k|                count_less(array->array, array->cardinality - nvals_greater,
 2305|  2.67k|                           (uint16_t)min);
 2306|  2.67k|            int32_t union_cardinality =
 2307|  2.67k|                nvals_less + (max - min + 1) + nvals_greater;
 2308|       |
 2309|  2.67k|            if (union_cardinality == INT32_C(0x10000)) {
  ------------------
  |  Branch (2309:17): [True: 567, False: 2.10k]
  ------------------
 2310|    567|                *result_type = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|    567|#define RUN_CONTAINER_TYPE 3
  ------------------
 2311|    567|                return run_container_create_range(0, INT32_C(0x10000));
 2312|  2.10k|            } else if (union_cardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (2312:24): [True: 642, False: 1.46k]
  ------------------
 2313|    642|                *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|    642|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 2314|    642|                array_container_add_range_nvals(array, min, max, nvals_less,
 2315|    642|                                                nvals_greater);
 2316|    642|                return array;
 2317|  1.46k|            } else {
 2318|  1.46k|                *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|  1.46k|#define BITSET_CONTAINER_TYPE 1
  ------------------
 2319|  1.46k|                bitset_container_t *bitset = bitset_container_from_array(array);
 2320|  1.46k|                bitset_set_lenrange(bitset->words, min, max - min);
 2321|  1.46k|                bitset->cardinality = union_cardinality;
 2322|  1.46k|                return bitset;
 2323|  1.46k|            }
 2324|  2.67k|        }
 2325|    413|        case RUN_CONTAINER_TYPE: {
  ------------------
  |  |   50|    413|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (2325:9): [True: 413, False: 2.67k]
  ------------------
 2326|    413|            run_container_t *run = CAST_run(c);
  ------------------
  |  |   77|    413|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    413|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2327|       |
 2328|    413|            int32_t nruns_greater =
 2329|    413|                rle16_count_greater(run->runs, run->n_runs, (uint16_t)max);
 2330|    413|            int32_t nruns_less = rle16_count_less(
 2331|    413|                run->runs, run->n_runs - nruns_greater, (uint16_t)min);
 2332|       |
 2333|    413|            int32_t run_size_bytes =
 2334|    413|                (nruns_less + 1 + nruns_greater) * sizeof(rle16_t);
 2335|    413|            int32_t bitset_size_bytes =
 2336|    413|                BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t);
 2337|       |
 2338|    413|            if (run_size_bytes <= bitset_size_bytes) {
  ------------------
  |  Branch (2338:17): [True: 413, False: 0]
  ------------------
 2339|    413|                run_container_add_range_nruns(run, min, max, nruns_less,
 2340|    413|                                              nruns_greater);
 2341|    413|                *result_type = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|    413|#define RUN_CONTAINER_TYPE 3
  ------------------
 2342|    413|                return run;
 2343|    413|            } else {
 2344|      0|                return container_from_run_range(run, min, max, result_type);
 2345|      0|            }
 2346|    413|        }
 2347|      0|        default:
  ------------------
  |  Branch (2347:9): [True: 0, False: 3.08k]
  ------------------
 2348|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2349|  3.08k|    }
 2350|  3.08k|}
roaring.c:container_remove_range:
 2365|  20.7k|                                                  uint8_t *result_type) {
 2366|  20.7k|    switch (type) {
 2367|  1.29k|        case BITSET_CONTAINER_TYPE: {
  ------------------
  |  |   48|  1.29k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (2367:9): [True: 1.29k, False: 19.4k]
  ------------------
 2368|  1.29k|            bitset_container_t *bitset = CAST_bitset(c);
  ------------------
  |  |   52|  1.29k|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.29k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2369|       |
 2370|  1.29k|            int32_t result_cardinality =
 2371|  1.29k|                bitset->cardinality -
 2372|  1.29k|                bitset_lenrange_cardinality(bitset->words, min, max - min);
 2373|       |
 2374|  1.29k|            if (result_cardinality == 0) {
  ------------------
  |  Branch (2374:17): [True: 34, False: 1.25k]
  ------------------
 2375|     34|                return NULL;
 2376|  1.25k|            } else if (result_cardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (2376:24): [True: 165, False: 1.09k]
  ------------------
 2377|    165|                *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|    165|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 2378|    165|                bitset_reset_range(bitset->words, min, max + 1);
 2379|    165|                bitset->cardinality = result_cardinality;
 2380|    165|                return array_container_from_bitset(bitset);
 2381|  1.09k|            } else {
 2382|  1.09k|                *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|  1.09k|#define BITSET_CONTAINER_TYPE 1
  ------------------
 2383|  1.09k|                bitset_reset_range(bitset->words, min, max + 1);
 2384|  1.09k|                bitset->cardinality = result_cardinality;
 2385|  1.09k|                return bitset;
 2386|  1.09k|            }
 2387|  1.29k|        }
 2388|  4.51k|        case ARRAY_CONTAINER_TYPE: {
  ------------------
  |  |   49|  4.51k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (2388:9): [True: 4.51k, False: 16.2k]
  ------------------
 2389|  4.51k|            array_container_t *array = CAST_array(c);
  ------------------
  |  |   54|  4.51k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  4.51k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2390|       |
 2391|  4.51k|            int32_t nvals_greater =
 2392|  4.51k|                count_greater(array->array, array->cardinality, (uint16_t)max);
 2393|  4.51k|            int32_t nvals_less =
 2394|  4.51k|                count_less(array->array, array->cardinality - nvals_greater,
 2395|  4.51k|                           (uint16_t)min);
 2396|  4.51k|            int32_t result_cardinality = nvals_less + nvals_greater;
 2397|       |
 2398|  4.51k|            if (result_cardinality == 0) {
  ------------------
  |  Branch (2398:17): [True: 359, False: 4.15k]
  ------------------
 2399|    359|                return NULL;
 2400|  4.15k|            } else {
 2401|  4.15k|                *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  4.15k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 2402|  4.15k|                array_container_remove_range(
 2403|  4.15k|                    array, nvals_less, array->cardinality - result_cardinality);
 2404|  4.15k|                return array;
 2405|  4.15k|            }
 2406|  4.51k|        }
 2407|  14.9k|        case RUN_CONTAINER_TYPE: {
  ------------------
  |  |   50|  14.9k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (2407:9): [True: 14.9k, False: 5.80k]
  ------------------
 2408|  14.9k|            run_container_t *run = CAST_run(c);
  ------------------
  |  |   77|  14.9k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  14.9k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2409|       |
 2410|  14.9k|            if (run->n_runs == 0) {
  ------------------
  |  Branch (2410:17): [True: 0, False: 14.9k]
  ------------------
 2411|      0|                return NULL;
 2412|      0|            }
 2413|  14.9k|            if (min <= run_container_minimum(run) &&
  ------------------
  |  Branch (2413:17): [True: 14.5k, False: 386]
  ------------------
 2414|  14.5k|                max >= run_container_maximum(run)) {
  ------------------
  |  Branch (2414:17): [True: 13.1k, False: 1.39k]
  ------------------
 2415|  13.1k|                return NULL;
 2416|  13.1k|            }
 2417|       |
 2418|  1.78k|            run_container_remove_range(run, min, max);
 2419|  1.78k|            return convert_run_to_efficient_container(run, result_type);
 2420|  14.9k|        }
 2421|      0|        default:
  ------------------
  |  Branch (2421:9): [True: 0, False: 20.7k]
  ------------------
 2422|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2423|  20.7k|    }
 2424|  20.7k|}
roaring.c:container_get_cardinality:
  244|   370k|                                            uint8_t typecode) {
  245|   370k|    c = container_unwrap_shared(c, &typecode);
  246|   370k|    switch (typecode) {
  ------------------
  |  Branch (246:13): [True: 370k, False: 0]
  ------------------
  247|  9.18k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|  9.18k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (247:9): [True: 9.18k, False: 361k]
  ------------------
  248|  9.18k|            return bitset_container_cardinality(const_CAST_bitset(c));
  ------------------
  |  |   53|  9.18k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  9.18k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  249|  75.9k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  75.9k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (249:9): [True: 75.9k, False: 295k]
  ------------------
  250|  75.9k|            return array_container_cardinality(const_CAST_array(c));
  ------------------
  |  |   55|  75.9k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  75.9k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  251|   285k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|   285k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (251:9): [True: 285k, False: 85.1k]
  ------------------
  252|   285k|            return run_container_cardinality(const_CAST_run(c));
  ------------------
  |  |   78|   285k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|   285k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  253|   370k|    }
  254|   370k|    assert(false);
  255|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  256|      0|    return 0;  // unreached
  257|   370k|}
roaring.c:get_container_type:
  129|  73.9k|static inline uint8_t get_container_type(const container_t *c, uint8_t type) {
  130|  73.9k|    if (type == SHARED_CONTAINER_TYPE) {
  ------------------
  |  |   51|  73.9k|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (130:9): [True: 0, False: 73.9k]
  ------------------
  131|      0|        return const_CAST_shared(c)->typecode;
  ------------------
  |  |   80|      0|#define const_CAST_shared(c) CAST(const shared_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  132|  73.9k|    } else {
  133|  73.9k|        return type;
  134|  73.9k|    }
  135|  73.9k|}
roaring.c:get_writable_copy_if_shared:
  146|  9.25M|                                                       uint8_t *type) {
  147|  9.25M|    if (*type == SHARED_CONTAINER_TYPE) {  // shared, return enclosed container
  ------------------
  |  |   51|  9.25M|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (147:9): [True: 0, False: 9.25M]
  ------------------
  148|      0|        return shared_container_extract_copy(CAST_shared(c), type);
  ------------------
  |  |   79|      0|#define CAST_shared(c) CAST(shared_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  149|  9.25M|    } else {
  150|  9.25M|        return c;  // not shared, so return as-is
  151|  9.25M|    }
  152|  9.25M|}
roaring.c:container_add:
  492|  9.01M|    uint8_t *new_typecode) {
  493|  9.01M|    c = get_writable_copy_if_shared(c, &typecode);
  494|  9.01M|    switch (typecode) {
  495|   313k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|   313k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (495:9): [True: 313k, False: 8.70M]
  ------------------
  496|   313k|            bitset_container_set(CAST_bitset(c), val);
  ------------------
  |  |   52|   313k|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|   313k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  497|   313k|            *new_typecode = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|   313k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  498|   313k|            return c;
  499|  8.32M|        case ARRAY_CONTAINER_TYPE: {
  ------------------
  |  |   49|  8.32M|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (499:9): [True: 8.32M, False: 697k]
  ------------------
  500|  8.32M|            array_container_t *ac = CAST_array(c);
  ------------------
  |  |   54|  8.32M|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  8.32M|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  501|  8.32M|            if (array_container_try_add(ac, val, DEFAULT_MAX_SIZE) != -1) {
  ------------------
  |  Branch (501:17): [True: 8.32M, False: 162]
  ------------------
  502|  8.32M|                *new_typecode = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  8.32M|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  503|  8.32M|                return ac;
  504|  8.32M|            } else {
  505|    162|                bitset_container_t *bitset = bitset_container_from_array(ac);
  506|    162|                bitset_container_add(bitset, val);
  507|    162|                *new_typecode = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|    162|#define BITSET_CONTAINER_TYPE 1
  ------------------
  508|    162|                return bitset;
  509|    162|            }
  510|  8.32M|        } break;
  511|   384k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|   384k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (511:9): [True: 384k, False: 8.63M]
  ------------------
  512|       |            // per Java, no container type adjustments are done (revisit?)
  513|   384k|            run_container_add(CAST_run(c), val);
  ------------------
  |  |   77|   384k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|   384k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  514|   384k|            *new_typecode = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|   384k|#define RUN_CONTAINER_TYPE 3
  ------------------
  515|   384k|            return c;
  516|      0|        default:
  ------------------
  |  Branch (516:9): [True: 0, False: 9.01M]
  ------------------
  517|      0|            assert(false);
  518|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  519|      0|            return NULL;
  520|  9.01M|    }
  521|  9.01M|}
roaring.c:container_remove:
  533|  13.1k|    uint8_t *new_typecode) {
  534|  13.1k|    c = get_writable_copy_if_shared(c, &typecode);
  535|  13.1k|    switch (typecode) {
  536|  2.21k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|  2.21k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (536:9): [True: 2.21k, False: 10.9k]
  ------------------
  537|  2.21k|            if (bitset_container_remove(CAST_bitset(c), val)) {
  ------------------
  |  |   52|  2.21k|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  2.21k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (537:17): [True: 1.38k, False: 829]
  ------------------
  538|  1.38k|                int card = bitset_container_cardinality(CAST_bitset(c));
  ------------------
  |  |   52|  1.38k|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.38k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  539|  1.38k|                if (card <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (539:21): [True: 19, False: 1.36k]
  ------------------
  540|     19|                    *new_typecode = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|     19|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  541|     19|                    return array_container_from_bitset(CAST_bitset(c));
  ------------------
  |  |   52|     19|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|     19|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  542|     19|                }
  543|  1.38k|            }
  544|  2.19k|            *new_typecode = typecode;
  545|  2.19k|            return c;
  546|  7.93k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  7.93k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (546:9): [True: 7.93k, False: 5.24k]
  ------------------
  547|  7.93k|            *new_typecode = typecode;
  548|  7.93k|            array_container_remove(CAST_array(c), val);
  ------------------
  |  |   54|  7.93k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  7.93k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  549|  7.93k|            return c;
  550|  3.02k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  3.02k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (550:9): [True: 3.02k, False: 10.1k]
  ------------------
  551|       |            // per Java, no container type adjustments are done (revisit?)
  552|  3.02k|            run_container_remove(CAST_run(c), val);
  ------------------
  |  |   77|  3.02k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  3.02k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  553|  3.02k|            *new_typecode = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|  3.02k|#define RUN_CONTAINER_TYPE 3
  ------------------
  554|  3.02k|            return c;
  555|      0|        default:
  ------------------
  |  Branch (555:9): [True: 0, False: 13.1k]
  ------------------
  556|      0|            assert(false);
  557|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  558|      0|            return NULL;
  559|  13.1k|    }
  560|  13.1k|}
roaring.c:container_nonzero_cardinality:
  437|   171k|                                                 uint8_t typecode) {
  438|   171k|    c = container_unwrap_shared(c, &typecode);
  439|   171k|    switch (typecode) {
  ------------------
  |  Branch (439:13): [True: 171k, False: 0]
  ------------------
  440|  6.18k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|  6.18k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (440:9): [True: 6.18k, False: 164k]
  ------------------
  441|  6.18k|            return bitset_container_const_nonzero_cardinality(
  442|  6.18k|                const_CAST_bitset(c));
  ------------------
  |  |   53|  6.18k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  6.18k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  443|   105k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|   105k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (443:9): [True: 105k, False: 65.7k]
  ------------------
  444|   105k|            return array_container_nonzero_cardinality(const_CAST_array(c));
  ------------------
  |  |   55|   105k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|   105k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  445|  59.6k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  59.6k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (445:9): [True: 59.6k, False: 111k]
  ------------------
  446|  59.6k|            return run_container_nonzero_cardinality(const_CAST_run(c));
  ------------------
  |  |   78|  59.6k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  59.6k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  447|   171k|    }
  448|   171k|    assert(false);
  449|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  450|      0|    return 0;  // unreached
  451|   171k|}
roaring.c:container_and:
  728|  7.08k|                                         uint8_t *result_type) {
  729|  7.08k|    c1 = container_unwrap_shared(c1, &type1);
  730|  7.08k|    c2 = container_unwrap_shared(c2, &type2);
  731|  7.08k|    container_t *result = NULL;
  732|  7.08k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  7.08k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
  733|      0|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (733:9): [True: 0, False: 7.08k]
  ------------------
  734|      0|            *result_type =
  735|      0|                bitset_bitset_container_intersection(
  ------------------
  |  Branch (735:17): [True: 0, False: 0]
  ------------------
  736|      0|                    const_CAST_bitset(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                  const_CAST_bitset(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  737|      0|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  738|      0|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  739|      0|            return result;
  740|       |
  741|  3.45k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  3.45k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (741:9): [True: 3.45k, False: 3.63k]
  ------------------
  742|  3.45k|            result = array_container_create();
  743|  3.45k|            array_container_intersection(
  744|  3.45k|                const_CAST_array(c1), const_CAST_array(c2), CAST_array(result));
  ------------------
  |  |   55|  3.45k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_array(c2), CAST_array(result));
  ------------------
  |  |   55|  3.45k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_array(c2), CAST_array(result));
  ------------------
  |  |   54|  3.45k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  745|  3.45k|            *result_type = ARRAY_CONTAINER_TYPE;  // never bitset
  ------------------
  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  746|  3.45k|            return result;
  747|       |
  748|    710|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|    710|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    710|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    710|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (748:9): [True: 710, False: 6.37k]
  ------------------
  749|    710|            result = run_container_create();
  750|    710|            run_container_intersection(const_CAST_run(c1), const_CAST_run(c2),
  ------------------
  |  |   78|    710|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          run_container_intersection(const_CAST_run(c1), const_CAST_run(c2),
  ------------------
  |  |   78|    710|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  751|    710|                                       CAST_run(result));
  ------------------
  |  |   77|    710|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  752|    710|            return convert_run_to_efficient_container_and_free(CAST_run(result),
  ------------------
  |  |   77|    710|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  753|    710|                                                               result_type);
  754|       |
  755|      0|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (755:9): [True: 0, False: 7.08k]
  ------------------
  756|      0|            result = array_container_create();
  757|      0|            array_bitset_container_intersection(const_CAST_array(c2),
  ------------------
  |  |   55|      0|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  758|      0|                                                const_CAST_bitset(c1),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  759|      0|                                                CAST_array(result));
  ------------------
  |  |   54|      0|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  760|      0|            *result_type = ARRAY_CONTAINER_TYPE;  // never bitset
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  761|      0|            return result;
  762|       |
  763|    568|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|    568|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    568|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    568|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (763:9): [True: 568, False: 6.52k]
  ------------------
  764|    568|            result = array_container_create();
  765|    568|            *result_type = ARRAY_CONTAINER_TYPE;  // never bitset
  ------------------
  |  |   49|    568|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  766|    568|            array_bitset_container_intersection(const_CAST_array(c1),
  ------------------
  |  |   55|    568|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  767|    568|                                                const_CAST_bitset(c2),
  ------------------
  |  |   53|    568|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  768|    568|                                                CAST_array(result));
  ------------------
  |  |   54|    568|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  769|    568|            return result;
  770|       |
  771|      0|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (771:9): [True: 0, False: 7.08k]
  ------------------
  772|      0|            *result_type =
  773|      0|                run_bitset_container_intersection(
  ------------------
  |  Branch (773:17): [True: 0, False: 0]
  ------------------
  774|      0|                    const_CAST_run(c2), const_CAST_bitset(c1), &result)
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                  const_CAST_run(c2), const_CAST_bitset(c1), &result)
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  775|      0|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  776|      0|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  777|      0|            return result;
  778|       |
  779|    593|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|    593|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    593|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    593|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (779:9): [True: 593, False: 6.49k]
  ------------------
  780|    593|            *result_type =
  781|    593|                run_bitset_container_intersection(
  ------------------
  |  Branch (781:17): [True: 0, False: 593]
  ------------------
  782|    593|                    const_CAST_run(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   78|    593|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                  const_CAST_run(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|    593|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  783|    593|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  784|    593|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  1.18k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  785|    593|            return result;
  786|       |
  787|    664|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|    664|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    664|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    664|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (787:9): [True: 664, False: 6.42k]
  ------------------
  788|    664|            result = array_container_create();
  789|    664|            *result_type = ARRAY_CONTAINER_TYPE;  // never bitset
  ------------------
  |  |   49|    664|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  790|    664|            array_run_container_intersection(
  791|    664|                const_CAST_array(c1), const_CAST_run(c2), CAST_array(result));
  ------------------
  |  |   55|    664|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_run(c2), CAST_array(result));
  ------------------
  |  |   78|    664|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_run(c2), CAST_array(result));
  ------------------
  |  |   54|    664|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  792|    664|            return result;
  793|       |
  794|  1.09k|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|  1.09k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  1.09k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  1.09k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (794:9): [True: 1.09k, False: 5.99k]
  ------------------
  795|  1.09k|            result = array_container_create();
  796|  1.09k|            *result_type = ARRAY_CONTAINER_TYPE;  // never bitset
  ------------------
  |  |   49|  1.09k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  797|  1.09k|            array_run_container_intersection(
  798|  1.09k|                const_CAST_array(c2), const_CAST_run(c1), CAST_array(result));
  ------------------
  |  |   55|  1.09k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c2), const_CAST_run(c1), CAST_array(result));
  ------------------
  |  |   78|  1.09k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c2), const_CAST_run(c1), CAST_array(result));
  ------------------
  |  |   54|  1.09k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  799|  1.09k|            return result;
  800|       |
  801|      0|        default:
  ------------------
  |  Branch (801:9): [True: 0, False: 7.08k]
  ------------------
  802|      0|            assert(false);
  803|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  804|      0|            return NULL;
  805|  7.08k|    }
  806|  7.08k|}
roaring.c:container_iand:
  923|  62.1k|                                          uint8_t *result_type) {
  924|  62.1k|    c1 = get_writable_copy_if_shared(c1, &type1);
  925|  62.1k|    c2 = container_unwrap_shared(c2, &type2);
  926|  62.1k|    container_t *result = NULL;
  927|  62.1k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  62.1k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
  928|  1.40k|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|  1.40k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|  1.40k|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|  1.40k|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (928:9): [True: 1.40k, False: 60.7k]
  ------------------
  929|  1.40k|            *result_type = bitset_bitset_container_intersection_inplace(
  ------------------
  |  Branch (929:28): [True: 1.40k, False: 0]
  ------------------
  930|  1.40k|                               CAST_bitset(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   52|  1.40k|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.40k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_bitset(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|  1.40k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.40k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  931|  1.40k|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|  1.40k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  932|  1.40k|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  1.40k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  933|  1.40k|            return result;
  934|       |
  935|  5.67k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  5.67k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  5.67k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  5.67k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (935:9): [True: 5.67k, False: 56.4k]
  ------------------
  936|  5.67k|            array_container_intersection_inplace(CAST_array(c1),
  ------------------
  |  |   54|  5.67k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  5.67k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  937|  5.67k|                                                 const_CAST_array(c2));
  ------------------
  |  |   55|  5.67k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  5.67k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  938|  5.67k|            *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  5.67k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  939|  5.67k|            return c1;
  940|       |
  941|  53.9k|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|  53.9k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  53.9k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  53.9k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (941:9): [True: 53.9k, False: 8.17k]
  ------------------
  942|  53.9k|            result = run_container_create();
  943|  53.9k|            run_container_intersection(const_CAST_run(c1), const_CAST_run(c2),
  ------------------
  |  |   78|  53.9k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  53.9k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          run_container_intersection(const_CAST_run(c1), const_CAST_run(c2),
  ------------------
  |  |   78|  53.9k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  53.9k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  944|  53.9k|                                       CAST_run(result));
  ------------------
  |  |   77|  53.9k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  53.9k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  945|       |            // as of January 2016, Java code used non-in-place intersection for
  946|       |            // two runcontainers
  947|  53.9k|            return convert_run_to_efficient_container_and_free(CAST_run(result),
  ------------------
  |  |   77|  53.9k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  53.9k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  948|  53.9k|                                                               result_type);
  949|       |
  950|     41|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|     41|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|     41|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|     41|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (950:9): [True: 41, False: 62.0k]
  ------------------
  951|       |            // c1 is a bitmap so no inplace possible
  952|     41|            result = array_container_create();
  953|     41|            array_bitset_container_intersection(const_CAST_array(c2),
  ------------------
  |  |   55|     41|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|     41|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  954|     41|                                                const_CAST_bitset(c1),
  ------------------
  |  |   53|     41|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|     41|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  955|     41|                                                CAST_array(result));
  ------------------
  |  |   54|     41|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|     41|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  956|     41|            *result_type = ARRAY_CONTAINER_TYPE;  // never bitset
  ------------------
  |  |   49|     41|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  957|     41|            return result;
  958|       |
  959|      0|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (959:9): [True: 0, False: 62.1k]
  ------------------
  960|      0|            *result_type = ARRAY_CONTAINER_TYPE;  // never bitset
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  961|      0|            array_bitset_container_intersection(
  962|      0|                const_CAST_array(c1), const_CAST_bitset(c2),
  ------------------
  |  |   55|      0|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_bitset(c2),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  963|      0|                CAST_array(c1));  // result is allowed to be same as c1
  ------------------
  |  |   54|      0|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  964|      0|            return c1;
  965|       |
  966|      0|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (966:9): [True: 0, False: 62.1k]
  ------------------
  967|       |            // will attempt in-place computation
  968|      0|            *result_type = run_bitset_container_intersection(
  ------------------
  |  Branch (968:28): [True: 0, False: 0]
  ------------------
  969|      0|                               const_CAST_run(c2), const_CAST_bitset(c1), &c1)
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             const_CAST_run(c2), const_CAST_bitset(c1), &c1)
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  970|      0|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  971|      0|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  972|      0|            return c1;
  973|       |
  974|      0|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (974:9): [True: 0, False: 62.1k]
  ------------------
  975|      0|            *result_type =
  976|      0|                run_bitset_container_intersection(
  ------------------
  |  Branch (976:17): [True: 0, False: 0]
  ------------------
  977|      0|                    const_CAST_run(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                  const_CAST_run(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  978|      0|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  979|      0|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  980|      0|            return result;
  981|       |
  982|    171|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|    171|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    171|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    171|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (982:9): [True: 171, False: 61.9k]
  ------------------
  983|    171|            result = array_container_create();
  984|    171|            *result_type = ARRAY_CONTAINER_TYPE;  // never bitset
  ------------------
  |  |   49|    171|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  985|    171|            array_run_container_intersection(
  986|    171|                const_CAST_array(c1), const_CAST_run(c2), CAST_array(result));
  ------------------
  |  |   55|    171|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    171|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_run(c2), CAST_array(result));
  ------------------
  |  |   78|    171|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    171|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_run(c2), CAST_array(result));
  ------------------
  |  |   54|    171|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    171|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  987|    171|            return result;
  988|       |
  989|    882|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|    882|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    882|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    882|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (989:9): [True: 882, False: 61.2k]
  ------------------
  990|    882|            result = array_container_create();
  991|    882|            *result_type = ARRAY_CONTAINER_TYPE;  // never bitset
  ------------------
  |  |   49|    882|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  992|    882|            array_run_container_intersection(
  993|    882|                const_CAST_array(c2), const_CAST_run(c1), CAST_array(result));
  ------------------
  |  |   55|    882|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    882|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c2), const_CAST_run(c1), CAST_array(result));
  ------------------
  |  |   78|    882|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    882|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c2), const_CAST_run(c1), CAST_array(result));
  ------------------
  |  |   54|    882|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    882|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  994|    882|            return result;
  995|       |
  996|      0|        default:
  ------------------
  |  Branch (996:9): [True: 0, False: 62.1k]
  ------------------
  997|      0|            assert(false);
  998|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  999|      0|            return NULL;
 1000|  62.1k|    }
 1001|  62.1k|}
roaring.c:container_or:
 1010|  7.08k|                                        uint8_t *result_type) {
 1011|  7.08k|    c1 = container_unwrap_shared(c1, &type1);
 1012|  7.08k|    c2 = container_unwrap_shared(c2, &type2);
 1013|  7.08k|    container_t *result = NULL;
 1014|  7.08k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  7.08k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
 1015|      0|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1015:9): [True: 0, False: 7.08k]
  ------------------
 1016|      0|            result = bitset_container_create();
 1017|      0|            bitset_container_or(const_CAST_bitset(c1), const_CAST_bitset(c2),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          bitset_container_or(const_CAST_bitset(c1), const_CAST_bitset(c2),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1018|      0|                                CAST_bitset(result));
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1019|      0|            *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1020|      0|            return result;
 1021|       |
 1022|  3.45k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  3.45k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1022:9): [True: 3.45k, False: 3.63k]
  ------------------
 1023|  3.45k|            *result_type =
 1024|  3.45k|                array_array_container_union(const_CAST_array(c1),
  ------------------
  |  |   55|  3.45k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1024:17): [True: 41, False: 3.41k]
  ------------------
 1025|  3.45k|                                            const_CAST_array(c2), &result)
  ------------------
  |  |   55|  3.45k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1026|  3.45k|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|     41|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1027|  3.45k|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  6.86k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1028|  3.45k|            return result;
 1029|       |
 1030|    710|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|    710|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    710|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    710|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1030:9): [True: 710, False: 6.37k]
  ------------------
 1031|    710|            result = run_container_create();
 1032|    710|            run_container_union(const_CAST_run(c1), const_CAST_run(c2),
  ------------------
  |  |   78|    710|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          run_container_union(const_CAST_run(c1), const_CAST_run(c2),
  ------------------
  |  |   78|    710|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1033|    710|                                CAST_run(result));
  ------------------
  |  |   77|    710|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1034|    710|            *result_type = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|    710|#define RUN_CONTAINER_TYPE 3
  ------------------
 1035|       |            // todo: could be optimized since will never convert to array
 1036|    710|            result = convert_run_to_efficient_container_and_free(
 1037|    710|                CAST_run(result), result_type);
  ------------------
  |  |   77|    710|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1038|    710|            return result;
 1039|       |
 1040|      0|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1040:9): [True: 0, False: 7.08k]
  ------------------
 1041|      0|            result = bitset_container_create();
 1042|      0|            array_bitset_container_union(const_CAST_array(c2),
  ------------------
  |  |   55|      0|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1043|      0|                                         const_CAST_bitset(c1),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1044|      0|                                         CAST_bitset(result));
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1045|      0|            *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1046|      0|            return result;
 1047|       |
 1048|    568|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|    568|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    568|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    568|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1048:9): [True: 568, False: 6.52k]
  ------------------
 1049|    568|            result = bitset_container_create();
 1050|    568|            array_bitset_container_union(const_CAST_array(c1),
  ------------------
  |  |   55|    568|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1051|    568|                                         const_CAST_bitset(c2),
  ------------------
  |  |   53|    568|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1052|    568|                                         CAST_bitset(result));
  ------------------
  |  |   52|    568|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1053|    568|            *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|    568|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1054|    568|            return result;
 1055|       |
 1056|      0|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1056:9): [True: 0, False: 7.08k]
  ------------------
 1057|      0|            if (run_container_is_full(const_CAST_run(c2))) {
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1057:17): [True: 0, False: 0]
  ------------------
 1058|      0|                result = run_container_create();
 1059|      0|                *result_type = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
 1060|      0|                run_container_copy(const_CAST_run(c2), CAST_run(result));
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              run_container_copy(const_CAST_run(c2), CAST_run(result));
  ------------------
  |  |   77|      0|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1061|      0|                return result;
 1062|      0|            }
 1063|      0|            result = bitset_container_create();
 1064|      0|            run_bitset_container_union(
 1065|      0|                const_CAST_run(c2), const_CAST_bitset(c1), CAST_bitset(result));
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_run(c2), const_CAST_bitset(c1), CAST_bitset(result));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_run(c2), const_CAST_bitset(c1), CAST_bitset(result));
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1066|      0|            *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1067|      0|            return result;
 1068|       |
 1069|    593|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|    593|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    593|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    593|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1069:9): [True: 593, False: 6.49k]
  ------------------
 1070|    593|            if (run_container_is_full(const_CAST_run(c1))) {
  ------------------
  |  |   78|    593|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1070:17): [True: 0, False: 593]
  ------------------
 1071|      0|                result = run_container_create();
 1072|      0|                *result_type = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
 1073|      0|                run_container_copy(const_CAST_run(c1), CAST_run(result));
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              run_container_copy(const_CAST_run(c1), CAST_run(result));
  ------------------
  |  |   77|      0|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1074|      0|                return result;
 1075|      0|            }
 1076|    593|            result = bitset_container_create();
 1077|    593|            run_bitset_container_union(
 1078|    593|                const_CAST_run(c1), const_CAST_bitset(c2), CAST_bitset(result));
  ------------------
  |  |   78|    593|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_run(c1), const_CAST_bitset(c2), CAST_bitset(result));
  ------------------
  |  |   53|    593|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_run(c1), const_CAST_bitset(c2), CAST_bitset(result));
  ------------------
  |  |   52|    593|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1079|    593|            *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|    593|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1080|    593|            return result;
 1081|       |
 1082|    664|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|    664|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    664|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    664|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1082:9): [True: 664, False: 6.42k]
  ------------------
 1083|    664|            result = run_container_create();
 1084|    664|            array_run_container_union(const_CAST_array(c1), const_CAST_run(c2),
  ------------------
  |  |   55|    664|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          array_run_container_union(const_CAST_array(c1), const_CAST_run(c2),
  ------------------
  |  |   78|    664|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1085|    664|                                      CAST_run(result));
  ------------------
  |  |   77|    664|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1086|    664|            result = convert_run_to_efficient_container_and_free(
 1087|    664|                CAST_run(result), result_type);
  ------------------
  |  |   77|    664|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1088|    664|            return result;
 1089|       |
 1090|  1.09k|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|  1.09k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  1.09k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  1.09k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1090:9): [True: 1.09k, False: 5.99k]
  ------------------
 1091|  1.09k|            result = run_container_create();
 1092|  1.09k|            array_run_container_union(const_CAST_array(c2), const_CAST_run(c1),
  ------------------
  |  |   55|  1.09k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          array_run_container_union(const_CAST_array(c2), const_CAST_run(c1),
  ------------------
  |  |   78|  1.09k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1093|  1.09k|                                      CAST_run(result));
  ------------------
  |  |   77|  1.09k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1094|  1.09k|            result = convert_run_to_efficient_container_and_free(
 1095|  1.09k|                CAST_run(result), result_type);
  ------------------
  |  |   77|  1.09k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1096|  1.09k|            return result;
 1097|       |
 1098|      0|        default:
  ------------------
  |  Branch (1098:9): [True: 0, False: 7.08k]
  ------------------
 1099|      0|            assert(false);
 1100|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 1101|      0|            return NULL;  // unreached
 1102|  7.08k|    }
 1103|  7.08k|}
roaring.c:container_is_full:
  262|  7.82k|static inline bool container_is_full(const container_t *c, uint8_t typecode) {
  263|  7.82k|    c = container_unwrap_shared(c, &typecode);
  264|  7.82k|    switch (typecode) {
  ------------------
  |  Branch (264:13): [True: 7.82k, False: 0]
  ------------------
  265|      0|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (265:9): [True: 0, False: 7.82k]
  ------------------
  266|      0|            return bitset_container_cardinality(const_CAST_bitset(c)) ==
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  267|      0|                   (1 << 16);
  268|  4.77k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  4.77k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (268:9): [True: 4.77k, False: 3.05k]
  ------------------
  269|  4.77k|            return array_container_cardinality(const_CAST_array(c)) ==
  ------------------
  |  |   55|  4.77k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  4.77k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  270|  4.77k|                   (1 << 16);
  271|  3.05k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  3.05k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (271:9): [True: 3.05k, False: 4.77k]
  ------------------
  272|  3.05k|            return run_container_is_full(const_CAST_run(c));
  ------------------
  |  |   78|  3.05k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.05k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  273|  7.82k|    }
  274|  7.82k|    assert(false);
  275|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  276|      0|    return 0;  // unreached
  277|  7.82k|}
roaring.c:container_ior:
 1228|  7.18k|                                         uint8_t *result_type) {
 1229|  7.18k|    c1 = get_writable_copy_if_shared(c1, &type1);
 1230|  7.18k|    c2 = container_unwrap_shared(c2, &type2);
 1231|  7.18k|    container_t *result = NULL;
 1232|  7.18k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  7.18k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
 1233|      0|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1233:9): [True: 0, False: 7.18k]
  ------------------
 1234|      0|            bitset_container_or(const_CAST_bitset(c1), const_CAST_bitset(c2),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          bitset_container_or(const_CAST_bitset(c1), const_CAST_bitset(c2),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1235|      0|                                CAST_bitset(c1));
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1236|      0|#if CROARING_OR_BITSET_CONVERSION_TO_FULL
 1237|      0|            if (CAST_bitset(c1)->cardinality == (1 << 16)) {  // we convert
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1237:17): [True: 0, False: 0]
  ------------------
 1238|      0|                result = run_container_create_range(0, (1 << 16));
 1239|      0|                *result_type = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
 1240|      0|                return result;
 1241|      0|            }
 1242|      0|#endif
 1243|      0|            *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1244|      0|            return c1;
 1245|       |
 1246|  3.62k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  3.62k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.62k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.62k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1246:9): [True: 3.62k, False: 3.56k]
  ------------------
 1247|  3.62k|            *result_type = array_array_container_inplace_union(
  ------------------
  |  Branch (1247:28): [True: 0, False: 3.62k]
  ------------------
 1248|  3.62k|                               CAST_array(c1), const_CAST_array(c2), &result)
  ------------------
  |  |   54|  3.62k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  3.62k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_array(c1), const_CAST_array(c2), &result)
  ------------------
  |  |   55|  3.62k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.62k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1249|  3.62k|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1250|  3.62k|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  7.24k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1251|  3.62k|            if ((result == NULL) && (*result_type == ARRAY_CONTAINER_TYPE)) {
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (1251:17): [True: 0, False: 3.62k]
  |  Branch (1251:37): [True: 0, False: 0]
  ------------------
 1252|      0|                return c1;  // the computation was done in-place!
 1253|      0|            }
 1254|  3.62k|            return result;
 1255|       |
 1256|  1.56k|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|  1.56k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  1.56k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  1.56k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1256:9): [True: 1.56k, False: 5.62k]
  ------------------
 1257|  1.56k|            run_container_union_inplace(CAST_run(c1), const_CAST_run(c2));
  ------------------
  |  |   77|  1.56k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.56k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          run_container_union_inplace(CAST_run(c1), const_CAST_run(c2));
  ------------------
  |  |   78|  1.56k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.56k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1258|  1.56k|            return convert_run_to_efficient_container(CAST_run(c1),
  ------------------
  |  |   77|  1.56k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.56k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1259|  1.56k|                                                      result_type);
 1260|       |
 1261|      0|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1261:9): [True: 0, False: 7.18k]
  ------------------
 1262|      0|            array_bitset_container_union(
 1263|      0|                const_CAST_array(c2), const_CAST_bitset(c1), CAST_bitset(c1));
  ------------------
  |  |   55|      0|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c2), const_CAST_bitset(c1), CAST_bitset(c1));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c2), const_CAST_bitset(c1), CAST_bitset(c1));
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1264|      0|            *result_type = BITSET_CONTAINER_TYPE;  // never array
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1265|      0|            return c1;
 1266|       |
 1267|    609|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|    609|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    609|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    609|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1267:9): [True: 609, False: 6.57k]
  ------------------
 1268|       |            // c1 is an array, so no in-place possible
 1269|    609|            result = bitset_container_create();
 1270|    609|            *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|    609|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1271|    609|            array_bitset_container_union(const_CAST_array(c1),
  ------------------
  |  |   55|    609|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    609|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1272|    609|                                         const_CAST_bitset(c2),
  ------------------
  |  |   53|    609|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    609|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1273|    609|                                         CAST_bitset(result));
  ------------------
  |  |   52|    609|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    609|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1274|    609|            return result;
 1275|       |
 1276|      0|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1276:9): [True: 0, False: 7.18k]
  ------------------
 1277|      0|            if (run_container_is_full(const_CAST_run(c2))) {
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1277:17): [True: 0, False: 0]
  ------------------
 1278|      0|                result = run_container_create();
 1279|      0|                *result_type = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
 1280|      0|                run_container_copy(const_CAST_run(c2), CAST_run(result));
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              run_container_copy(const_CAST_run(c2), CAST_run(result));
  ------------------
  |  |   77|      0|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1281|      0|                return result;
 1282|      0|            }
 1283|      0|            run_bitset_container_union(const_CAST_run(c2),
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1284|      0|                                       const_CAST_bitset(c1),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1285|      0|                                       CAST_bitset(c1));  // allowed
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1286|      0|            *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1287|      0|            return c1;
 1288|       |
 1289|    593|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|    593|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    593|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    593|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1289:9): [True: 593, False: 6.59k]
  ------------------
 1290|    593|            if (run_container_is_full(const_CAST_run(c1))) {
  ------------------
  |  |   78|    593|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1290:17): [True: 0, False: 593]
  ------------------
 1291|      0|                *result_type = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
 1292|      0|                return c1;
 1293|      0|            }
 1294|    593|            result = bitset_container_create();
 1295|    593|            run_bitset_container_union(
 1296|    593|                const_CAST_run(c1), const_CAST_bitset(c2), CAST_bitset(result));
  ------------------
  |  |   78|    593|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_run(c1), const_CAST_bitset(c2), CAST_bitset(result));
  ------------------
  |  |   53|    593|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_run(c1), const_CAST_bitset(c2), CAST_bitset(result));
  ------------------
  |  |   52|    593|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1297|    593|            *result_type = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|    593|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1298|    593|            return result;
 1299|       |
 1300|    538|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|    538|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    538|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    538|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1300:9): [True: 538, False: 6.64k]
  ------------------
 1301|    538|            result = run_container_create();
 1302|    538|            array_run_container_union(const_CAST_array(c1), const_CAST_run(c2),
  ------------------
  |  |   55|    538|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    538|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          array_run_container_union(const_CAST_array(c1), const_CAST_run(c2),
  ------------------
  |  |   78|    538|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    538|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1303|    538|                                      CAST_run(result));
  ------------------
  |  |   77|    538|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    538|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1304|    538|            result = convert_run_to_efficient_container_and_free(
 1305|    538|                CAST_run(result), result_type);
  ------------------
  |  |   77|    538|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    538|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1306|    538|            return result;
 1307|       |
 1308|    262|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|    262|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    262|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    262|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1308:9): [True: 262, False: 6.92k]
  ------------------
 1309|    262|            array_run_container_inplace_union(const_CAST_array(c2),
  ------------------
  |  |   55|    262|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    262|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1310|    262|                                              CAST_run(c1));
  ------------------
  |  |   77|    262|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    262|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1311|    262|            c1 = convert_run_to_efficient_container(CAST_run(c1), result_type);
  ------------------
  |  |   77|    262|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    262|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1312|    262|            return c1;
 1313|       |
 1314|      0|        default:
  ------------------
  |  Branch (1314:9): [True: 0, False: 7.18k]
  ------------------
 1315|      0|            assert(false);
 1316|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 1317|      0|            return NULL;
 1318|  7.18k|    }
 1319|  7.18k|}
roaring.c:container_xor:
 1451|  7.08k|                                         uint8_t *result_type) {
 1452|  7.08k|    c1 = container_unwrap_shared(c1, &type1);
 1453|  7.08k|    c2 = container_unwrap_shared(c2, &type2);
 1454|  7.08k|    container_t *result = NULL;
 1455|  7.08k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  7.08k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
 1456|      0|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1456:9): [True: 0, False: 7.08k]
  ------------------
 1457|      0|            *result_type =
 1458|      0|                bitset_bitset_container_xor(const_CAST_bitset(c1),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1458:17): [True: 0, False: 0]
  ------------------
 1459|      0|                                            const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1460|      0|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1461|      0|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1462|      0|            return result;
 1463|       |
 1464|  3.45k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  3.45k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1464:9): [True: 3.45k, False: 3.63k]
  ------------------
 1465|  3.45k|            *result_type =
 1466|  3.45k|                array_array_container_xor(const_CAST_array(c1),
  ------------------
  |  |   55|  3.45k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1466:17): [True: 11, False: 3.44k]
  ------------------
 1467|  3.45k|                                          const_CAST_array(c2), &result)
  ------------------
  |  |   55|  3.45k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1468|  3.45k|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|     11|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1469|  3.45k|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  6.89k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1470|  3.45k|            return result;
 1471|       |
 1472|    710|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|    710|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    710|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    710|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1472:9): [True: 710, False: 6.37k]
  ------------------
 1473|    710|            *result_type = (uint8_t)run_run_container_xor(
 1474|    710|                const_CAST_run(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   78|    710|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_run(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   78|    710|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1475|    710|            return result;
 1476|       |
 1477|      0|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1477:9): [True: 0, False: 7.08k]
  ------------------
 1478|      0|            *result_type =
 1479|      0|                array_bitset_container_xor(const_CAST_array(c2),
  ------------------
  |  |   55|      0|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1479:17): [True: 0, False: 0]
  ------------------
 1480|      0|                                           const_CAST_bitset(c1), &result)
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1481|      0|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1482|      0|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1483|      0|            return result;
 1484|       |
 1485|    568|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|    568|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    568|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    568|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1485:9): [True: 568, False: 6.52k]
  ------------------
 1486|    568|            *result_type =
 1487|    568|                array_bitset_container_xor(const_CAST_array(c1),
  ------------------
  |  |   55|    568|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1487:17): [True: 505, False: 63]
  ------------------
 1488|    568|                                           const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|    568|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1489|    568|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|    505|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1490|    568|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|    631|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1491|    568|            return result;
 1492|       |
 1493|      0|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1493:9): [True: 0, False: 7.08k]
  ------------------
 1494|      0|            *result_type =
 1495|      0|                run_bitset_container_xor(const_CAST_run(c2),
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1495:17): [True: 0, False: 0]
  ------------------
 1496|      0|                                         const_CAST_bitset(c1), &result)
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1497|      0|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1498|      0|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1499|      0|            return result;
 1500|       |
 1501|    593|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|    593|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    593|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    593|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1501:9): [True: 593, False: 6.49k]
  ------------------
 1502|    593|            *result_type =
 1503|    593|                run_bitset_container_xor(const_CAST_run(c1),
  ------------------
  |  |   78|    593|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1503:17): [True: 505, False: 88]
  ------------------
 1504|    593|                                         const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|    593|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1505|    593|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|    505|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1506|    593|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|    681|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1507|    593|            return result;
 1508|       |
 1509|    664|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|    664|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    664|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    664|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1509:9): [True: 664, False: 6.42k]
  ------------------
 1510|    664|            *result_type = (uint8_t)array_run_container_xor(
 1511|    664|                const_CAST_array(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   55|    664|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   78|    664|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1512|    664|            return result;
 1513|       |
 1514|  1.09k|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|  1.09k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  1.09k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  1.09k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1514:9): [True: 1.09k, False: 5.99k]
  ------------------
 1515|  1.09k|            *result_type = (uint8_t)array_run_container_xor(
 1516|  1.09k|                const_CAST_array(c2), const_CAST_run(c1), &result);
  ------------------
  |  |   55|  1.09k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c2), const_CAST_run(c1), &result);
  ------------------
  |  |   78|  1.09k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1517|  1.09k|            return result;
 1518|       |
 1519|      0|        default:
  ------------------
  |  Branch (1519:9): [True: 0, False: 7.08k]
  ------------------
 1520|      0|            assert(false);
 1521|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 1522|      0|            return NULL;  // unreached
 1523|  7.08k|    }
 1524|  7.08k|}
roaring.c:container_ixor:
 1667|  60.1k|                                          uint8_t *result_type) {
 1668|  60.1k|    c1 = get_writable_copy_if_shared(c1, &type1);
 1669|  60.1k|    c2 = container_unwrap_shared(c2, &type2);
 1670|  60.1k|    container_t *result = NULL;
 1671|  60.1k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  60.1k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
 1672|  1.35k|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|  1.35k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|  1.35k|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|  1.35k|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1672:9): [True: 1.35k, False: 58.8k]
  ------------------
 1673|  1.35k|            *result_type = bitset_bitset_container_ixor(
  ------------------
  |  Branch (1673:28): [True: 0, False: 1.35k]
  ------------------
 1674|  1.35k|                               CAST_bitset(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   52|  1.35k|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.35k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_bitset(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|  1.35k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.35k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1675|  1.35k|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1676|  1.35k|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  2.71k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1677|  1.35k|            return result;
 1678|       |
 1679|  5.36k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  5.36k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  5.36k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  5.36k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1679:9): [True: 5.36k, False: 54.8k]
  ------------------
 1680|  5.36k|            *result_type = array_array_container_ixor(
  ------------------
  |  Branch (1680:28): [True: 0, False: 5.36k]
  ------------------
 1681|  5.36k|                               CAST_array(c1), const_CAST_array(c2), &result)
  ------------------
  |  |   54|  5.36k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  5.36k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_array(c1), const_CAST_array(c2), &result)
  ------------------
  |  |   55|  5.36k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  5.36k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1682|  5.36k|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1683|  5.36k|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  10.7k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1684|  5.36k|            return result;
 1685|       |
 1686|  53.0k|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|  53.0k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  53.0k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  53.0k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1686:9): [True: 53.0k, False: 7.18k]
  ------------------
 1687|  53.0k|            *result_type = (uint8_t)run_run_container_ixor(
 1688|  53.0k|                CAST_run(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   77|  53.0k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  53.0k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              CAST_run(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   78|  53.0k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  53.0k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1689|  53.0k|            return result;
 1690|       |
 1691|      0|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1691:9): [True: 0, False: 60.1k]
  ------------------
 1692|      0|            *result_type = bitset_array_container_ixor(
  ------------------
  |  Branch (1692:28): [True: 0, False: 0]
  ------------------
 1693|      0|                               CAST_bitset(c1), const_CAST_array(c2), &result)
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_bitset(c1), const_CAST_array(c2), &result)
  ------------------
  |  |   55|      0|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1694|      0|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1695|      0|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1696|      0|            return result;
 1697|       |
 1698|     73|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|     73|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|     73|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|     73|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1698:9): [True: 73, False: 60.1k]
  ------------------
 1699|     73|            *result_type = array_bitset_container_ixor(
  ------------------
  |  Branch (1699:28): [True: 0, False: 73]
  ------------------
 1700|     73|                               CAST_array(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   54|     73|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|     73|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_array(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|     73|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|     73|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1701|     73|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1702|     73|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|    146|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1703|     73|            return result;
 1704|       |
 1705|     72|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|     72|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|     72|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|     72|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1705:9): [True: 72, False: 60.1k]
  ------------------
 1706|     72|            *result_type = bitset_run_container_ixor(
  ------------------
  |  Branch (1706:28): [True: 0, False: 72]
  ------------------
 1707|     72|                               CAST_bitset(c1), const_CAST_run(c2), &result)
  ------------------
  |  |   52|     72|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|     72|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_bitset(c1), const_CAST_run(c2), &result)
  ------------------
  |  |   78|     72|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|     72|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1708|     72|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1709|     72|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|    144|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1710|       |
 1711|     72|            return result;
 1712|       |
 1713|     10|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|     10|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|     10|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|     10|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1713:9): [True: 10, False: 60.1k]
  ------------------
 1714|     10|            *result_type = run_bitset_container_ixor(
  ------------------
  |  Branch (1714:28): [True: 0, False: 10]
  ------------------
 1715|     10|                               CAST_run(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   77|     10|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|     10|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_run(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|     10|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|     10|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1716|     10|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1717|     10|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|     20|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1718|     10|            return result;
 1719|       |
 1720|    237|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|    237|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    237|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    237|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1720:9): [True: 237, False: 59.9k]
  ------------------
 1721|    237|            *result_type = (uint8_t)array_run_container_ixor(
 1722|    237|                CAST_array(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   54|    237|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    237|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              CAST_array(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   78|    237|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    237|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1723|    237|            return result;
 1724|       |
 1725|     65|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|     65|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|     65|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|     65|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1725:9): [True: 65, False: 60.1k]
  ------------------
 1726|     65|            *result_type = (uint8_t)run_array_container_ixor(
 1727|     65|                CAST_run(c1), const_CAST_array(c2), &result);
  ------------------
  |  |   77|     65|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|     65|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              CAST_run(c1), const_CAST_array(c2), &result);
  ------------------
  |  |   55|     65|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|     65|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1728|     65|            return result;
 1729|       |
 1730|      0|        default:
  ------------------
  |  Branch (1730:9): [True: 0, False: 60.1k]
  ------------------
 1731|      0|            assert(false);
 1732|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 1733|      0|            return NULL;
 1734|  60.1k|    }
 1735|  60.1k|}
roaring.c:container_andnot:
 1787|  7.08k|                                            uint8_t *result_type) {
 1788|  7.08k|    c1 = container_unwrap_shared(c1, &type1);
 1789|  7.08k|    c2 = container_unwrap_shared(c2, &type2);
 1790|  7.08k|    container_t *result = NULL;
 1791|  7.08k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  7.08k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
 1792|      0|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1792:9): [True: 0, False: 7.08k]
  ------------------
 1793|      0|            *result_type =
 1794|      0|                bitset_bitset_container_andnot(const_CAST_bitset(c1),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1794:17): [True: 0, False: 0]
  ------------------
 1795|      0|                                               const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1796|      0|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1797|      0|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1798|      0|            return result;
 1799|       |
 1800|  3.45k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  3.45k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1800:9): [True: 3.45k, False: 3.63k]
  ------------------
 1801|  3.45k|            result = array_container_create();
 1802|  3.45k|            array_array_container_andnot(
 1803|  3.45k|                const_CAST_array(c1), const_CAST_array(c2), CAST_array(result));
  ------------------
  |  |   55|  3.45k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_array(c2), CAST_array(result));
  ------------------
  |  |   55|  3.45k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_array(c2), CAST_array(result));
  ------------------
  |  |   54|  3.45k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1804|  3.45k|            *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1805|  3.45k|            return result;
 1806|       |
 1807|    710|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|    710|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    710|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    710|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1807:9): [True: 710, False: 6.37k]
  ------------------
 1808|    710|            if (run_container_is_full(const_CAST_run(c2))) {
  ------------------
  |  |   78|    710|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1808:17): [True: 10, False: 700]
  ------------------
 1809|     10|                result = array_container_create();
 1810|     10|                *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|     10|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1811|     10|                return result;
 1812|     10|            }
 1813|    700|            *result_type = (uint8_t)run_run_container_andnot(
 1814|    700|                const_CAST_run(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   78|    700|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    700|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_run(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   78|    700|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    700|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1815|    700|            return result;
 1816|       |
 1817|      0|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1817:9): [True: 0, False: 7.08k]
  ------------------
 1818|      0|            *result_type =
 1819|      0|                bitset_array_container_andnot(const_CAST_bitset(c1),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1819:17): [True: 0, False: 0]
  ------------------
 1820|      0|                                              const_CAST_array(c2), &result)
  ------------------
  |  |   55|      0|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1821|      0|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1822|      0|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1823|      0|            return result;
 1824|       |
 1825|    568|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|    568|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    568|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    568|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1825:9): [True: 568, False: 6.52k]
  ------------------
 1826|    568|            result = array_container_create();
 1827|    568|            array_bitset_container_andnot(const_CAST_array(c1),
  ------------------
  |  |   55|    568|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1828|    568|                                          const_CAST_bitset(c2),
  ------------------
  |  |   53|    568|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1829|    568|                                          CAST_array(result));
  ------------------
  |  |   54|    568|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1830|    568|            *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|    568|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1831|    568|            return result;
 1832|       |
 1833|      0|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1833:9): [True: 0, False: 7.08k]
  ------------------
 1834|      0|            if (run_container_is_full(const_CAST_run(c2))) {
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1834:17): [True: 0, False: 0]
  ------------------
 1835|      0|                result = array_container_create();
 1836|      0|                *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1837|      0|                return result;
 1838|      0|            }
 1839|      0|            *result_type =
 1840|      0|                bitset_run_container_andnot(const_CAST_bitset(c1),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1840:17): [True: 0, False: 0]
  ------------------
 1841|      0|                                            const_CAST_run(c2), &result)
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1842|      0|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1843|      0|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1844|      0|            return result;
 1845|       |
 1846|    593|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|    593|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    593|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    593|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1846:9): [True: 593, False: 6.49k]
  ------------------
 1847|    593|            *result_type =
 1848|    593|                run_bitset_container_andnot(const_CAST_run(c1),
  ------------------
  |  |   78|    593|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1848:17): [True: 0, False: 593]
  ------------------
 1849|    593|                                            const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|    593|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1850|    593|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1851|    593|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  1.18k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1852|    593|            return result;
 1853|       |
 1854|    664|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|    664|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    664|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    664|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1854:9): [True: 664, False: 6.42k]
  ------------------
 1855|    664|            if (run_container_is_full(const_CAST_run(c2))) {
  ------------------
  |  |   78|    664|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (1855:17): [True: 16, False: 648]
  ------------------
 1856|     16|                result = array_container_create();
 1857|     16|                *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|     16|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1858|     16|                return result;
 1859|     16|            }
 1860|    648|            result = array_container_create();
 1861|    648|            array_run_container_andnot(const_CAST_array(c1), const_CAST_run(c2),
  ------------------
  |  |   55|    648|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    648|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          array_run_container_andnot(const_CAST_array(c1), const_CAST_run(c2),
  ------------------
  |  |   78|    648|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    648|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1862|    648|                                       CAST_array(result));
  ------------------
  |  |   54|    648|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    648|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1863|    648|            *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|    648|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1864|    648|            return result;
 1865|       |
 1866|  1.09k|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|  1.09k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  1.09k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  1.09k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1866:9): [True: 1.09k, False: 5.99k]
  ------------------
 1867|  1.09k|            *result_type = (uint8_t)run_array_container_andnot(
 1868|  1.09k|                const_CAST_run(c1), const_CAST_array(c2), &result);
  ------------------
  |  |   78|  1.09k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_run(c1), const_CAST_array(c2), &result);
  ------------------
  |  |   55|  1.09k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1869|  1.09k|            return result;
 1870|       |
 1871|      0|        default:
  ------------------
  |  Branch (1871:9): [True: 0, False: 7.08k]
  ------------------
 1872|      0|            assert(false);
 1873|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 1874|      0|            return NULL;  // unreached
 1875|  7.08k|    }
 1876|  7.08k|}
roaring.c:container_iandnot:
 1891|  6.79k|                                             uint8_t *result_type) {
 1892|  6.79k|    c1 = get_writable_copy_if_shared(c1, &type1);
 1893|  6.79k|    c2 = container_unwrap_shared(c2, &type2);
 1894|  6.79k|    container_t *result = NULL;
 1895|  6.79k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  6.79k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
 1896|      0|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1896:9): [True: 0, False: 6.79k]
  ------------------
 1897|      0|            *result_type = bitset_bitset_container_iandnot(
  ------------------
  |  Branch (1897:28): [True: 0, False: 0]
  ------------------
 1898|      0|                               CAST_bitset(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_bitset(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1899|      0|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1900|      0|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1901|      0|            return result;
 1902|       |
 1903|  4.47k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  4.47k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  4.47k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  4.47k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1903:9): [True: 4.47k, False: 2.32k]
  ------------------
 1904|  4.47k|            array_array_container_iandnot(CAST_array(c1), const_CAST_array(c2));
  ------------------
  |  |   54|  4.47k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  4.47k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          array_array_container_iandnot(CAST_array(c1), const_CAST_array(c2));
  ------------------
  |  |   55|  4.47k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  4.47k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1905|  4.47k|            *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  4.47k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1906|  4.47k|            return c1;
 1907|       |
 1908|    471|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|    471|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    471|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    471|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1908:9): [True: 471, False: 6.32k]
  ------------------
 1909|    471|            *result_type = (uint8_t)run_run_container_iandnot(
 1910|    471|                CAST_run(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   77|    471|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    471|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              CAST_run(c1), const_CAST_run(c2), &result);
  ------------------
  |  |   78|    471|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    471|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1911|    471|            return result;
 1912|       |
 1913|  1.13k|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|  1.13k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|  1.13k|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  1.13k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1913:9): [True: 1.13k, False: 5.65k]
  ------------------
 1914|  1.13k|            *result_type = bitset_array_container_iandnot(
  ------------------
  |  Branch (1914:28): [True: 926, False: 211]
  ------------------
 1915|  1.13k|                               CAST_bitset(c1), const_CAST_array(c2), &result)
  ------------------
  |  |   52|  1.13k|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.13k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_bitset(c1), const_CAST_array(c2), &result)
  ------------------
  |  |   55|  1.13k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.13k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1916|  1.13k|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|    926|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1917|  1.13k|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  1.34k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1918|  1.13k|            return result;
 1919|       |
 1920|      0|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1920:9): [True: 0, False: 6.79k]
  ------------------
 1921|      0|            *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1922|      0|            array_bitset_container_iandnot(CAST_array(c1),
  ------------------
  |  |   54|      0|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1923|      0|                                           const_CAST_bitset(c2));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1924|      0|            return c1;
 1925|       |
 1926|      0|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1926:9): [True: 0, False: 6.79k]
  ------------------
 1927|      0|            *result_type = bitset_run_container_iandnot(
  ------------------
  |  Branch (1927:28): [True: 0, False: 0]
  ------------------
 1928|      0|                               CAST_bitset(c1), const_CAST_run(c2), &result)
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_bitset(c1), const_CAST_run(c2), &result)
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1929|      0|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1930|      0|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1931|      0|            return result;
 1932|       |
 1933|      0|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (1933:9): [True: 0, False: 6.79k]
  ------------------
 1934|      0|            *result_type = run_bitset_container_iandnot(
  ------------------
  |  Branch (1934:28): [True: 0, False: 0]
  ------------------
 1935|      0|                               CAST_run(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   77|      0|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                                             CAST_run(c1), const_CAST_bitset(c2), &result)
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1936|      0|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
 1937|      0|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1938|      0|            return result;
 1939|       |
 1940|     45|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|     45|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|     45|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|     45|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (1940:9): [True: 45, False: 6.74k]
  ------------------
 1941|     45|            *result_type = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|     45|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 1942|     45|            array_run_container_iandnot(CAST_array(c1), const_CAST_run(c2));
  ------------------
  |  |   54|     45|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|     45|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          array_run_container_iandnot(CAST_array(c1), const_CAST_run(c2));
  ------------------
  |  |   78|     45|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|     45|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1943|     45|            return c1;
 1944|       |
 1945|    668|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|    668|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    668|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    668|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (1945:9): [True: 668, False: 6.12k]
  ------------------
 1946|    668|            *result_type = (uint8_t)run_array_container_iandnot(
 1947|    668|                CAST_run(c1), const_CAST_array(c2), &result);
  ------------------
  |  |   77|    668|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    668|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              CAST_run(c1), const_CAST_array(c2), &result);
  ------------------
  |  |   55|    668|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    668|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1948|    668|            return result;
 1949|       |
 1950|      0|        default:
  ------------------
  |  Branch (1950:9): [True: 0, False: 6.79k]
  ------------------
 1951|      0|            assert(false);
 1952|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 1953|      0|            return NULL;
 1954|  6.79k|    }
 1955|  6.79k|}
roaring.c:container_rank:
 2203|  7.18k|                                 uint16_t x) {
 2204|  7.18k|    c = container_unwrap_shared(c, &type);
 2205|  7.18k|    switch (type) {
 2206|      0|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (2206:9): [True: 0, False: 7.18k]
  ------------------
 2207|      0|            return bitset_container_rank(const_CAST_bitset(c), x);
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2208|  4.76k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  4.76k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (2208:9): [True: 4.76k, False: 2.41k]
  ------------------
 2209|  4.76k|            return array_container_rank(const_CAST_array(c), x);
  ------------------
  |  |   55|  4.76k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  4.76k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2210|  2.41k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  2.41k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (2210:9): [True: 2.41k, False: 4.76k]
  ------------------
 2211|  2.41k|            return run_container_rank(const_CAST_run(c), x);
  ------------------
  |  |   78|  2.41k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.41k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2212|      0|        default:
  ------------------
  |  Branch (2212:9): [True: 0, False: 7.18k]
  ------------------
 2213|      0|            assert(false);
 2214|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2215|  7.18k|    }
 2216|  7.18k|    assert(false);
 2217|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2218|      0|    return false;
 2219|  7.18k|}
roaring.c:container_shrink_to_fit:
  279|  7.18k|static inline int container_shrink_to_fit(container_t *c, uint8_t type) {
  280|  7.18k|    c = container_mutable_unwrap_shared(c, &type);
  281|  7.18k|    switch (type) {
  ------------------
  |  Branch (281:13): [True: 7.18k, False: 0]
  ------------------
  282|      0|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (282:9): [True: 0, False: 7.18k]
  ------------------
  283|      0|            return 0;  // no shrinking possible
  284|  4.76k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  4.76k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (284:9): [True: 4.76k, False: 2.41k]
  ------------------
  285|  4.76k|            return array_container_shrink_to_fit(CAST_array(c));
  ------------------
  |  |   54|  4.76k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  4.76k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  286|  2.41k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  2.41k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (286:9): [True: 2.41k, False: 4.76k]
  ------------------
  287|  2.41k|            return run_container_shrink_to_fit(CAST_run(c));
  ------------------
  |  |   77|  2.41k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  2.41k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  288|  7.18k|    }
  289|  7.18k|    assert(false);
  290|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  291|      0|    return 0;  // unreached
  292|  7.18k|}
roaring.c:container_iterate:
 1964|  62.1k|                                     void *ptr) {
 1965|  62.1k|    c = container_unwrap_shared(c, &type);
 1966|  62.1k|    switch (type) {
 1967|  1.44k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|  1.44k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (1967:9): [True: 1.44k, False: 60.7k]
  ------------------
 1968|  1.44k|            return bitset_container_iterate(const_CAST_bitset(c), base,
  ------------------
  |  |   53|  1.44k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.44k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1969|  1.44k|                                            iterator, ptr);
 1970|  7.26k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  7.26k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (1970:9): [True: 7.26k, False: 54.9k]
  ------------------
 1971|  7.26k|            return array_container_iterate(const_CAST_array(c), base, iterator,
  ------------------
  |  |   55|  7.26k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  7.26k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1972|  7.26k|                                           ptr);
 1973|  53.4k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  53.4k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (1973:9): [True: 53.4k, False: 8.70k]
  ------------------
 1974|  53.4k|            return run_container_iterate(const_CAST_run(c), base, iterator,
  ------------------
  |  |   78|  53.4k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  53.4k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1975|  53.4k|                                         ptr);
 1976|      0|        default:
  ------------------
  |  Branch (1976:9): [True: 0, False: 62.1k]
  ------------------
 1977|      0|            assert(false);
 1978|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 1979|  62.1k|    }
 1980|  62.1k|    assert(false);
 1981|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 1982|      0|    return false;
 1983|  62.1k|}
roaring.c:container_maximum:
 2165|  14.2k|static inline uint16_t container_maximum(const container_t *c, uint8_t type) {
 2166|  14.2k|    c = container_unwrap_shared(c, &type);
 2167|  14.2k|    switch (type) {
 2168|  2.35k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|  2.35k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (2168:9): [True: 2.35k, False: 11.9k]
  ------------------
 2169|  2.35k|            return bitset_container_maximum(const_CAST_bitset(c));
  ------------------
  |  |   53|  2.35k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.35k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2170|  10.5k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  10.5k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (2170:9): [True: 10.5k, False: 3.73k]
  ------------------
 2171|  10.5k|            return array_container_maximum(const_CAST_array(c));
  ------------------
  |  |   55|  10.5k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  10.5k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2172|  1.38k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  1.38k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (2172:9): [True: 1.38k, False: 12.8k]
  ------------------
 2173|  1.38k|            return run_container_maximum(const_CAST_run(c));
  ------------------
  |  |   78|  1.38k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.38k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2174|      0|        default:
  ------------------
  |  Branch (2174:9): [True: 0, False: 14.2k]
  ------------------
 2175|      0|            assert(false);
 2176|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2177|  14.2k|    }
 2178|  14.2k|    assert(false);
 2179|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2180|      0|    return false;
 2181|  14.2k|}
roaring.c:container_equals:
  620|  78.7k|                                    const container_t *c2, uint8_t type2) {
  621|  78.7k|    c1 = container_unwrap_shared(c1, &type1);
  622|  78.7k|    c2 = container_unwrap_shared(c2, &type2);
  623|  78.7k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  78.7k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
  624|  66.2k|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|  66.2k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|  66.2k|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|  66.2k|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (624:9): [True: 66.2k, False: 12.4k]
  ------------------
  625|  66.2k|            return bitset_container_equals(const_CAST_bitset(c1),
  ------------------
  |  |   53|  66.2k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  66.2k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  626|  66.2k|                                           const_CAST_bitset(c2));
  ------------------
  |  |   53|  66.2k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  66.2k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  627|       |
  628|      0|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (628:9): [True: 0, False: 78.7k]
  ------------------
  629|      0|            return run_container_equals_bitset(const_CAST_run(c2),
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  630|      0|                                               const_CAST_bitset(c1));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  631|       |
  632|      0|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (632:9): [True: 0, False: 78.7k]
  ------------------
  633|      0|            return run_container_equals_bitset(const_CAST_run(c1),
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  634|      0|                                               const_CAST_bitset(c2));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  635|       |
  636|      0|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (636:9): [True: 0, False: 78.7k]
  ------------------
  637|       |            // java would always return false?
  638|      0|            return array_container_equal_bitset(const_CAST_array(c2),
  ------------------
  |  |   55|      0|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  639|      0|                                                const_CAST_bitset(c1));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  640|       |
  641|    385|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|    385|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    385|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    385|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (641:9): [True: 385, False: 78.4k]
  ------------------
  642|       |            // java would always return false?
  643|    385|            return array_container_equal_bitset(const_CAST_array(c1),
  ------------------
  |  |   55|    385|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    385|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  644|    385|                                                const_CAST_bitset(c2));
  ------------------
  |  |   53|    385|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    385|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  645|       |
  646|    650|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|    650|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    650|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    650|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (646:9): [True: 650, False: 78.1k]
  ------------------
  647|    650|            return run_container_equals_array(const_CAST_run(c2),
  ------------------
  |  |   78|    650|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    650|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  648|    650|                                              const_CAST_array(c1));
  ------------------
  |  |   55|    650|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    650|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  649|       |
  650|    228|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|    228|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    228|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    228|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (650:9): [True: 228, False: 78.5k]
  ------------------
  651|    228|            return run_container_equals_array(const_CAST_run(c1),
  ------------------
  |  |   78|    228|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    228|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  652|    228|                                              const_CAST_array(c2));
  ------------------
  |  |   55|    228|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    228|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  653|       |
  654|  11.1k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  11.1k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  11.1k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  11.1k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (654:9): [True: 11.1k, False: 67.6k]
  ------------------
  655|  11.1k|            return array_container_equals(const_CAST_array(c1),
  ------------------
  |  |   55|  11.1k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  11.1k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  656|  11.1k|                                          const_CAST_array(c2));
  ------------------
  |  |   55|  11.1k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  11.1k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  657|       |
  658|    126|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|    126|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    126|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    126|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (658:9): [True: 126, False: 78.6k]
  ------------------
  659|    126|            return run_container_equals(const_CAST_run(c1), const_CAST_run(c2));
  ------------------
  |  |   78|    126|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    126|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                          return run_container_equals(const_CAST_run(c1), const_CAST_run(c2));
  ------------------
  |  |   78|    126|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    126|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  660|       |
  661|      0|        default:
  ------------------
  |  Branch (661:9): [True: 0, False: 78.7k]
  ------------------
  662|      0|            assert(false);
  663|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  664|      0|            return false;
  665|  78.7k|    }
  666|  78.7k|}
roaring.c:container_is_subset:
  673|  12.0k|                                       const container_t *c2, uint8_t type2) {
  674|  12.0k|    c1 = container_unwrap_shared(c1, &type1);
  675|  12.0k|    c2 = container_unwrap_shared(c2, &type2);
  676|  12.0k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  12.0k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
  677|      0|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (677:9): [True: 0, False: 12.0k]
  ------------------
  678|      0|            return bitset_container_is_subset(const_CAST_bitset(c1),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  679|      0|                                              const_CAST_bitset(c2));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  680|       |
  681|      0|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (681:9): [True: 0, False: 12.0k]
  ------------------
  682|      0|            return bitset_container_is_subset_run(const_CAST_bitset(c1),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  683|      0|                                                  const_CAST_run(c2));
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  684|       |
  685|      0|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (685:9): [True: 0, False: 12.0k]
  ------------------
  686|      0|            return run_container_is_subset_bitset(const_CAST_run(c1),
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  687|      0|                                                  const_CAST_bitset(c2));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  688|       |
  689|      0|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (689:9): [True: 0, False: 12.0k]
  ------------------
  690|      0|            return false;  // by construction, size(c1) > size(c2)
  691|       |
  692|  2.23k|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|  2.23k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  2.23k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|  2.23k|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (692:9): [True: 2.23k, False: 9.84k]
  ------------------
  693|  2.23k|            return array_container_is_subset_bitset(const_CAST_array(c1),
  ------------------
  |  |   55|  2.23k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.23k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  694|  2.23k|                                                    const_CAST_bitset(c2));
  ------------------
  |  |   53|  2.23k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.23k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  695|       |
  696|  2.05k|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|  2.05k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  2.05k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  2.05k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (696:9): [True: 2.05k, False: 10.0k]
  ------------------
  697|  2.05k|            return array_container_is_subset_run(const_CAST_array(c1),
  ------------------
  |  |   55|  2.05k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.05k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  698|  2.05k|                                                 const_CAST_run(c2));
  ------------------
  |  |   78|  2.05k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.05k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  699|       |
  700|    350|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|    350|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    350|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    350|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (700:9): [True: 350, False: 11.7k]
  ------------------
  701|    350|            return run_container_is_subset_array(const_CAST_run(c1),
  ------------------
  |  |   78|    350|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    350|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  702|    350|                                                 const_CAST_array(c2));
  ------------------
  |  |   55|    350|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    350|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  703|       |
  704|  7.18k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  7.18k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  7.18k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  7.18k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (704:9): [True: 7.18k, False: 4.89k]
  ------------------
  705|  7.18k|            return array_container_is_subset(const_CAST_array(c1),
  ------------------
  |  |   55|  7.18k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  7.18k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  706|  7.18k|                                             const_CAST_array(c2));
  ------------------
  |  |   55|  7.18k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  7.18k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  707|       |
  708|    254|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|    254|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    254|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    254|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (708:9): [True: 254, False: 11.8k]
  ------------------
  709|    254|            return run_container_is_subset(const_CAST_run(c1),
  ------------------
  |  |   78|    254|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    254|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  710|    254|                                           const_CAST_run(c2));
  ------------------
  |  |   78|    254|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    254|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  711|       |
  712|      0|        default:
  ------------------
  |  Branch (712:9): [True: 0, False: 12.0k]
  ------------------
  713|      0|            assert(false);
  714|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  715|      0|            return false;
  716|  12.0k|    }
  717|  12.0k|}
roaring.c:container_inot_range:
 2105|  7.41k|                                                uint8_t *result_type) {
 2106|  7.41k|    c = get_writable_copy_if_shared(c, &type);
 2107|  7.41k|    container_t *result = NULL;
 2108|  7.41k|    switch (type) {
 2109|  1.22k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|  1.22k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (2109:9): [True: 1.22k, False: 6.19k]
  ------------------
 2110|  1.22k|            *result_type = bitset_container_negation_range_inplace(
  ------------------
  |  Branch (2110:28): [True: 1.20k, False: 18]
  ------------------
 2111|  1.22k|                               CAST_bitset(c), range_start, range_end, &result)
  ------------------
  |  |   52|  1.22k|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.22k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2112|  1.22k|                               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|  1.20k|#define BITSET_CONTAINER_TYPE 1
  ------------------
 2113|  1.22k|                               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  1.23k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 2114|  1.22k|            return result;
 2115|  4.53k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  4.53k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (2115:9): [True: 4.53k, False: 2.88k]
  ------------------
 2116|  4.53k|            *result_type = (uint8_t)array_container_negation_range_to_any(
 2117|  4.53k|                CAST_array(c), range_start, range_end, &result);
  ------------------
  |  |   54|  4.53k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  4.53k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2118|  4.53k|            array_container_free(CAST_array(c));
  ------------------
  |  |   54|  4.53k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  4.53k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2119|  4.53k|            return result;
 2120|  1.66k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  1.66k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (2120:9): [True: 1.66k, False: 5.75k]
  ------------------
 2121|  1.66k|            *result_type = (uint8_t)run_container_negation_range_inplace(
 2122|  1.66k|                CAST_run(c), range_start, range_end, &result);
  ------------------
  |  |   77|  1.66k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.66k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2123|  1.66k|            return result;
 2124|       |
 2125|      0|        default:
  ------------------
  |  Branch (2125:9): [True: 0, False: 7.41k]
  ------------------
 2126|      0|            assert(false);
 2127|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2128|  7.41k|    }
 2129|  7.41k|    assert(false);
 2130|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2131|      0|    return NULL;
 2132|  7.41k|}
roaring.c:container_inot:
 2072|  6.64k|                                          uint8_t *result_type) {
 2073|  6.64k|    c = get_writable_copy_if_shared(c, &type);
 2074|  6.64k|    container_t *result = NULL;
 2075|  6.64k|    switch (type) {
 2076|     46|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|     46|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (2076:9): [True: 46, False: 6.59k]
  ------------------
 2077|     46|            *result_type =
 2078|     46|                bitset_container_negation_inplace(CAST_bitset(c), &result)
  ------------------
  |  |   52|     46|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|     46|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  |  Branch (2078:17): [True: 31, False: 15]
  ------------------
 2079|     46|                    ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|     31|#define BITSET_CONTAINER_TYPE 1
  ------------------
 2080|     46|                    : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|     61|#define ARRAY_CONTAINER_TYPE 2
  ------------------
 2081|     46|            return result;
 2082|    175|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|    175|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (2082:9): [True: 175, False: 6.47k]
  ------------------
 2083|       |            // will never be inplace
 2084|    175|            *result_type = (uint8_t)array_container_negation_range_to_any(
 2085|    175|                CAST_array(c), 0, 1 << 16, &result);
  ------------------
  |  |   54|    175|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    175|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2086|    175|            array_container_free(CAST_array(c));
  ------------------
  |  |   54|    175|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    175|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2087|    175|            return result;
 2088|  6.42k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  6.42k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (2088:9): [True: 6.42k, False: 221]
  ------------------
 2089|  6.42k|            *result_type =
 2090|  6.42k|                (uint8_t)run_container_negation_inplace(CAST_run(c), &result);
  ------------------
  |  |   77|  6.42k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  6.42k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2091|  6.42k|            return result;
 2092|       |
 2093|      0|        default:
  ------------------
  |  Branch (2093:9): [True: 0, False: 6.64k]
  ------------------
 2094|      0|            assert(false);
 2095|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2096|  6.64k|    }
 2097|  6.64k|    assert(false);
 2098|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2099|      0|    return NULL;
 2100|  6.64k|}
roaring.c:container_unwrap_shared:
  106|  1.11M|    const container_t *candidate_shared_container, uint8_t *type) {
  107|  1.11M|    if (*type == SHARED_CONTAINER_TYPE) {
  ------------------
  |  |   51|  1.11M|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (107:9): [True: 0, False: 1.11M]
  ------------------
  108|      0|        *type = const_CAST_shared(candidate_shared_container)->typecode;
  ------------------
  |  |   80|      0|#define const_CAST_shared(c) CAST(const shared_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  109|      0|        assert(*type != SHARED_CONTAINER_TYPE);
  110|      0|        return const_CAST_shared(candidate_shared_container)->container;
  ------------------
  |  |   80|      0|#define const_CAST_shared(c) CAST(const shared_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  111|  1.11M|    } else {
  112|  1.11M|        return candidate_shared_container;
  113|  1.11M|    }
  114|  1.11M|}
roaring.c:container_mutable_unwrap_shared:
  118|  7.18k|                                                           uint8_t *type) {
  119|  7.18k|    if (*type == SHARED_CONTAINER_TYPE) {  // the passed in container is shared
  ------------------
  |  |   51|  7.18k|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (119:9): [True: 0, False: 7.18k]
  ------------------
  120|      0|        *type = CAST_shared(c)->typecode;
  ------------------
  |  |   79|      0|#define CAST_shared(c) CAST(shared_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  121|      0|        assert(*type != SHARED_CONTAINER_TYPE);
  122|      0|        return CAST_shared(c)->container;  // return the enclosed container
  ------------------
  |  |   79|      0|#define CAST_shared(c) CAST(shared_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  123|  7.18k|    } else {
  124|  7.18k|        return c;  // wasn't shared, so return as-is
  125|  7.18k|    }
  126|  7.18k|}
roaring.c:container_minimum:
 2183|  7.14k|static inline uint16_t container_minimum(const container_t *c, uint8_t type) {
 2184|  7.14k|    c = container_unwrap_shared(c, &type);
 2185|  7.14k|    switch (type) {
 2186|  1.16k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|  1.16k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (2186:9): [True: 1.16k, False: 5.97k]
  ------------------
 2187|  1.16k|            return bitset_container_minimum(const_CAST_bitset(c));
  ------------------
  |  |   53|  1.16k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.16k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2188|  4.58k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  4.58k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (2188:9): [True: 4.58k, False: 2.56k]
  ------------------
 2189|  4.58k|            return array_container_minimum(const_CAST_array(c));
  ------------------
  |  |   55|  4.58k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  4.58k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2190|  1.39k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  1.39k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (2190:9): [True: 1.39k, False: 5.74k]
  ------------------
 2191|  1.39k|            return run_container_minimum(const_CAST_run(c));
  ------------------
  |  |   78|  1.39k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.39k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2192|      0|        default:
  ------------------
  |  Branch (2192:9): [True: 0, False: 7.14k]
  ------------------
 2193|      0|            assert(false);
 2194|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2195|  7.14k|    }
 2196|  7.14k|    assert(false);
 2197|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2198|      0|    return false;
 2199|  7.14k|}
roaring.c:container_select:
 2144|  7.18k|                                    uint32_t *element) {
 2145|  7.18k|    c = container_unwrap_shared(c, &type);
 2146|  7.18k|    switch (type) {
 2147|      0|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (2147:9): [True: 0, False: 7.18k]
  ------------------
 2148|      0|            return bitset_container_select(const_CAST_bitset(c), start_rank,
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2149|      0|                                           rank, element);
 2150|  4.76k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  4.76k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (2150:9): [True: 4.76k, False: 2.41k]
  ------------------
 2151|  4.76k|            return array_container_select(const_CAST_array(c), start_rank, rank,
  ------------------
  |  |   55|  4.76k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  4.76k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2152|  4.76k|                                          element);
 2153|  2.41k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  2.41k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (2153:9): [True: 2.41k, False: 4.76k]
  ------------------
 2154|  2.41k|            return run_container_select(const_CAST_run(c), start_rank, rank,
  ------------------
  |  |   78|  2.41k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.41k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2155|  2.41k|                                        element);
 2156|      0|        default:
  ------------------
  |  Branch (2156:9): [True: 0, False: 7.18k]
  ------------------
 2157|      0|            assert(false);
 2158|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2159|  7.18k|    }
 2160|  7.18k|    assert(false);
 2161|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2162|      0|    return false;
 2163|  7.18k|}
roaring.c:container_intersect:
  865|  7.08k|                                       const container_t *c2, uint8_t type2) {
  866|  7.08k|    c1 = container_unwrap_shared(c1, &type1);
  867|  7.08k|    c2 = container_unwrap_shared(c2, &type2);
  868|  7.08k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  7.08k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
  869|      0|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (869:9): [True: 0, False: 7.08k]
  ------------------
  870|      0|            return bitset_container_intersect(const_CAST_bitset(c1),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  871|      0|                                              const_CAST_bitset(c2));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  872|       |
  873|  3.45k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  3.45k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  3.45k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (873:9): [True: 3.45k, False: 3.63k]
  ------------------
  874|  3.45k|            return array_container_intersect(const_CAST_array(c1),
  ------------------
  |  |   55|  3.45k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  875|  3.45k|                                             const_CAST_array(c2));
  ------------------
  |  |   55|  3.45k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.45k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  876|       |
  877|    710|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|    710|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    710|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    710|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (877:9): [True: 710, False: 6.37k]
  ------------------
  878|    710|            return run_container_intersect(const_CAST_run(c1),
  ------------------
  |  |   78|    710|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  879|    710|                                           const_CAST_run(c2));
  ------------------
  |  |   78|    710|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    710|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  880|       |
  881|      0|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (881:9): [True: 0, False: 7.08k]
  ------------------
  882|      0|            return array_bitset_container_intersect(const_CAST_array(c2),
  ------------------
  |  |   55|      0|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  883|      0|                                                    const_CAST_bitset(c1));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  884|       |
  885|    568|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|    568|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    568|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    568|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (885:9): [True: 568, False: 6.52k]
  ------------------
  886|    568|            return array_bitset_container_intersect(const_CAST_array(c1),
  ------------------
  |  |   55|    568|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  887|    568|                                                    const_CAST_bitset(c2));
  ------------------
  |  |   53|    568|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    568|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  888|       |
  889|      0|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (889:9): [True: 0, False: 7.08k]
  ------------------
  890|      0|            return run_bitset_container_intersect(const_CAST_run(c2),
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  891|      0|                                                  const_CAST_bitset(c1));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  892|       |
  893|    593|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|    593|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    593|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|    593|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (893:9): [True: 593, False: 6.49k]
  ------------------
  894|    593|            return run_bitset_container_intersect(const_CAST_run(c1),
  ------------------
  |  |   78|    593|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  895|    593|                                                  const_CAST_bitset(c2));
  ------------------
  |  |   53|    593|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    593|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  896|       |
  897|    664|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|    664|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|    664|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|    664|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (897:9): [True: 664, False: 6.42k]
  ------------------
  898|    664|            return array_run_container_intersect(const_CAST_array(c1),
  ------------------
  |  |   55|    664|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  899|    664|                                                 const_CAST_run(c2));
  ------------------
  |  |   78|    664|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    664|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  900|       |
  901|  1.09k|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|  1.09k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  1.09k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  1.09k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (901:9): [True: 1.09k, False: 5.99k]
  ------------------
  902|  1.09k|            return array_run_container_intersect(const_CAST_array(c2),
  ------------------
  |  |   55|  1.09k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  903|  1.09k|                                                 const_CAST_run(c1));
  ------------------
  |  |   78|  1.09k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.09k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  904|       |
  905|      0|        default:
  ------------------
  |  Branch (905:9): [True: 0, False: 7.08k]
  ------------------
  906|      0|            assert(false);
  907|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  908|      0|            return 0;
  909|  7.08k|    }
  910|  7.08k|}
roaring.c:container_and_cardinality:
  814|  28.3k|                                            uint8_t type2) {
  815|  28.3k|    c1 = container_unwrap_shared(c1, &type1);
  816|  28.3k|    c2 = container_unwrap_shared(c2, &type2);
  817|  28.3k|    switch (PAIR_CONTAINER_TYPES(type1, type2)) {
  ------------------
  |  |   62|  28.3k|#define PAIR_CONTAINER_TYPES(type1, type2) (4 * (type1) + (type2))
  ------------------
  818|      0|        case CONTAINER_PAIR(BITSET, BITSET):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (818:9): [True: 0, False: 28.3k]
  ------------------
  819|      0|            return bitset_container_and_justcard(const_CAST_bitset(c1),
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  820|      0|                                                 const_CAST_bitset(c2));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  821|       |
  822|  13.8k|        case CONTAINER_PAIR(ARRAY, ARRAY):
  ------------------
  |  |   65|  13.8k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  13.8k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  13.8k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (822:9): [True: 13.8k, False: 14.5k]
  ------------------
  823|  13.8k|            return array_container_intersection_cardinality(
  824|  13.8k|                const_CAST_array(c1), const_CAST_array(c2));
  ------------------
  |  |   55|  13.8k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  13.8k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_array(c2));
  ------------------
  |  |   55|  13.8k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  13.8k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  825|       |
  826|  2.84k|        case CONTAINER_PAIR(RUN, RUN):
  ------------------
  |  |   65|  2.84k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  2.84k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  2.84k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (826:9): [True: 2.84k, False: 25.5k]
  ------------------
  827|  2.84k|            return run_container_intersection_cardinality(const_CAST_run(c1),
  ------------------
  |  |   78|  2.84k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.84k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  828|  2.84k|                                                          const_CAST_run(c2));
  ------------------
  |  |   78|  2.84k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.84k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  829|       |
  830|      0|        case CONTAINER_PAIR(BITSET, ARRAY):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|      0|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (830:9): [True: 0, False: 28.3k]
  ------------------
  831|      0|            return array_bitset_container_intersection_cardinality(
  832|      0|                const_CAST_array(c2), const_CAST_bitset(c1));
  ------------------
  |  |   55|      0|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c2), const_CAST_bitset(c1));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  833|       |
  834|  2.27k|        case CONTAINER_PAIR(ARRAY, BITSET):
  ------------------
  |  |   65|  2.27k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  2.27k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|  2.27k|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (834:9): [True: 2.27k, False: 26.0k]
  ------------------
  835|  2.27k|            return array_bitset_container_intersection_cardinality(
  836|  2.27k|                const_CAST_array(c1), const_CAST_bitset(c2));
  ------------------
  |  |   55|  2.27k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.27k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_bitset(c2));
  ------------------
  |  |   53|  2.27k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.27k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  837|       |
  838|      0|        case CONTAINER_PAIR(BITSET, RUN):
  ------------------
  |  |   65|      0|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (838:9): [True: 0, False: 28.3k]
  ------------------
  839|      0|            return run_bitset_container_intersection_cardinality(
  840|      0|                const_CAST_run(c2), const_CAST_bitset(c1));
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_run(c2), const_CAST_bitset(c1));
  ------------------
  |  |   53|      0|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  841|       |
  842|  2.37k|        case CONTAINER_PAIR(RUN, BITSET):
  ------------------
  |  |   65|  2.37k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  2.37k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   48|  2.37k|#define BITSET_CONTAINER_TYPE 1
  |  |  ------------------
  ------------------
  |  Branch (842:9): [True: 2.37k, False: 25.9k]
  ------------------
  843|  2.37k|            return run_bitset_container_intersection_cardinality(
  844|  2.37k|                const_CAST_run(c1), const_CAST_bitset(c2));
  ------------------
  |  |   78|  2.37k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.37k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_run(c1), const_CAST_bitset(c2));
  ------------------
  |  |   53|  2.37k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.37k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  845|       |
  846|  2.65k|        case CONTAINER_PAIR(ARRAY, RUN):
  ------------------
  |  |   65|  2.65k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  2.65k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  2.65k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  ------------------
  |  Branch (846:9): [True: 2.65k, False: 25.7k]
  ------------------
  847|  2.65k|            return array_run_container_intersection_cardinality(
  848|  2.65k|                const_CAST_array(c1), const_CAST_run(c2));
  ------------------
  |  |   55|  2.65k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.65k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c1), const_CAST_run(c2));
  ------------------
  |  |   78|  2.65k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.65k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  849|       |
  850|  4.39k|        case CONTAINER_PAIR(RUN, ARRAY):
  ------------------
  |  |   65|  4.39k|    (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   50|  4.39k|#define RUN_CONTAINER_TYPE 3
  |  |  ------------------
  |  |                   (4 * (name1##_CONTAINER_TYPE) + (name2##_CONTAINER_TYPE))
  |  |  ------------------
  |  |  |  |   49|  4.39k|#define ARRAY_CONTAINER_TYPE 2
  |  |  ------------------
  ------------------
  |  Branch (850:9): [True: 4.39k, False: 23.9k]
  ------------------
  851|  4.39k|            return array_run_container_intersection_cardinality(
  852|  4.39k|                const_CAST_array(c2), const_CAST_run(c1));
  ------------------
  |  |   55|  4.39k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  4.39k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
                              const_CAST_array(c2), const_CAST_run(c1));
  ------------------
  |  |   78|  4.39k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  4.39k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  853|       |
  854|      0|        default:
  ------------------
  |  Branch (854:9): [True: 0, False: 28.3k]
  ------------------
  855|      0|            assert(false);
  856|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  857|      0|            return 0;
  858|  28.3k|    }
  859|  28.3k|}
roaring.c:container_contains_range:
  596|    454|) {
  597|    454|    c = container_unwrap_shared(c, &typecode);
  598|    454|    switch (typecode) {
  599|    237|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|    237|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (599:9): [True: 237, False: 217]
  ------------------
  600|    237|            return bitset_container_get_range(const_CAST_bitset(c), range_start,
  ------------------
  |  |   53|    237|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    237|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  601|    237|                                              range_end);
  602|     69|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|     69|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (602:9): [True: 69, False: 385]
  ------------------
  603|     69|            return array_container_contains_range(const_CAST_array(c),
  ------------------
  |  |   55|     69|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|     69|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  604|     69|                                                  range_start, range_end);
  605|    148|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|    148|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (605:9): [True: 148, False: 306]
  ------------------
  606|    148|            return run_container_contains_range(const_CAST_run(c), range_start,
  ------------------
  |  |   78|    148|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    148|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  607|    148|                                                range_end);
  608|      0|        default:
  ------------------
  |  Branch (608:9): [True: 0, False: 454]
  ------------------
  609|      0|            assert(false);
  610|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  611|      0|            return false;
  612|    454|    }
  613|    454|}
roaring_array.c:container_to_uint32_array:
  465|  62.1k|                                            uint8_t typecode, uint32_t base) {
  466|  62.1k|    c = container_unwrap_shared(c, &typecode);
  467|  62.1k|    switch (typecode) {
  ------------------
  |  Branch (467:13): [True: 62.1k, False: 0]
  ------------------
  468|  1.40k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|  1.40k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (468:9): [True: 1.40k, False: 60.7k]
  ------------------
  469|  1.40k|            return bitset_container_to_uint32_array(output,
  470|  1.40k|                                                    const_CAST_bitset(c), base);
  ------------------
  |  |   53|  1.40k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.40k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  471|  6.59k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  6.59k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (471:9): [True: 6.59k, False: 55.5k]
  ------------------
  472|  6.59k|            return array_container_to_uint32_array(output, const_CAST_array(c),
  ------------------
  |  |   55|  6.59k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  6.59k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  473|  6.59k|                                                   base);
  474|  54.1k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  54.1k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (474:9): [True: 54.1k, False: 8.00k]
  ------------------
  475|  54.1k|            return run_container_to_uint32_array(output, const_CAST_run(c),
  ------------------
  |  |   78|  54.1k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  54.1k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  476|  54.1k|                                                 base);
  477|  62.1k|    }
  478|  62.1k|    assert(false);
  479|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  480|      0|    return 0;  // unreached
  481|  62.1k|}
roaring_array.c:container_unwrap_shared:
  106|   365k|    const container_t *candidate_shared_container, uint8_t *type) {
  107|   365k|    if (*type == SHARED_CONTAINER_TYPE) {
  ------------------
  |  |   51|   365k|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (107:9): [True: 0, False: 365k]
  ------------------
  108|      0|        *type = const_CAST_shared(candidate_shared_container)->typecode;
  ------------------
  |  |   80|      0|#define const_CAST_shared(c) CAST(const shared_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  109|      0|        assert(*type != SHARED_CONTAINER_TYPE);
  110|      0|        return const_CAST_shared(candidate_shared_container)->container;
  ------------------
  |  |   80|      0|#define const_CAST_shared(c) CAST(const shared_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  111|   365k|    } else {
  112|   365k|        return candidate_shared_container;
  113|   365k|    }
  114|   365k|}
roaring_array.c:get_container_type:
  129|   155k|static inline uint8_t get_container_type(const container_t *c, uint8_t type) {
  130|   155k|    if (type == SHARED_CONTAINER_TYPE) {
  ------------------
  |  |   51|   155k|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (130:9): [True: 0, False: 155k]
  ------------------
  131|      0|        return const_CAST_shared(c)->typecode;
  ------------------
  |  |   80|      0|#define const_CAST_shared(c) CAST(const shared_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  132|   155k|    } else {
  133|   155k|        return type;
  134|   155k|    }
  135|   155k|}
roaring_array.c:container_size_in_bytes:
  403|   155k|                                              uint8_t typecode) {
  404|   155k|    c = container_unwrap_shared(c, &typecode);
  405|   155k|    switch (typecode) {
  ------------------
  |  Branch (405:13): [True: 155k, False: 0]
  ------------------
  406|   132k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|   132k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (406:9): [True: 132k, False: 22.5k]
  ------------------
  407|   132k|            return bitset_container_size_in_bytes(const_CAST_bitset(c));
  ------------------
  |  |   53|   132k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|   132k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  408|  20.0k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  20.0k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (408:9): [True: 20.0k, False: 135k]
  ------------------
  409|  20.0k|            return array_container_size_in_bytes(const_CAST_array(c));
  ------------------
  |  |   55|  20.0k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  20.0k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  410|  2.41k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|  2.41k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (410:9): [True: 2.41k, False: 152k]
  ------------------
  411|  2.41k|            return run_container_size_in_bytes(const_CAST_run(c));
  ------------------
  |  |   78|  2.41k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  2.41k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  412|   155k|    }
  413|   155k|    assert(false);
  414|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  415|      0|    return 0;  // unreached
  416|   155k|}
roaring_array.c:container_get_cardinality:
  244|  73.9k|                                            uint8_t typecode) {
  245|  73.9k|    c = container_unwrap_shared(c, &typecode);
  246|  73.9k|    switch (typecode) {
  ------------------
  |  Branch (246:13): [True: 73.9k, False: 0]
  ------------------
  247|  66.2k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|  66.2k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (247:9): [True: 66.2k, False: 7.66k]
  ------------------
  248|  66.2k|            return bitset_container_cardinality(const_CAST_bitset(c));
  ------------------
  |  |   53|  66.2k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  66.2k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  249|  7.66k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  7.66k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (249:9): [True: 7.66k, False: 66.2k]
  ------------------
  250|  7.66k|            return array_container_cardinality(const_CAST_array(c));
  ------------------
  |  |   55|  7.66k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  7.66k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  251|      0|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (251:9): [True: 0, False: 73.9k]
  ------------------
  252|      0|            return run_container_cardinality(const_CAST_run(c));
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  253|  73.9k|    }
  254|  73.9k|    assert(false);
  255|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  256|      0|    return 0;  // unreached
  257|  73.9k|}
roaring_array.c:container_write:
  382|  73.9k|                                      char *buf) {
  383|  73.9k|    c = container_unwrap_shared(c, &typecode);
  384|  73.9k|    switch (typecode) {
  ------------------
  |  Branch (384:13): [True: 73.9k, False: 0]
  ------------------
  385|  66.2k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|  66.2k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (385:9): [True: 66.2k, False: 7.66k]
  ------------------
  386|  66.2k|            return bitset_container_write(const_CAST_bitset(c), buf);
  ------------------
  |  |   53|  66.2k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  66.2k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  387|  7.66k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  7.66k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (387:9): [True: 7.66k, False: 66.2k]
  ------------------
  388|  7.66k|            return array_container_write(const_CAST_array(c), buf);
  ------------------
  |  |   55|  7.66k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  7.66k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  389|      0|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (389:9): [True: 0, False: 73.9k]
  ------------------
  390|      0|            return run_container_write(const_CAST_run(c), buf);
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  391|  73.9k|    }
  392|  73.9k|    assert(false);
  393|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  394|      0|    return 0;  // unreached
  395|  73.9k|}
containers.c:container_unwrap_shared:
  106|  7.29k|    const container_t *candidate_shared_container, uint8_t *type) {
  107|  7.29k|    if (*type == SHARED_CONTAINER_TYPE) {
  ------------------
  |  |   51|  7.29k|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (107:9): [True: 0, False: 7.29k]
  ------------------
  108|      0|        *type = const_CAST_shared(candidate_shared_container)->typecode;
  ------------------
  |  |   80|      0|#define const_CAST_shared(c) CAST(const shared_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  109|      0|        assert(*type != SHARED_CONTAINER_TYPE);
  110|      0|        return const_CAST_shared(candidate_shared_container)->container;
  ------------------
  |  |   80|      0|#define const_CAST_shared(c) CAST(const shared_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  111|  7.29k|    } else {
  112|  7.29k|        return candidate_shared_container;
  113|  7.29k|    }
  114|  7.29k|}
containers.c:container_maximum:
 2165|  7.09k|static inline uint16_t container_maximum(const container_t *c, uint8_t type) {
 2166|  7.09k|    c = container_unwrap_shared(c, &type);
 2167|  7.09k|    switch (type) {
 2168|  1.78k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|  1.78k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (2168:9): [True: 1.78k, False: 5.31k]
  ------------------
 2169|  1.78k|            return bitset_container_maximum(const_CAST_bitset(c));
  ------------------
  |  |   53|  1.78k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.78k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2170|  5.31k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  5.31k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (2170:9): [True: 5.31k, False: 1.78k]
  ------------------
 2171|  5.31k|            return array_container_maximum(const_CAST_array(c));
  ------------------
  |  |   55|  5.31k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  5.31k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2172|      0|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (2172:9): [True: 0, False: 7.09k]
  ------------------
 2173|      0|            return run_container_maximum(const_CAST_run(c));
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 2174|      0|        default:
  ------------------
  |  Branch (2174:9): [True: 0, False: 7.09k]
  ------------------
 2175|      0|            assert(false);
 2176|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2177|  7.09k|    }
 2178|  7.09k|    assert(false);
 2179|      0|    roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
 2180|      0|    return false;
 2181|  7.09k|}

run_container_contains:
  262|  9.12k|inline bool run_container_contains(const run_container_t *run, uint16_t pos) {
  263|  9.12k|    int32_t index = interleavedBinarySearch(run->runs, run->n_runs, pos);
  264|  9.12k|    if (index >= 0) return true;
  ------------------
  |  Branch (264:9): [True: 6.70k, False: 2.41k]
  ------------------
  265|  2.41k|    index = -index - 2;  // points to preceding value, possibly -1
  266|  2.41k|    if (index != -1) {   // possible match
  ------------------
  |  Branch (266:9): [True: 774, False: 1.64k]
  ------------------
  267|    774|        int32_t offset = pos - run->runs[index].value;
  268|    774|        int32_t le = run->runs[index].length;
  269|    774|        if (offset <= le) return true;
  ------------------
  |  Branch (269:13): [True: 535, False: 239]
  ------------------
  270|    774|    }
  271|  1.88k|    return false;
  272|  2.41k|}
interleavedBinarySearch:
  113|   396k|                                       uint16_t ikey) {
  114|   396k|    int32_t low = 0;
  115|   396k|    int32_t high = lenarray - 1;
  116|  1.79M|    while (low <= high) {
  ------------------
  |  Branch (116:12): [True: 1.59M, False: 203k]
  ------------------
  117|  1.59M|        int32_t middleIndex = (low + high) >> 1;
  118|  1.59M|        uint16_t middleValue = array[middleIndex].value;
  119|  1.59M|        if (middleValue < ikey) {
  ------------------
  |  Branch (119:13): [True: 583k, False: 1.01M]
  ------------------
  120|   583k|            low = middleIndex + 1;
  121|  1.01M|        } else if (middleValue > ikey) {
  ------------------
  |  Branch (121:20): [True: 818k, False: 193k]
  ------------------
  122|   818k|            high = middleIndex - 1;
  123|   818k|        } else {
  124|   193k|            return middleIndex;
  125|   193k|        }
  126|  1.59M|    }
  127|   203k|    return -(low + 1);
  128|   396k|}
run_container_minimum:
  606|  16.3k|inline uint16_t run_container_minimum(const run_container_t *run) {
  607|  16.3k|    if (run->n_runs == 0) return 0;
  ------------------
  |  Branch (607:9): [True: 0, False: 16.3k]
  ------------------
  608|  16.3k|    return run->runs[0].value;
  609|  16.3k|}
run_container_maximum:
  613|  15.9k|inline uint16_t run_container_maximum(const run_container_t *run) {
  614|  15.9k|    if (run->n_runs == 0) return 0;
  ------------------
  |  Branch (614:9): [True: 0, False: 15.9k]
  ------------------
  615|  15.9k|    return run->runs[run->n_runs - 1].value + run->runs[run->n_runs - 1].length;
  616|  15.9k|}
roaring.c:run_container_create_range:
  575|  83.9k|                                                          uint32_t stop) {
  576|  83.9k|    run_container_t *rc = run_container_create_given_capacity(1);
  577|  83.9k|    if (rc) {
  ------------------
  |  Branch (577:9): [True: 83.9k, False: 0]
  ------------------
  578|  83.9k|        rle16_t r;
  579|  83.9k|        r.value = (uint16_t)start;
  580|  83.9k|        r.length = (uint16_t)(stop - start - 1);
  581|  83.9k|        run_container_append_first(rc, r);
  582|  83.9k|    }
  583|  83.9k|    return rc;
  584|  83.9k|}
roaring.c:run_container_append_first:
  354|  83.9k|                                                 rle16_t vl) {
  355|  83.9k|    run->runs[run->n_runs] = vl;
  356|  83.9k|    run->n_runs++;
  357|  83.9k|    return vl;
  358|  83.9k|}
roaring.c:rle16_count_greater:
  179|    413|                                          int32_t lenarray, uint16_t key) {
  180|    413|    if (lenarray == 0) return 0;
  ------------------
  |  Branch (180:9): [True: 0, False: 413]
  ------------------
  181|    413|    int32_t low = 0;
  182|    413|    int32_t high = lenarray - 1;
  183|  3.08k|    while (low <= high) {
  ------------------
  |  Branch (183:12): [True: 2.70k, False: 381]
  ------------------
  184|  2.70k|        int32_t middleIndex = (low + high) >> 1;
  185|  2.70k|        uint16_t min_value = array[middleIndex].value;
  186|  2.70k|        uint16_t max_value =
  187|  2.70k|            array[middleIndex].value + array[middleIndex].length;
  188|  2.70k|        if (max_value < key) {
  ------------------
  |  Branch (188:13): [True: 2.50k, False: 202]
  ------------------
  189|  2.50k|            low = middleIndex + 1;
  190|  2.50k|        } else if (key + UINT32_C(1) < min_value) {  // uint32 arithmetic
  ------------------
  |  Branch (190:20): [True: 170, False: 32]
  ------------------
  191|    170|            high = middleIndex - 1;
  192|    170|        } else {
  193|     32|            return lenarray - (middleIndex + 1);
  194|     32|        }
  195|  2.70k|    }
  196|    381|    return lenarray - low;
  197|    413|}
roaring.c:rle16_count_less:
  158|    413|                                       uint16_t key) {
  159|    413|    if (lenarray == 0) return 0;
  ------------------
  |  Branch (159:9): [True: 2, False: 411]
  ------------------
  160|    411|    int32_t low = 0;
  161|    411|    int32_t high = lenarray - 1;
  162|  2.59k|    while (low <= high) {
  ------------------
  |  Branch (162:12): [True: 2.40k, False: 196]
  ------------------
  163|  2.40k|        int32_t middleIndex = (low + high) >> 1;
  164|  2.40k|        uint16_t min_value = array[middleIndex].value;
  165|  2.40k|        uint16_t max_value =
  166|  2.40k|            array[middleIndex].value + array[middleIndex].length;
  167|  2.40k|        if (max_value + UINT32_C(1) < key) {  // uint32 arithmetic
  ------------------
  |  Branch (167:13): [True: 1.19k, False: 1.21k]
  ------------------
  168|  1.19k|            low = middleIndex + 1;
  169|  1.21k|        } else if (key < min_value) {
  ------------------
  |  Branch (169:20): [True: 995, False: 215]
  ------------------
  170|    995|            high = middleIndex - 1;
  171|    995|        } else {
  172|    215|            return middleIndex;
  173|    215|        }
  174|  2.40k|    }
  175|    196|    return low;
  176|    411|}
roaring.c:run_container_add_range_nruns:
  654|    413|                                                 int32_t nruns_greater) {
  655|    413|    int32_t nruns_common = run->n_runs - nruns_less - nruns_greater;
  656|    413|    if (nruns_common == 0) {
  ------------------
  |  Branch (656:9): [True: 122, False: 291]
  ------------------
  657|    122|        makeRoomAtIndex(run, (uint16_t)nruns_less);
  658|    122|        run->runs[nruns_less].value = (uint16_t)min;
  659|    122|        run->runs[nruns_less].length = (uint16_t)(max - min);
  660|    291|    } else {
  661|    291|        uint32_t common_min = run->runs[nruns_less].value;
  662|    291|        uint32_t common_max = run->runs[nruns_less + nruns_common - 1].value +
  663|    291|                              run->runs[nruns_less + nruns_common - 1].length;
  664|    291|        uint32_t result_min = (common_min < min) ? common_min : min;
  ------------------
  |  Branch (664:31): [True: 71, False: 220]
  ------------------
  665|    291|        uint32_t result_max = (common_max > max) ? common_max : max;
  ------------------
  |  Branch (665:31): [True: 23, False: 268]
  ------------------
  666|       |
  667|    291|        run->runs[nruns_less].value = (uint16_t)result_min;
  668|    291|        run->runs[nruns_less].length = (uint16_t)(result_max - result_min);
  669|       |
  670|    291|        memmove(&(run->runs[nruns_less + 1]),
  671|    291|                &(run->runs[run->n_runs - nruns_greater]),
  672|    291|                nruns_greater * sizeof(rle16_t));
  673|    291|        run->n_runs = nruns_less + 1 + nruns_greater;
  674|    291|    }
  675|    413|}
roaring.c:makeRoomAtIndex:
  209|    759|static inline void makeRoomAtIndex(run_container_t *run, uint16_t index) {
  210|       |    /* This function calls realloc + memmove sequentially to move by one index.
  211|       |     * Potentially copying twice the array.
  212|       |     */
  213|    759|    if (run->n_runs + 1 > run->capacity)
  ------------------
  |  Branch (213:9): [True: 628, False: 131]
  ------------------
  214|    628|        run_container_grow(run, run->n_runs + 1, true);
  215|    759|    memmove(run->runs + 1 + index, run->runs + index,
  216|    759|            (run->n_runs - index) * sizeof(rle16_t));
  217|    759|    run->n_runs++;
  218|    759|}
roaring.c:run_container_remove_range:
  711|  1.78k|                                              uint32_t min, uint32_t max) {
  712|  1.78k|    int32_t first = rle16_find_run(run->runs, run->n_runs, (uint16_t)min);
  713|  1.78k|    int32_t last = rle16_find_run(run->runs, run->n_runs, (uint16_t)max);
  714|       |
  715|  1.78k|    if (first >= 0 && min > run->runs[first].value &&
  ------------------
  |  Branch (715:9): [True: 638, False: 1.14k]
  |  Branch (715:23): [True: 289, False: 349]
  ------------------
  716|    289|        max < ((uint32_t)run->runs[first].value +
  ------------------
  |  Branch (716:9): [True: 27, False: 262]
  ------------------
  717|    289|               (uint32_t)run->runs[first].length)) {
  718|       |        // split this run into two adjacent runs
  719|       |
  720|       |        // right subinterval
  721|     27|        makeRoomAtIndex(run, (uint16_t)(first + 1));
  722|     27|        run->runs[first + 1].value = (uint16_t)(max + 1);
  723|     27|        run->runs[first + 1].length =
  724|     27|            (uint16_t)((run->runs[first].value + run->runs[first].length) -
  725|     27|                       (max + 1));
  726|       |
  727|       |        // left subinterval
  728|     27|        run->runs[first].length =
  729|     27|            (uint16_t)((min - 1) - run->runs[first].value);
  730|       |
  731|     27|        return;
  732|     27|    }
  733|       |
  734|       |    // update left-most partial run
  735|  1.75k|    if (first >= 0) {
  ------------------
  |  Branch (735:9): [True: 611, False: 1.14k]
  ------------------
  736|    611|        if (min > run->runs[first].value) {
  ------------------
  |  Branch (736:13): [True: 262, False: 349]
  ------------------
  737|    262|            run->runs[first].length =
  738|    262|                (uint16_t)((min - 1) - run->runs[first].value);
  739|    262|            first++;
  740|    262|        }
  741|  1.14k|    } else {
  742|  1.14k|        first = -first - 1;
  743|  1.14k|    }
  744|       |
  745|       |    // update right-most run
  746|  1.75k|    if (last >= 0) {
  ------------------
  |  Branch (746:9): [True: 590, False: 1.16k]
  ------------------
  747|    590|        uint16_t run_max = run->runs[last].value + run->runs[last].length;
  748|    590|        if (run_max > max) {
  ------------------
  |  Branch (748:13): [True: 346, False: 244]
  ------------------
  749|    346|            run->runs[last].value = (uint16_t)(max + 1);
  750|    346|            run->runs[last].length = (uint16_t)(run_max - (max + 1));
  751|    346|            last--;
  752|    346|        }
  753|  1.16k|    } else {
  754|  1.16k|        last = (-last - 1) - 1;
  755|  1.16k|    }
  756|       |
  757|       |    // remove intermediate runs
  758|  1.75k|    if (first <= last) {
  ------------------
  |  Branch (758:9): [True: 156, False: 1.60k]
  ------------------
  759|    156|        run_container_shift_tail(run, run->n_runs - (last + 1),
  760|    156|                                 -(last - first + 1));
  761|    156|    }
  762|  1.75k|}
roaring.c:rle16_find_run:
  134|  3.57k|                                     uint16_t ikey) {
  135|  3.57k|    int32_t low = 0;
  136|  3.57k|    int32_t high = lenarray - 1;
  137|  14.8k|    while (low <= high) {
  ------------------
  |  Branch (137:12): [True: 12.5k, False: 2.31k]
  ------------------
  138|  12.5k|        int32_t middleIndex = (low + high) >> 1;
  139|  12.5k|        uint16_t min = array[middleIndex].value;
  140|  12.5k|        uint16_t max = array[middleIndex].value + array[middleIndex].length;
  141|  12.5k|        if (ikey > max) {
  ------------------
  |  Branch (141:13): [True: 1.63k, False: 10.9k]
  ------------------
  142|  1.63k|            low = middleIndex + 1;
  143|  10.9k|        } else if (ikey < min) {
  ------------------
  |  Branch (143:20): [True: 9.65k, False: 1.25k]
  ------------------
  144|  9.65k|            high = middleIndex - 1;
  145|  9.65k|        } else {
  146|  1.25k|            return middleIndex;
  147|  1.25k|        }
  148|  12.5k|    }
  149|  2.31k|    return -(low + 1);
  150|  3.57k|}
roaring.c:run_container_shift_tail:
  694|    156|                                            int32_t distance) {
  695|    156|    if (distance > 0) {
  ------------------
  |  Branch (695:9): [True: 0, False: 156]
  ------------------
  696|      0|        if (run->capacity < count + distance) {
  ------------------
  |  Branch (696:13): [True: 0, False: 0]
  ------------------
  697|       |            run_container_grow(run, count + distance, true);
  698|      0|        }
  699|      0|    }
  700|    156|    int32_t srcpos = run->n_runs - count;
  701|    156|    int32_t dstpos = srcpos + distance;
  702|    156|    memmove(&(run->runs[dstpos]), &(run->runs[srcpos]),
  703|    156|            sizeof(rle16_t) * count);
  704|    156|    run->n_runs += distance;
  705|    156|}
roaring.c:run_container_remove:
  224|  3.02k|static inline bool run_container_remove(run_container_t *run, uint16_t pos) {
  225|  3.02k|    int32_t index = interleavedBinarySearch(run->runs, run->n_runs, pos);
  226|  3.02k|    if (index >= 0) {
  ------------------
  |  Branch (226:9): [True: 1.19k, False: 1.83k]
  ------------------
  227|  1.19k|        int32_t le = run->runs[index].length;
  228|  1.19k|        if (le == 0) {
  ------------------
  |  Branch (228:13): [True: 247, False: 943]
  ------------------
  229|    247|            recoverRoomAtIndex(run, (uint16_t)index);
  230|    943|        } else {
  231|    943|            run->runs[index].value++;
  232|    943|            run->runs[index].length--;
  233|    943|        }
  234|  1.19k|        return true;
  235|  1.19k|    }
  236|  1.83k|    index = -index - 2;  // points to preceding value, possibly -1
  237|  1.83k|    if (index >= 0) {    // possible match
  ------------------
  |  Branch (237:9): [True: 800, False: 1.03k]
  ------------------
  238|    800|        int32_t offset = pos - run->runs[index].value;
  239|    800|        int32_t le = run->runs[index].length;
  240|    800|        if (offset < le) {
  ------------------
  |  Branch (240:13): [True: 610, False: 190]
  ------------------
  241|       |            // need to break in two
  242|    610|            run->runs[index].length = (uint16_t)(offset - 1);
  243|       |            // need to insert
  244|    610|            uint16_t newvalue = pos + 1;
  245|    610|            int32_t newlength = le - offset - 1;
  246|    610|            makeRoomAtIndex(run, (uint16_t)(index + 1));
  247|    610|            run->runs[index + 1].value = newvalue;
  248|    610|            run->runs[index + 1].length = (uint16_t)newlength;
  249|    610|            return true;
  250|       |
  251|    610|        } else if (offset == le) {
  ------------------
  |  Branch (251:20): [True: 30, False: 160]
  ------------------
  252|     30|            run->runs[index].length--;
  253|     30|            return true;
  254|     30|        }
  255|    800|    }
  256|       |    // no match
  257|  1.19k|    return false;
  258|  1.83k|}
roaring.c:recoverRoomAtIndex:
  102|    247|static inline void recoverRoomAtIndex(run_container_t *run, uint16_t index) {
  103|    247|    memmove(run->runs + index, run->runs + (1 + index),
  104|    247|            (run->n_runs - index - 1) * sizeof(rle16_t));
  105|    247|    run->n_runs--;
  106|    247|}
roaring.c:run_container_nonzero_cardinality:
  312|  59.6k|    const run_container_t *run) {
  313|  59.6k|    return run->n_runs > 0;  // runs never empty
  314|  59.6k|}
roaring.c:run_container_is_full:
  398|  5.61k|static inline bool run_container_is_full(const run_container_t *run) {
  399|  5.61k|    rle16_t vl = run->runs[0];
  400|  5.61k|    return (run->n_runs == 1) && (vl.value == 0) && (vl.length == 0xFFFF);
  ------------------
  |  Branch (400:12): [True: 997, False: 4.61k]
  |  Branch (400:34): [True: 773, False: 224]
  |  Branch (400:53): [True: 653, False: 120]
  ------------------
  401|  5.61k|}
roaring.c:run_container_equals:
  506|    126|                                        const run_container_t *container2) {
  507|    126|    if (container1->n_runs != container2->n_runs) {
  ------------------
  |  Branch (507:9): [True: 99, False: 27]
  ------------------
  508|     99|        return false;
  509|     99|    }
  510|     27|    return memequals(container1->runs, container2->runs,
  511|     27|                     container1->n_runs * sizeof(rle16_t));
  512|    126|}
roaring.c:run_container_contains_range:
  281|    148|                                                uint32_t pos_end) {
  282|    148|    uint32_t count = 0;
  283|    148|    int32_t index =
  284|    148|        interleavedBinarySearch(run->runs, run->n_runs, (uint16_t)pos_start);
  285|    148|    if (index < 0) {
  ------------------
  |  Branch (285:9): [True: 90, False: 58]
  ------------------
  286|     90|        index = -index - 2;
  287|     90|        if ((index == -1) ||
  ------------------
  |  Branch (287:13): [True: 22, False: 68]
  ------------------
  288|     68|            ((pos_start - run->runs[index].value) > run->runs[index].length)) {
  ------------------
  |  Branch (288:13): [True: 12, False: 56]
  ------------------
  289|     34|            return false;
  290|     34|        }
  291|     90|    }
  292|  2.58k|    for (int32_t i = index; i < run->n_runs; ++i) {
  ------------------
  |  Branch (292:29): [True: 2.53k, False: 59]
  ------------------
  293|  2.53k|        const uint32_t stop = run->runs[i].value + run->runs[i].length;
  294|  2.53k|        if (run->runs[i].value >= pos_end) break;
  ------------------
  |  Branch (294:13): [True: 11, False: 2.51k]
  ------------------
  295|  2.51k|        if (stop >= pos_end) {
  ------------------
  |  Branch (295:13): [True: 44, False: 2.47k]
  ------------------
  296|     44|            count += (((pos_end - run->runs[i].value) > 0)
  ------------------
  |  Branch (296:23): [True: 44, False: 0]
  ------------------
  297|     44|                          ? (pos_end - run->runs[i].value)
  298|     44|                          : 0);
  299|     44|            break;
  300|     44|        }
  301|  2.47k|        const uint32_t min = (stop - pos_start) > 0 ? (stop - pos_start) : 0;
  ------------------
  |  Branch (301:30): [True: 2.45k, False: 17]
  ------------------
  302|  2.47k|        count += (min < run->runs[i].length) ? min : run->runs[i].length;
  ------------------
  |  Branch (302:18): [True: 47, False: 2.42k]
  ------------------
  303|  2.47k|    }
  304|    114|    return count >= (pos_end - pos_start - 1);
  305|    148|}
roaring_array.c:run_container_size_in_bytes:
  497|  2.41k|    const run_container_t *container) {
  498|  2.41k|    return run_container_serialized_size_in_bytes(container->n_runs);
  499|  2.41k|}
roaring_array.c:run_container_serialized_size_in_bytes:
  460|  2.41k|static inline int32_t run_container_serialized_size_in_bytes(int32_t num_runs) {
  461|  2.41k|    return sizeof(uint16_t) +
  462|  2.41k|           sizeof(rle16_t) * num_runs;  // each run requires 2 2-byte entries.
  463|  2.41k|}
convert.c:run_container_serialized_size_in_bytes:
  460|   139k|static inline int32_t run_container_serialized_size_in_bytes(int32_t num_runs) {
  461|   139k|    return sizeof(uint16_t) +
  462|   139k|           sizeof(rle16_t) * num_runs;  // each run requires 2 2-byte entries.
  463|   139k|}
mixed_intersection.c:run_container_is_full:
  398|  15.1k|static inline bool run_container_is_full(const run_container_t *run) {
  399|  15.1k|    rle16_t vl = run->runs[0];
  400|  15.1k|    return (run->n_runs == 1) && (vl.value == 0) && (vl.length == 0xFFFF);
  ------------------
  |  Branch (400:12): [True: 1.28k, False: 13.9k]
  |  Branch (400:34): [True: 510, False: 778]
  |  Branch (400:53): [True: 96, False: 414]
  ------------------
  401|  15.1k|}
mixed_union.c:run_container_is_full:
  398|  2.56k|static inline bool run_container_is_full(const run_container_t *run) {
  399|  2.56k|    rle16_t vl = run->runs[0];
  400|  2.56k|    return (run->n_runs == 1) && (vl.value == 0) && (vl.length == 0xFFFF);
  ------------------
  |  Branch (400:12): [True: 312, False: 2.25k]
  |  Branch (400:34): [True: 181, False: 131]
  |  Branch (400:53): [True: 67, False: 114]
  ------------------
  401|  2.56k|}
mixed_union.c:run_container_append_first:
  354|  1.88k|                                                 rle16_t vl) {
  355|  1.88k|    run->runs[run->n_runs] = vl;
  356|  1.88k|    run->n_runs++;
  357|  1.88k|    return vl;
  358|  1.88k|}
mixed_union.c:run_container_append_value_first:
  388|    613|                                                       uint16_t val) {
  389|    613|    rle16_t newrle = CROARING_MAKE_RLE16(val, 0);
  ------------------
  |  |   60|    613|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  390|    613|    run->runs[run->n_runs] = newrle;
  391|    613|    run->n_runs++;
  392|    613|    return newrle;
  393|    613|}
mixed_union.c:run_container_append:
  335|   141k|                                        rle16_t *previousrl) {
  336|   141k|    const uint32_t previousend = previousrl->value + previousrl->length;
  337|   141k|    if (vl.value > previousend + 1) {  // we add a new one
  ------------------
  |  Branch (337:9): [True: 130k, False: 10.3k]
  ------------------
  338|   130k|        run->runs[run->n_runs] = vl;
  339|   130k|        run->n_runs++;
  340|   130k|        *previousrl = vl;
  341|   130k|    } else {
  342|  10.3k|        uint32_t newend = vl.value + vl.length + UINT32_C(1);
  343|  10.3k|        if (newend > previousend) {  // we merge
  ------------------
  |  Branch (343:13): [True: 10.3k, False: 0]
  ------------------
  344|  10.3k|            previousrl->length = (uint16_t)(newend - 1 - previousrl->value);
  345|  10.3k|            run->runs[run->n_runs - 1] = *previousrl;
  346|  10.3k|        }
  347|  10.3k|    }
  348|   141k|}
mixed_union.c:run_container_append_value:
  371|   421k|                                              rle16_t *previousrl) {
  372|   421k|    const uint32_t previousend = previousrl->value + previousrl->length;
  373|   421k|    if (val > previousend + 1) {  // we add a new one
  ------------------
  |  Branch (373:9): [True: 47.3k, False: 374k]
  ------------------
  374|  47.3k|        *previousrl = CROARING_MAKE_RLE16(val, 0);
  ------------------
  |  |   60|  47.3k|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  375|  47.3k|        run->runs[run->n_runs] = *previousrl;
  376|  47.3k|        run->n_runs++;
  377|   374k|    } else if (val == previousend + 1) {  // we merge
  ------------------
  |  Branch (377:16): [True: 133k, False: 241k]
  ------------------
  378|   133k|        previousrl->length++;
  379|   133k|        run->runs[run->n_runs - 1] = *previousrl;
  380|   133k|    }
  381|   421k|}
mixed_negation.c:run_container_serialized_size_in_bytes:
  460|    346|static inline int32_t run_container_serialized_size_in_bytes(int32_t num_runs) {
  461|    346|    return sizeof(uint16_t) +
  462|    346|           sizeof(rle16_t) * num_runs;  // each run requires 2 2-byte entries.
  463|    346|}
run.c:run_container_is_full:
  398|   120k|static inline bool run_container_is_full(const run_container_t *run) {
  399|   120k|    rle16_t vl = run->runs[0];
  400|   120k|    return (run->n_runs == 1) && (vl.value == 0) && (vl.length == 0xFFFF);
  ------------------
  |  Branch (400:12): [True: 106k, False: 14.6k]
  |  Branch (400:34): [True: 104k, False: 1.55k]
  |  Branch (400:53): [True: 102k, False: 2.12k]
  ------------------
  401|   120k|}
run.c:run_container_serialized_size_in_bytes:
  460|     67|static inline int32_t run_container_serialized_size_in_bytes(int32_t num_runs) {
  461|     67|    return sizeof(uint16_t) +
  462|     67|           sizeof(rle16_t) * num_runs;  // each run requires 2 2-byte entries.
  463|     67|}
run.c:recoverRoomAtIndex:
  102|  6.07k|static inline void recoverRoomAtIndex(run_container_t *run, uint16_t index) {
  103|  6.07k|    memmove(run->runs + index, run->runs + (1 + index),
  104|  6.07k|            (run->n_runs - index - 1) * sizeof(rle16_t));
  105|  6.07k|    run->n_runs--;
  106|  6.07k|}
run.c:makeRoomAtIndex:
  209|  41.3k|static inline void makeRoomAtIndex(run_container_t *run, uint16_t index) {
  210|       |    /* This function calls realloc + memmove sequentially to move by one index.
  211|       |     * Potentially copying twice the array.
  212|       |     */
  213|  41.3k|    if (run->n_runs + 1 > run->capacity)
  ------------------
  |  Branch (213:9): [True: 2.54k, False: 38.8k]
  ------------------
  214|  2.54k|        run_container_grow(run, run->n_runs + 1, true);
  215|  41.3k|    memmove(run->runs + 1 + index, run->runs + index,
  216|  41.3k|            (run->n_runs - index) * sizeof(rle16_t));
  217|  41.3k|    run->n_runs++;
  218|  41.3k|}
run.c:run_container_append_first:
  354|  2.23k|                                                 rle16_t vl) {
  355|  2.23k|    run->runs[run->n_runs] = vl;
  356|  2.23k|    run->n_runs++;
  357|  2.23k|    return vl;
  358|  2.23k|}
run.c:run_container_append:
  335|   276k|                                        rle16_t *previousrl) {
  336|   276k|    const uint32_t previousend = previousrl->value + previousrl->length;
  337|   276k|    if (vl.value > previousend + 1) {  // we add a new one
  ------------------
  |  Branch (337:9): [True: 142k, False: 133k]
  ------------------
  338|   142k|        run->runs[run->n_runs] = vl;
  339|   142k|        run->n_runs++;
  340|   142k|        *previousrl = vl;
  341|   142k|    } else {
  342|   133k|        uint32_t newend = vl.value + vl.length + UINT32_C(1);
  343|   133k|        if (newend > previousend) {  // we merge
  ------------------
  |  Branch (343:13): [True: 103k, False: 30.6k]
  ------------------
  344|   103k|            previousrl->length = (uint16_t)(newend - 1 - previousrl->value);
  345|   103k|            run->runs[run->n_runs - 1] = *previousrl;
  346|   103k|        }
  347|   133k|    }
  348|   276k|}
run.c:run_append_exclusive:
  526|   366k|                                           uint16_t start, uint16_t length) {
  527|   366k|    rle16_t *last_run = n_runs ? runs + (n_runs - 1) : NULL;
  ------------------
  |  Branch (527:25): [True: 298k, False: 67.5k]
  ------------------
  528|   366k|    const int old_end = n_runs ? last_run->value + last_run->length + 1 : -1;
  ------------------
  |  Branch (528:25): [True: 298k, False: 67.5k]
  ------------------
  529|   366k|    if (start > old_end) {
  ------------------
  |  Branch (529:9): [True: 232k, False: 134k]
  ------------------
  530|   232k|        runs[n_runs] = CROARING_MAKE_RLE16(start, length);
  ------------------
  |  |   60|   232k|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  531|   232k|        return n_runs + 1;
  532|   232k|    }
  533|   134k|    if (start == old_end) {  // we merge
  ------------------
  |  Branch (533:9): [True: 3.45k, False: 130k]
  ------------------
  534|  3.45k|        last_run->length += length + 1;
  535|  3.45k|        return n_runs;
  536|  3.45k|    }
  537|   130k|    const int new_end = start + length + 1;
  538|   130k|    if (start == last_run->value) {  // wipe out previous
  ------------------
  |  Branch (538:9): [True: 104k, False: 26.5k]
  ------------------
  539|   104k|        if (new_end < old_end) {
  ------------------
  |  Branch (539:13): [True: 6.36k, False: 97.8k]
  ------------------
  540|  6.36k|            *last_run = CROARING_MAKE_RLE16(new_end, old_end - new_end - 1);
  ------------------
  |  |   60|  6.36k|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  541|  97.8k|        } else if (new_end > old_end) {
  ------------------
  |  Branch (541:20): [True: 2.24k, False: 95.5k]
  ------------------
  542|  2.24k|            *last_run = CROARING_MAKE_RLE16(old_end, new_end - old_end - 1);
  ------------------
  |  |   60|  2.24k|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  543|  95.5k|        } else {
  544|  95.5k|            return n_runs - 1;
  545|  95.5k|        }
  546|  8.60k|        return n_runs;
  547|   104k|    }
  548|  26.5k|    last_run->length = start - last_run->value - 1;
  549|  26.5k|    if (new_end < old_end) {
  ------------------
  |  Branch (549:9): [True: 20.6k, False: 5.88k]
  ------------------
  550|  20.6k|        runs[n_runs] = CROARING_MAKE_RLE16(new_end, old_end - new_end - 1);
  ------------------
  |  |   60|  20.6k|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  551|  20.6k|        return n_runs + 1;
  552|  20.6k|    } else if (new_end > old_end) {
  ------------------
  |  Branch (552:16): [True: 1.02k, False: 4.86k]
  ------------------
  553|  1.02k|        runs[n_runs] = CROARING_MAKE_RLE16(old_end, new_end - old_end - 1);
  ------------------
  |  |   60|  1.02k|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  554|  1.02k|        return n_runs + 1;
  555|  1.02k|    }
  556|  4.86k|    return n_runs;
  557|  26.5k|}
run.c:run_container_empty:
  317|     10|static inline bool run_container_empty(const run_container_t *run) {
  318|     10|    return run->n_runs == 0;  // runs never empty
  319|     10|}
run.c:run_container_size_in_bytes:
  497|     67|    const run_container_t *container) {
  498|     67|    return run_container_serialized_size_in_bytes(container->n_runs);
  499|     67|}

roaring_trailing_zeroes:
  248|  67.1M|inline int roaring_trailing_zeroes(unsigned long long input_num) {
  249|  67.1M|    return __builtin_ctzll(input_num);
  250|  67.1M|}
roaring_leading_zeroes:
  252|  4.14k|inline int roaring_leading_zeroes(unsigned long long input_num) {
  253|  4.14k|    return __builtin_clzll(input_num);
  254|  4.14k|}
roaring.c:roaring_hamming:
  293|   193k|static inline int roaring_hamming(uint64_t x) {
  294|       |#if defined(_WIN64) && defined(CROARING_REGULAR_VISUAL_STUDIO) && \
  295|       |    CROARING_REGULAR_VISUAL_STUDIO
  296|       |#ifdef CROARING_USENEON
  297|       |    return vaddv_u8(vcnt_u8(vcreate_u8(input_num)));
  298|       |#elif defined(_M_ARM64)
  299|       |    return roaring_hamming_backup(x);
  300|       |    // (int) _CountOneBits64(x); is unavailable
  301|       |#else   // _M_ARM64
  302|       |    return (int)__popcnt64(x);
  303|       |#endif  // _M_ARM64
  304|       |#elif defined(_WIN32) && defined(CROARING_REGULAR_VISUAL_STUDIO) && \
  305|       |    CROARING_REGULAR_VISUAL_STUDIO
  306|       |#ifdef _M_ARM
  307|       |    return roaring_hamming_backup(x);
  308|       |    // _CountOneBits is unavailable
  309|       |#else   // _M_ARM
  310|       |    return (int)__popcnt((unsigned int)x) +
  311|       |           (int)__popcnt((unsigned int)(x >> 32));
  312|       |#endif  // _M_ARM
  313|       |#else
  314|   193k|    return __builtin_popcountll(x);
  315|   193k|#endif
  316|   193k|}
mixed_intersection.c:roaring_hamming:
  293|   189k|static inline int roaring_hamming(uint64_t x) {
  294|       |#if defined(_WIN64) && defined(CROARING_REGULAR_VISUAL_STUDIO) && \
  295|       |    CROARING_REGULAR_VISUAL_STUDIO
  296|       |#ifdef CROARING_USENEON
  297|       |    return vaddv_u8(vcnt_u8(vcreate_u8(input_num)));
  298|       |#elif defined(_M_ARM64)
  299|       |    return roaring_hamming_backup(x);
  300|       |    // (int) _CountOneBits64(x); is unavailable
  301|       |#else   // _M_ARM64
  302|       |    return (int)__popcnt64(x);
  303|       |#endif  // _M_ARM64
  304|       |#elif defined(_WIN32) && defined(CROARING_REGULAR_VISUAL_STUDIO) && \
  305|       |    CROARING_REGULAR_VISUAL_STUDIO
  306|       |#ifdef _M_ARM
  307|       |    return roaring_hamming_backup(x);
  308|       |    // _CountOneBits is unavailable
  309|       |#else   // _M_ARM
  310|       |    return (int)__popcnt((unsigned int)x) +
  311|       |           (int)__popcnt((unsigned int)(x >> 32));
  312|       |#endif  // _M_ARM
  313|       |#else
  314|   189k|    return __builtin_popcountll(x);
  315|   189k|#endif
  316|   189k|}

roaring_bitmap_init_cleared:
   72|  35.9k|inline void roaring_bitmap_init_cleared(roaring_bitmap_t *r) {
   73|  35.9k|    roaring_bitmap_init_with_capacity(r, 0);
   74|  35.9k|}
roaring_bitmap_add_range:
  434|  7.18k|                                     uint64_t max) {
  435|  7.18k|    if (max <= min || min > (uint64_t)UINT32_MAX + 1) {
  ------------------
  |  Branch (435:9): [True: 4.49k, False: 2.69k]
  |  Branch (435:23): [True: 0, False: 2.69k]
  ------------------
  436|  4.49k|        return;
  437|  4.49k|    }
  438|  2.69k|    roaring_bitmap_add_range_closed(r, (uint32_t)min, (uint32_t)(max - 1));
  439|  2.69k|}
roaring_bitmap_remove_range:
  456|  7.18k|                                        uint64_t max) {
  457|  7.18k|    if (max <= min || min > (uint64_t)UINT32_MAX + 1) {
  ------------------
  |  Branch (457:9): [True: 6.28k, False: 906]
  |  Branch (457:23): [True: 0, False: 906]
  ------------------
  458|  6.28k|        return;
  459|  6.28k|    }
  460|    906|    roaring_bitmap_remove_range_closed(r, (uint32_t)min, (uint32_t)(max - 1));
  461|    906|}
roaring_bitmap_contains:
  478|  7.24k|inline bool roaring_bitmap_contains(const roaring_bitmap_t *r, uint32_t val) {
  479|       |    // For performance reasons, this function is inline and uses internal
  480|       |    // functions directly.
  481|  7.24k|#ifdef __cplusplus
  482|  7.24k|    using namespace ::roaring::internal;
  483|  7.24k|#endif
  484|  7.24k|    const uint16_t hb = val >> 16;
  485|       |    /*
  486|       |     * the next function call involves a binary search and lots of branching.
  487|       |     */
  488|  7.24k|    int32_t i = ra_get_index(&r->high_low_container, hb);
  489|  7.24k|    if (i < 0) return false;
  ------------------
  |  Branch (489:9): [True: 628, False: 6.61k]
  ------------------
  490|       |
  491|  6.61k|    uint8_t typecode;
  492|       |    // next call ought to be cheap
  493|  6.61k|    container_t *container = ra_get_container_at_index(&r->high_low_container,
  494|  6.61k|                                                       (uint16_t)i, &typecode);
  495|       |    // rest might be a tad expensive, possibly involving another round of binary
  496|       |    // search
  497|  6.61k|    return container_contains(container, val & 0xFFFF, typecode);
  498|  7.24k|}
roaring_bitmap_set_copy_on_write:
  117|  66.6k|inline void roaring_bitmap_set_copy_on_write(roaring_bitmap_t *r, bool cow) {
  118|  66.6k|    if (cow) {
  ------------------
  |  Branch (118:9): [True: 0, False: 66.6k]
  ------------------
  119|      0|        r->high_low_container.flags |= ROARING_FLAG_COW;
  ------------------
  |  |   46|      0|#define ROARING_FLAG_COW UINT8_C(0x1)
  ------------------
  120|  66.6k|    } else {
  121|  66.6k|        if (roaring_bitmap_get_copy_on_write(r)) {
  ------------------
  |  Branch (121:13): [True: 0, False: 66.6k]
  ------------------
  122|      0|            roaring_unshare_all(r);
  123|      0|        }
  124|       |        r->high_low_container.flags &= ~ROARING_FLAG_COW;
  ------------------
  |  |   46|  66.6k|#define ROARING_FLAG_COW UINT8_C(0x1)
  ------------------
  125|  66.6k|    }
  126|  66.6k|}
roaring_bitmap_get_copy_on_write:
  114|  81.0k|inline bool roaring_bitmap_get_copy_on_write(const roaring_bitmap_t *r) {
  115|       |    return r->high_low_container.flags & ROARING_FLAG_COW;
  ------------------
  |  |   46|  81.0k|#define ROARING_FLAG_COW UINT8_C(0x1)
  ------------------
  116|  81.0k|}

ra_get_index:
   93|  97.7k|inline int32_t ra_get_index(const roaring_array_t *ra, uint16_t x) {
   94|  97.7k|    if ((ra->size == 0) || ra->keys[ra->size - 1] == x) return ra->size - 1;
  ------------------
  |  Branch (94:9): [True: 14.4k, False: 83.2k]
  |  Branch (94:28): [True: 40.3k, False: 42.9k]
  ------------------
   95|  42.9k|    return binarySearch(ra->keys, (int32_t)ra->size, x);
   96|  97.7k|}
ra_get_container_at_index:
  102|   467k|                                              uint16_t i, uint8_t *typecode) {
  103|   467k|    *typecode = ra->typecodes[i];
  104|   467k|    return ra->containers[i];
  105|   467k|}
ra_get_key_at_index:
  110|   319k|inline uint16_t ra_get_key_at_index(const roaring_array_t *ra, uint16_t i) {
  111|   319k|    return ra->keys[i];
  112|   319k|}
ra_set_container_at_index:
  175|   113k|                                      container_t *c, uint8_t typecode) {
  176|       |    assert(i < ra->size);
  177|   113k|    ra->containers[i] = c;
  178|   113k|    ra->typecodes[i] = typecode;
  179|   113k|}
ra_get_size:
  191|  15.1k|inline int32_t ra_get_size(const roaring_array_t *ra) { return ra->size; }
ra_replace_key_and_container_at_index:
  205|   142k|                                                  uint8_t typecode) {
  206|   142k|    assert(i < ra->size);
  207|       |
  208|   142k|    ra->keys[i] = key;
  209|   142k|    ra->containers[i] = c;
  210|   142k|    ra->typecodes[i] = typecode;
  211|   142k|}
roaring.c:ra_advance_until:
  194|    399|                                       int32_t pos) {
  195|    399|    return advanceUntil(ra->keys, pos, ra->size, x);
  196|    399|}
roaring.c:ra_unshare_container_at_index:
  268|  69.9k|                                                 uint16_t i) {
  269|       |    assert(i < ra->size);
  270|  69.9k|    ra->containers[i] =
  271|  69.9k|        get_writable_copy_if_shared(ra->containers[i], &ra->typecodes[i]);
  272|  69.9k|}

intersect_vector16:
  387|  2.94k|                           size_t s_b, uint16_t *C) {
  388|  2.94k|    size_t count = 0;
  389|  2.94k|    size_t i_a = 0, i_b = 0;
  390|  2.94k|    const int vectorlength = sizeof(__m128i) / sizeof(uint16_t);
  391|  2.94k|    const size_t st_a = (s_a / vectorlength) * vectorlength;
  392|  2.94k|    const size_t st_b = (s_b / vectorlength) * vectorlength;
  393|  2.94k|    __m128i v_a, v_b;
  394|  2.94k|    if ((i_a < st_a) && (i_b < st_b)) {
  ------------------
  |  Branch (394:9): [True: 2.60k, False: 346]
  |  Branch (394:25): [True: 2.07k, False: 525]
  ------------------
  395|  2.07k|        v_a = _mm_lddqu_si128((__m128i *)&A[i_a]);
  396|  2.07k|        v_b = _mm_lddqu_si128((__m128i *)&B[i_b]);
  397|  5.50k|        while ((A[i_a] == 0) || (B[i_b] == 0)) {
  ------------------
  |  Branch (397:16): [True: 3.43k, False: 2.06k]
  |  Branch (397:33): [True: 196, False: 1.87k]
  ------------------
  398|  3.62k|            const __m128i res_v = _mm_cmpestrm(
  399|  3.62k|                v_b, vectorlength, v_a, vectorlength,
  400|  3.62k|                _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK);
  401|  3.62k|            const int r = _mm_extract_epi32(res_v, 0);
  402|  3.62k|            __m128i sm16 = _mm_loadu_si128((const __m128i *)shuffle_mask16 + r);
  403|  3.62k|            __m128i p = _mm_shuffle_epi8(v_a, sm16);
  404|  3.62k|            _mm_storeu_si128((__m128i *)&C[count], p);  // can overflow
  405|  3.62k|            count += _mm_popcnt_u32(r);
  406|  3.62k|            const uint16_t a_max = A[i_a + vectorlength - 1];
  407|  3.62k|            const uint16_t b_max = B[i_b + vectorlength - 1];
  408|  3.62k|            if (a_max <= b_max) {
  ------------------
  |  Branch (408:17): [True: 2.08k, False: 1.54k]
  ------------------
  409|  2.08k|                i_a += vectorlength;
  410|  2.08k|                if (i_a == st_a) break;
  ------------------
  |  Branch (410:21): [True: 164, False: 1.91k]
  ------------------
  411|  1.91k|                v_a = _mm_lddqu_si128((__m128i *)&A[i_a]);
  412|  1.91k|            }
  413|  3.46k|            if (b_max <= a_max) {
  ------------------
  |  Branch (413:17): [True: 1.65k, False: 1.81k]
  ------------------
  414|  1.65k|                i_b += vectorlength;
  415|  1.65k|                if (i_b == st_b) break;
  ------------------
  |  Branch (415:21): [True: 42, False: 1.60k]
  ------------------
  416|  1.60k|                v_b = _mm_lddqu_si128((__m128i *)&B[i_b]);
  417|  1.60k|            }
  418|  3.46k|        }
  419|  2.07k|        if ((i_a < st_a) && (i_b < st_b))
  ------------------
  |  Branch (419:13): [True: 1.91k, False: 164]
  |  Branch (419:29): [True: 1.87k, False: 42]
  ------------------
  420|  50.0k|            while (true) {
  ------------------
  |  Branch (420:20): [True: 50.0k, Folded]
  ------------------
  421|  50.0k|                const __m128i res_v = _mm_cmpistrm(
  422|  50.0k|                    v_b, v_a,
  423|  50.0k|                    _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK);
  424|  50.0k|                const int r = _mm_extract_epi32(res_v, 0);
  425|  50.0k|                __m128i sm16 =
  426|  50.0k|                    _mm_loadu_si128((const __m128i *)shuffle_mask16 + r);
  427|  50.0k|                __m128i p = _mm_shuffle_epi8(v_a, sm16);
  428|  50.0k|                _mm_storeu_si128((__m128i *)&C[count], p);  // can overflow
  429|  50.0k|                count += _mm_popcnt_u32(r);
  430|  50.0k|                const uint16_t a_max = A[i_a + vectorlength - 1];
  431|  50.0k|                const uint16_t b_max = B[i_b + vectorlength - 1];
  432|  50.0k|                if (a_max <= b_max) {
  ------------------
  |  Branch (432:21): [True: 21.8k, False: 28.1k]
  ------------------
  433|  21.8k|                    i_a += vectorlength;
  434|  21.8k|                    if (i_a == st_a) break;
  ------------------
  |  Branch (434:25): [True: 980, False: 20.8k]
  ------------------
  435|  20.8k|                    v_a = _mm_lddqu_si128((__m128i *)&A[i_a]);
  436|  20.8k|                }
  437|  49.0k|                if (b_max <= a_max) {
  ------------------
  |  Branch (437:21): [True: 29.8k, False: 19.2k]
  ------------------
  438|  29.8k|                    i_b += vectorlength;
  439|  29.8k|                    if (i_b == st_b) break;
  ------------------
  |  Branch (439:25): [True: 892, False: 28.9k]
  ------------------
  440|  28.9k|                    v_b = _mm_lddqu_si128((__m128i *)&B[i_b]);
  441|  28.9k|                }
  442|  49.0k|            }
  443|  2.07k|    }
  444|       |    // intersect the tail using scalar intersection
  445|  59.7k|    while (i_a < s_a && i_b < s_b) {
  ------------------
  |  Branch (445:12): [True: 57.6k, False: 2.14k]
  |  Branch (445:25): [True: 56.8k, False: 801]
  ------------------
  446|  56.8k|        uint16_t a = A[i_a];
  447|  56.8k|        uint16_t b = B[i_b];
  448|  56.8k|        if (a < b) {
  ------------------
  |  Branch (448:13): [True: 28.7k, False: 28.0k]
  ------------------
  449|  28.7k|            i_a++;
  450|  28.7k|        } else if (b < a) {
  ------------------
  |  Branch (450:20): [True: 18.8k, False: 9.12k]
  ------------------
  451|  18.8k|            i_b++;
  452|  18.8k|        } else {
  453|  9.12k|            C[count] = a;  //==b;
  454|  9.12k|            count++;
  455|  9.12k|            i_a++;
  456|  9.12k|            i_b++;
  457|  9.12k|        }
  458|  56.8k|    }
  459|  2.94k|    return (int32_t)count;
  460|  2.94k|}
array_container_to_uint32_array_vector16:
  465|  6.59k|                                             uint32_t base) {
  466|  6.59k|    int outpos = 0;
  467|  6.59k|    uint32_t *out = (uint32_t *)vout;
  468|  6.59k|    size_t i = 0;
  469|   198k|    for (; i + sizeof(__m128i) / sizeof(uint16_t) <= cardinality;
  ------------------
  |  Branch (469:12): [True: 191k, False: 6.59k]
  ------------------
  470|   191k|         i += sizeof(__m128i) / sizeof(uint16_t)) {
  471|   191k|        __m128i vinput = _mm_loadu_si128((const __m128i *)(array + i));
  472|   191k|        __m256i voutput = _mm256_add_epi32(_mm256_cvtepu16_epi32(vinput),
  473|   191k|                                           _mm256_set1_epi32(base));
  474|   191k|        _mm256_storeu_si256((__m256i *)(out + outpos), voutput);
  475|   191k|        outpos += sizeof(__m256i) / sizeof(uint32_t);
  476|   191k|    }
  477|  24.7k|    for (; i < cardinality; ++i) {
  ------------------
  |  Branch (477:12): [True: 18.1k, False: 6.59k]
  ------------------
  478|  18.1k|        const uint32_t val = base + array[i];
  479|  18.1k|        memcpy(out + outpos, &val,
  480|  18.1k|               sizeof(uint32_t));  // should be compiled as a MOV on x64
  481|  18.1k|        outpos++;
  482|  18.1k|    }
  483|  6.59k|    return outpos;
  484|  6.59k|}
intersect_vector16_inplace:
  488|  5.47k|                                   size_t s_b) {
  489|  5.47k|    size_t count = 0;
  490|  5.47k|    size_t i_a = 0, i_b = 0;
  491|  5.47k|    const int vectorlength = sizeof(__m128i) / sizeof(uint16_t);
  492|  5.47k|    const size_t st_a = (s_a / vectorlength) * vectorlength;
  493|  5.47k|    const size_t st_b = (s_b / vectorlength) * vectorlength;
  494|  5.47k|    __m128i v_a, v_b;
  495|  5.47k|    if ((i_a < st_a) && (i_b < st_b)) {
  ------------------
  |  Branch (495:9): [True: 3.39k, False: 2.08k]
  |  Branch (495:25): [True: 2.82k, False: 568]
  ------------------
  496|  2.82k|        v_a = _mm_lddqu_si128((__m128i *)&A[i_a]);
  497|  2.82k|        v_b = _mm_lddqu_si128((__m128i *)&B[i_b]);
  498|  2.82k|        __m128i tmp[2] = {_mm_setzero_si128()};
  499|  2.82k|        size_t tmp_count = 0;
  500|  5.47k|        while ((A[i_a] == 0) || (B[i_b] == 0)) {
  ------------------
  |  Branch (500:16): [True: 2.50k, False: 2.97k]
  |  Branch (500:33): [True: 311, False: 2.66k]
  ------------------
  501|  2.81k|            const __m128i res_v = _mm_cmpestrm(
  502|  2.81k|                v_b, vectorlength, v_a, vectorlength,
  503|  2.81k|                _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK);
  504|  2.81k|            const int r = _mm_extract_epi32(res_v, 0);
  505|  2.81k|            __m128i sm16 = _mm_loadu_si128((const __m128i *)shuffle_mask16 + r);
  506|  2.81k|            __m128i p = _mm_shuffle_epi8(v_a, sm16);
  507|  2.81k|            _mm_storeu_si128((__m128i *)&((uint16_t *)tmp)[tmp_count], p);
  508|  2.81k|            tmp_count += _mm_popcnt_u32(r);
  509|  2.81k|            const uint16_t a_max = A[i_a + vectorlength - 1];
  510|  2.81k|            const uint16_t b_max = B[i_b + vectorlength - 1];
  511|  2.81k|            if (a_max <= b_max) {
  ------------------
  |  Branch (511:17): [True: 2.65k, False: 158]
  ------------------
  512|  2.65k|                _mm_storeu_si128((__m128i *)&A[count], tmp[0]);
  513|  2.65k|                _mm_storeu_si128(tmp, _mm_setzero_si128());
  514|  2.65k|                count += tmp_count;
  515|  2.65k|                tmp_count = 0;
  516|  2.65k|                i_a += vectorlength;
  517|  2.65k|                if (i_a == st_a) break;
  ------------------
  |  Branch (517:21): [True: 146, False: 2.51k]
  ------------------
  518|  2.51k|                v_a = _mm_lddqu_si128((__m128i *)&A[i_a]);
  519|  2.51k|            }
  520|  2.67k|            if (b_max <= a_max) {
  ------------------
  |  Branch (520:17): [True: 368, False: 2.30k]
  ------------------
  521|    368|                i_b += vectorlength;
  522|    368|                if (i_b == st_b) break;
  ------------------
  |  Branch (522:21): [True: 17, False: 351]
  ------------------
  523|    351|                v_b = _mm_lddqu_si128((__m128i *)&B[i_b]);
  524|    351|            }
  525|  2.67k|        }
  526|  2.82k|        if ((i_a < st_a) && (i_b < st_b)) {
  ------------------
  |  Branch (526:13): [True: 2.68k, False: 146]
  |  Branch (526:29): [True: 2.66k, False: 17]
  ------------------
  527|   260k|            while (true) {
  ------------------
  |  Branch (527:20): [True: 260k, Folded]
  ------------------
  528|   260k|                const __m128i res_v = _mm_cmpistrm(
  529|   260k|                    v_b, v_a,
  530|   260k|                    _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK);
  531|   260k|                const int r = _mm_extract_epi32(res_v, 0);
  532|   260k|                __m128i sm16 =
  533|   260k|                    _mm_loadu_si128((const __m128i *)shuffle_mask16 + r);
  534|   260k|                __m128i p = _mm_shuffle_epi8(v_a, sm16);
  535|   260k|                _mm_storeu_si128((__m128i *)&((uint16_t *)tmp)[tmp_count], p);
  536|   260k|                tmp_count += _mm_popcnt_u32(r);
  537|   260k|                const uint16_t a_max = A[i_a + vectorlength - 1];
  538|   260k|                const uint16_t b_max = B[i_b + vectorlength - 1];
  539|   260k|                if (a_max <= b_max) {
  ------------------
  |  Branch (539:21): [True: 153k, False: 107k]
  ------------------
  540|   153k|                    _mm_storeu_si128((__m128i *)&A[count], tmp[0]);
  541|   153k|                    _mm_storeu_si128(tmp, _mm_setzero_si128());
  542|   153k|                    count += tmp_count;
  543|   153k|                    tmp_count = 0;
  544|   153k|                    i_a += vectorlength;
  545|   153k|                    if (i_a == st_a) break;
  ------------------
  |  Branch (545:25): [True: 1.33k, False: 152k]
  ------------------
  546|   152k|                    v_a = _mm_lddqu_si128((__m128i *)&A[i_a]);
  547|   152k|                }
  548|   259k|                if (b_max <= a_max) {
  ------------------
  |  Branch (548:21): [True: 146k, False: 113k]
  ------------------
  549|   146k|                    i_b += vectorlength;
  550|   146k|                    if (i_b == st_b) break;
  ------------------
  |  Branch (550:25): [True: 1.32k, False: 144k]
  ------------------
  551|   144k|                    v_b = _mm_lddqu_si128((__m128i *)&B[i_b]);
  552|   144k|                }
  553|   259k|            }
  554|  2.66k|        }
  555|       |        // tmp_count <= 8, so this does not affect efficiency so much
  556|  6.22k|        for (size_t i = 0; i < tmp_count; i++) {
  ------------------
  |  Branch (556:28): [True: 3.40k, False: 2.82k]
  ------------------
  557|  3.40k|            A[count] = ((uint16_t *)tmp)[i];
  558|  3.40k|            count++;
  559|  3.40k|        }
  560|  2.82k|        i_a += tmp_count;  // We can at least jump pass $tmp_count elements in A
  561|  2.82k|    }
  562|       |    // intersect the tail using scalar intersection
  563|  57.5k|    while (i_a < s_a && i_b < s_b) {
  ------------------
  |  Branch (563:12): [True: 52.9k, False: 4.60k]
  |  Branch (563:25): [True: 52.0k, False: 869]
  ------------------
  564|  52.0k|        uint16_t a = A[i_a];
  565|  52.0k|        uint16_t b = B[i_b];
  566|  52.0k|        if (a < b) {
  ------------------
  |  Branch (566:13): [True: 26.5k, False: 25.4k]
  ------------------
  567|  26.5k|            i_a++;
  568|  26.5k|        } else if (b < a) {
  ------------------
  |  Branch (568:20): [True: 8.90k, False: 16.5k]
  ------------------
  569|  8.90k|            i_b++;
  570|  16.5k|        } else {
  571|  16.5k|            A[count] = a;  //==b;
  572|  16.5k|            count++;
  573|  16.5k|            i_a++;
  574|  16.5k|            i_b++;
  575|  16.5k|        }
  576|  52.0k|    }
  577|  5.47k|    return (int32_t)count;
  578|  5.47k|}
intersect_vector16_cardinality:
  584|  11.7k|                                       const uint16_t *B, size_t s_b) {
  585|  11.7k|    size_t count = 0;
  586|  11.7k|    size_t i_a = 0, i_b = 0;
  587|  11.7k|    const int vectorlength = sizeof(__m128i) / sizeof(uint16_t);
  588|  11.7k|    const size_t st_a = (s_a / vectorlength) * vectorlength;
  589|  11.7k|    const size_t st_b = (s_b / vectorlength) * vectorlength;
  590|  11.7k|    __m128i v_a, v_b;
  591|  11.7k|    if ((i_a < st_a) && (i_b < st_b)) {
  ------------------
  |  Branch (591:9): [True: 10.4k, False: 1.38k]
  |  Branch (591:25): [True: 8.31k, False: 2.10k]
  ------------------
  592|  8.31k|        v_a = _mm_lddqu_si128((__m128i *)&A[i_a]);
  593|  8.31k|        v_b = _mm_lddqu_si128((__m128i *)&B[i_b]);
  594|  22.0k|        while ((A[i_a] == 0) || (B[i_b] == 0)) {
  ------------------
  |  Branch (594:16): [True: 13.7k, False: 8.27k]
  |  Branch (594:33): [True: 784, False: 7.48k]
  ------------------
  595|  14.5k|            const __m128i res_v = _mm_cmpestrm(
  596|  14.5k|                v_b, vectorlength, v_a, vectorlength,
  597|  14.5k|                _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK);
  598|  14.5k|            const int r = _mm_extract_epi32(res_v, 0);
  599|  14.5k|            count += _mm_popcnt_u32(r);
  600|  14.5k|            const uint16_t a_max = A[i_a + vectorlength - 1];
  601|  14.5k|            const uint16_t b_max = B[i_b + vectorlength - 1];
  602|  14.5k|            if (a_max <= b_max) {
  ------------------
  |  Branch (602:17): [True: 8.33k, False: 6.18k]
  ------------------
  603|  8.33k|                i_a += vectorlength;
  604|  8.33k|                if (i_a == st_a) break;
  ------------------
  |  Branch (604:21): [True: 656, False: 7.67k]
  ------------------
  605|  7.67k|                v_a = _mm_lddqu_si128((__m128i *)&A[i_a]);
  606|  7.67k|            }
  607|  13.8k|            if (b_max <= a_max) {
  ------------------
  |  Branch (607:17): [True: 6.60k, False: 7.26k]
  ------------------
  608|  6.60k|                i_b += vectorlength;
  609|  6.60k|                if (i_b == st_b) break;
  ------------------
  |  Branch (609:21): [True: 168, False: 6.43k]
  ------------------
  610|  6.43k|                v_b = _mm_lddqu_si128((__m128i *)&B[i_b]);
  611|  6.43k|            }
  612|  13.8k|        }
  613|  8.31k|        if ((i_a < st_a) && (i_b < st_b))
  ------------------
  |  Branch (613:13): [True: 7.65k, False: 656]
  |  Branch (613:29): [True: 7.48k, False: 168]
  ------------------
  614|   200k|            while (true) {
  ------------------
  |  Branch (614:20): [True: 200k, Folded]
  ------------------
  615|   200k|                const __m128i res_v = _mm_cmpistrm(
  616|   200k|                    v_b, v_a,
  617|   200k|                    _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK);
  618|   200k|                const int r = _mm_extract_epi32(res_v, 0);
  619|   200k|                count += _mm_popcnt_u32(r);
  620|   200k|                const uint16_t a_max = A[i_a + vectorlength - 1];
  621|   200k|                const uint16_t b_max = B[i_b + vectorlength - 1];
  622|   200k|                if (a_max <= b_max) {
  ------------------
  |  Branch (622:21): [True: 87.4k, False: 112k]
  ------------------
  623|  87.4k|                    i_a += vectorlength;
  624|  87.4k|                    if (i_a == st_a) break;
  ------------------
  |  Branch (624:25): [True: 3.92k, False: 83.5k]
  ------------------
  625|  83.5k|                    v_a = _mm_lddqu_si128((__m128i *)&A[i_a]);
  626|  83.5k|                }
  627|   196k|                if (b_max <= a_max) {
  ------------------
  |  Branch (627:21): [True: 119k, False: 76.9k]
  ------------------
  628|   119k|                    i_b += vectorlength;
  629|   119k|                    if (i_b == st_b) break;
  ------------------
  |  Branch (629:25): [True: 3.56k, False: 115k]
  ------------------
  630|   115k|                    v_b = _mm_lddqu_si128((__m128i *)&B[i_b]);
  631|   115k|                }
  632|   196k|            }
  633|  8.31k|    }
  634|       |    // intersect the tail using scalar intersection
  635|   239k|    while (i_a < s_a && i_b < s_b) {
  ------------------
  |  Branch (635:12): [True: 230k, False: 8.59k]
  |  Branch (635:25): [True: 227k, False: 3.20k]
  ------------------
  636|   227k|        uint16_t a = A[i_a];
  637|   227k|        uint16_t b = B[i_b];
  638|   227k|        if (a < b) {
  ------------------
  |  Branch (638:13): [True: 115k, False: 112k]
  ------------------
  639|   115k|            i_a++;
  640|   115k|        } else if (b < a) {
  ------------------
  |  Branch (640:20): [True: 75.5k, False: 36.5k]
  ------------------
  641|  75.5k|            i_b++;
  642|  75.5k|        } else {
  643|  36.5k|            count++;
  644|  36.5k|            i_a++;
  645|  36.5k|            i_b++;
  646|  36.5k|        }
  647|   227k|    }
  648|  11.7k|    return (int32_t)count;
  649|  11.7k|}
difference_vector16:
  659|  2.18k|                            size_t s_b, uint16_t *C) {
  660|       |    // we handle the degenerate case
  661|  2.18k|    if (s_a == 0) return 0;
  ------------------
  |  Branch (661:9): [True: 0, False: 2.18k]
  ------------------
  662|  2.18k|    if (s_b == 0) {
  ------------------
  |  Branch (662:9): [True: 0, False: 2.18k]
  ------------------
  663|      0|        if (A != C) memcpy(C, A, sizeof(uint16_t) * s_a);
  ------------------
  |  Branch (663:13): [True: 0, False: 0]
  ------------------
  664|      0|        return (int32_t)s_a;
  665|      0|    }
  666|       |    // handle the leading zeroes, it is messy but it allows us to use the fast
  667|       |    // _mm_cmpistrm instrinsic safely
  668|  2.18k|    int32_t count = 0;
  669|  2.18k|    if ((A[0] == 0) || (B[0] == 0)) {
  ------------------
  |  Branch (669:9): [True: 2.07k, False: 106]
  |  Branch (669:24): [True: 4, False: 102]
  ------------------
  670|  2.07k|        if ((A[0] == 0) && (B[0] == 0)) {
  ------------------
  |  Branch (670:13): [True: 2.07k, False: 4]
  |  Branch (670:28): [True: 313, False: 1.76k]
  ------------------
  671|    313|            A++;
  672|    313|            s_a--;
  673|    313|            B++;
  674|    313|            s_b--;
  675|  1.76k|        } else if (A[0] == 0) {
  ------------------
  |  Branch (675:20): [True: 1.76k, False: 4]
  ------------------
  676|  1.76k|            C[count++] = 0;
  677|  1.76k|            A++;
  678|  1.76k|            s_a--;
  679|  1.76k|        } else {
  680|      4|            B++;
  681|      4|            s_b--;
  682|      4|        }
  683|  2.07k|    }
  684|       |    // at this point, we have two non-empty arrays, made of non-zero
  685|       |    // increasing values.
  686|  2.18k|    size_t i_a = 0, i_b = 0;
  687|  2.18k|    const size_t vectorlength = sizeof(__m128i) / sizeof(uint16_t);
  688|  2.18k|    const size_t st_a = (s_a / vectorlength) * vectorlength;
  689|  2.18k|    const size_t st_b = (s_b / vectorlength) * vectorlength;
  690|  2.18k|    if ((i_a < st_a) && (i_b < st_b)) {  // this is the vectorized code path
  ------------------
  |  Branch (690:9): [True: 2.14k, False: 32]
  |  Branch (690:25): [True: 2.14k, False: 2]
  ------------------
  691|  2.14k|        __m128i v_a, v_b;                //, v_bmax;
  692|       |        // we load a vector from A and a vector from B
  693|  2.14k|        v_a = _mm_lddqu_si128((__m128i *)&A[i_a]);
  694|  2.14k|        v_b = _mm_lddqu_si128((__m128i *)&B[i_b]);
  695|       |        // we have a runningmask which indicates which values from A have been
  696|       |        // spotted in B, these don't get written out.
  697|  2.14k|        __m128i runningmask_a_found_in_b = _mm_setzero_si128();
  698|       |        /****
  699|       |         * start of the main vectorized loop
  700|       |         *****/
  701|  53.6k|        while (true) {
  ------------------
  |  Branch (701:16): [True: 53.6k, Folded]
  ------------------
  702|       |            // afoundinb will contain a mask indicate for each entry in A
  703|       |            // whether it is seen
  704|       |            // in B
  705|  53.6k|            const __m128i a_found_in_b = _mm_cmpistrm(
  706|  53.6k|                v_b, v_a,
  707|  53.6k|                _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK);
  708|  53.6k|            runningmask_a_found_in_b =
  709|  53.6k|                _mm_or_si128(runningmask_a_found_in_b, a_found_in_b);
  710|       |            // we always compare the last values of A and B
  711|  53.6k|            const uint16_t a_max = A[i_a + vectorlength - 1];
  712|  53.6k|            const uint16_t b_max = B[i_b + vectorlength - 1];
  713|  53.6k|            if (a_max <= b_max) {
  ------------------
  |  Branch (713:17): [True: 24.0k, False: 29.5k]
  ------------------
  714|       |                // Ok. In this code path, we are ready to write our v_a
  715|       |                // because there is no need to read more from B, they will
  716|       |                // all be large values.
  717|  24.0k|                const int bitmask_belongs_to_difference =
  718|  24.0k|                    _mm_extract_epi32(runningmask_a_found_in_b, 0) ^ 0xFF;
  719|       |                /*** next few lines are probably expensive *****/
  720|  24.0k|                __m128i sm16 = _mm_loadu_si128((const __m128i *)shuffle_mask16 +
  721|  24.0k|                                               bitmask_belongs_to_difference);
  722|  24.0k|                __m128i p = _mm_shuffle_epi8(v_a, sm16);
  723|  24.0k|                _mm_storeu_si128((__m128i *)&C[count], p);  // can overflow
  724|  24.0k|                count += _mm_popcnt_u32(bitmask_belongs_to_difference);
  725|       |                // we advance a
  726|  24.0k|                i_a += vectorlength;
  727|  24.0k|                if (i_a == st_a)  // no more
  ------------------
  |  Branch (727:21): [True: 1.35k, False: 22.7k]
  ------------------
  728|  1.35k|                    break;
  729|  22.7k|                runningmask_a_found_in_b = _mm_setzero_si128();
  730|  22.7k|                v_a = _mm_lddqu_si128((__m128i *)&A[i_a]);
  731|  22.7k|            }
  732|  52.3k|            if (b_max <= a_max) {
  ------------------
  |  Branch (732:17): [True: 33.1k, False: 19.1k]
  ------------------
  733|       |                // in this code path, the current v_b has become useless
  734|  33.1k|                i_b += vectorlength;
  735|  33.1k|                if (i_b == st_b) break;
  ------------------
  |  Branch (735:21): [True: 797, False: 32.3k]
  ------------------
  736|  32.3k|                v_b = _mm_lddqu_si128((__m128i *)&B[i_b]);
  737|  32.3k|            }
  738|  52.3k|        }
  739|       |        // at this point, either we have i_a == st_a, which is the end of the
  740|       |        // vectorized processing,
  741|       |        // or we have i_b == st_b,  and we are not done processing the vector...
  742|       |        // so we need to finish it off.
  743|  2.14k|        if (i_a < st_a) {        // we have unfinished business...
  ------------------
  |  Branch (743:13): [True: 797, False: 1.35k]
  ------------------
  744|    797|            uint16_t buffer[8];  // buffer to do a masked load
  745|    797|            memset(buffer, 0, 8 * sizeof(uint16_t));
  746|    797|            memcpy(buffer, B + i_b, (s_b - i_b) * sizeof(uint16_t));
  747|    797|            v_b = _mm_lddqu_si128((__m128i *)buffer);
  748|    797|            const __m128i a_found_in_b = _mm_cmpistrm(
  749|    797|                v_b, v_a,
  750|    797|                _SIDD_UWORD_OPS | _SIDD_CMP_EQUAL_ANY | _SIDD_BIT_MASK);
  751|    797|            runningmask_a_found_in_b =
  752|    797|                _mm_or_si128(runningmask_a_found_in_b, a_found_in_b);
  753|    797|            const int bitmask_belongs_to_difference =
  754|    797|                _mm_extract_epi32(runningmask_a_found_in_b, 0) ^ 0xFF;
  755|    797|            __m128i sm16 = _mm_loadu_si128((const __m128i *)shuffle_mask16 +
  756|    797|                                           bitmask_belongs_to_difference);
  757|    797|            __m128i p = _mm_shuffle_epi8(v_a, sm16);
  758|    797|            _mm_storeu_si128((__m128i *)&C[count], p);  // can overflow
  759|    797|            count += _mm_popcnt_u32(bitmask_belongs_to_difference);
  760|    797|            i_a += vectorlength;
  761|    797|        }
  762|       |        // at this point we should have i_a == st_a and i_b == st_b
  763|  2.14k|    }
  764|       |    // do the tail using scalar code
  765|  38.8k|    while (i_a < s_a && i_b < s_b) {
  ------------------
  |  Branch (765:12): [True: 37.0k, False: 1.72k]
  |  Branch (765:25): [True: 36.6k, False: 455]
  ------------------
  766|  36.6k|        uint16_t a = A[i_a];
  767|  36.6k|        uint16_t b = B[i_b];
  768|  36.6k|        if (b < a) {
  ------------------
  |  Branch (768:13): [True: 22.3k, False: 14.2k]
  ------------------
  769|  22.3k|            i_b++;
  770|  22.3k|        } else if (a < b) {
  ------------------
  |  Branch (770:20): [True: 9.29k, False: 4.96k]
  ------------------
  771|  9.29k|            C[count] = a;
  772|  9.29k|            count++;
  773|  9.29k|            i_a++;
  774|  9.29k|        } else {  //==
  775|  4.96k|            i_a++;
  776|  4.96k|            i_b++;
  777|  4.96k|        }
  778|  36.6k|    }
  779|  2.18k|    if (i_a < s_a) {
  ------------------
  |  Branch (779:9): [True: 455, False: 1.72k]
  ------------------
  780|    455|        if (C == A) {
  ------------------
  |  Branch (780:13): [True: 0, False: 455]
  ------------------
  781|      0|            assert((size_t)count <= i_a);
  782|      0|            if ((size_t)count < i_a) {
  ------------------
  |  Branch (782:17): [True: 0, False: 0]
  ------------------
  783|      0|                memmove(C + count, A + i_a, sizeof(uint16_t) * (s_a - i_a));
  784|      0|            }
  785|    455|        } else {
  786|  12.9k|            for (size_t i = 0; i < (s_a - i_a); i++) {
  ------------------
  |  Branch (786:32): [True: 12.4k, False: 455]
  ------------------
  787|  12.4k|                C[count + i] = A[i + i_a];
  788|  12.4k|            }
  789|    455|        }
  790|    455|        count += (int32_t)(s_a - i_a);
  791|    455|    }
  792|  2.18k|    return count;
  793|  2.18k|}
intersect_skewed_uint16:
  859|    704|                                uint16_t *buffer) {
  860|    704|    size_t pos = 0, idx_l = 0, idx_s = 0;
  861|       |
  862|    704|    if (0 == size_s) {
  ------------------
  |  Branch (862:9): [True: 0, False: 704]
  ------------------
  863|      0|        return 0;
  864|      0|    }
  865|    704|    int32_t index1 = 0, index2 = 0, index3 = 0, index4 = 0;
  866|  1.84k|    while ((idx_s + 4 <= size_s) && (idx_l < size_l)) {
  ------------------
  |  Branch (866:12): [True: 1.13k, False: 704]
  |  Branch (866:37): [True: 1.13k, False: 0]
  ------------------
  867|  1.13k|        uint16_t target1 = small[idx_s];
  868|  1.13k|        uint16_t target2 = small[idx_s + 1];
  869|  1.13k|        uint16_t target3 = small[idx_s + 2];
  870|  1.13k|        uint16_t target4 = small[idx_s + 3];
  871|  1.13k|        binarySearch4(large + idx_l, (int32_t)(size_l - idx_l), target1,
  872|  1.13k|                      target2, target3, target4, &index1, &index2, &index3,
  873|  1.13k|                      &index4);
  874|  1.13k|        if ((index1 + idx_l < size_l) && (large[idx_l + index1] == target1)) {
  ------------------
  |  Branch (874:13): [True: 1.13k, False: 1]
  |  Branch (874:42): [True: 557, False: 579]
  ------------------
  875|    557|            buffer[pos++] = target1;
  876|    557|        }
  877|  1.13k|        if ((index2 + idx_l < size_l) && (large[idx_l + index2] == target2)) {
  ------------------
  |  Branch (877:13): [True: 1.13k, False: 2]
  |  Branch (877:42): [True: 665, False: 470]
  ------------------
  878|    665|            buffer[pos++] = target2;
  879|    665|        }
  880|  1.13k|        if ((index3 + idx_l < size_l) && (large[idx_l + index3] == target3)) {
  ------------------
  |  Branch (880:13): [True: 1.13k, False: 3]
  |  Branch (880:42): [True: 664, False: 470]
  ------------------
  881|    664|            buffer[pos++] = target3;
  882|    664|        }
  883|  1.13k|        if ((index4 + idx_l < size_l) && (large[idx_l + index4] == target4)) {
  ------------------
  |  Branch (883:13): [True: 1.13k, False: 7]
  |  Branch (883:42): [True: 626, False: 504]
  ------------------
  884|    626|            buffer[pos++] = target4;
  885|    626|        }
  886|  1.13k|        idx_s += 4;
  887|  1.13k|        idx_l += index4;
  888|  1.13k|    }
  889|    704|    if ((idx_s + 2 <= size_s) && (idx_l < size_l)) {
  ------------------
  |  Branch (889:9): [True: 403, False: 301]
  |  Branch (889:34): [True: 402, False: 1]
  ------------------
  890|    402|        uint16_t target1 = small[idx_s];
  891|    402|        uint16_t target2 = small[idx_s + 1];
  892|    402|        binarySearch2(large + idx_l, (int32_t)(size_l - idx_l), target1,
  893|    402|                      target2, &index1, &index2);
  894|    402|        if ((index1 + idx_l < size_l) && (large[idx_l + index1] == target1)) {
  ------------------
  |  Branch (894:13): [True: 397, False: 5]
  |  Branch (894:42): [True: 260, False: 137]
  ------------------
  895|    260|            buffer[pos++] = target1;
  896|    260|        }
  897|    402|        if ((index2 + idx_l < size_l) && (large[idx_l + index2] == target2)) {
  ------------------
  |  Branch (897:13): [True: 384, False: 18]
  |  Branch (897:42): [True: 265, False: 119]
  ------------------
  898|    265|            buffer[pos++] = target2;
  899|    265|        }
  900|    402|        idx_s += 2;
  901|    402|        idx_l += index2;
  902|    402|    }
  903|    704|    if ((idx_s < size_s) && (idx_l < size_l)) {
  ------------------
  |  Branch (903:9): [True: 316, False: 388]
  |  Branch (903:29): [True: 313, False: 3]
  ------------------
  904|    313|        uint16_t val_s = small[idx_s];
  905|    313|        int32_t index =
  906|    313|            binarySearch(large + idx_l, (int32_t)(size_l - idx_l), val_s);
  907|    313|        if (index >= 0) buffer[pos++] = val_s;
  ------------------
  |  Branch (907:13): [True: 224, False: 89]
  ------------------
  908|    313|    }
  909|    704|    return (int32_t)pos;
  910|    704|}
intersect_skewed_uint16_cardinality:
  916|  2.02k|                                            size_t size_l) {
  917|  2.02k|    size_t pos = 0, idx_l = 0, idx_s = 0;
  918|       |
  919|  2.02k|    if (0 == size_s) {
  ------------------
  |  Branch (919:9): [True: 0, False: 2.02k]
  ------------------
  920|      0|        return 0;
  921|      0|    }
  922|       |
  923|  2.02k|    uint16_t val_l = large[idx_l], val_s = small[idx_s];
  924|       |
  925|  26.3k|    while (true) {
  ------------------
  |  Branch (925:12): [True: 26.3k, Folded]
  ------------------
  926|  26.3k|        if (val_l < val_s) {
  ------------------
  |  Branch (926:13): [True: 5.46k, False: 20.9k]
  ------------------
  927|  5.46k|            idx_l = advanceUntil(large, (int32_t)idx_l, (int32_t)size_l, val_s);
  928|  5.46k|            if (idx_l == size_l) break;
  ------------------
  |  Branch (928:17): [True: 144, False: 5.32k]
  ------------------
  929|  5.32k|            val_l = large[idx_l];
  930|  20.9k|        } else if (val_s < val_l) {
  ------------------
  |  Branch (930:20): [True: 9.36k, False: 11.5k]
  ------------------
  931|  9.36k|            idx_s++;
  932|  9.36k|            if (idx_s == size_s) break;
  ------------------
  |  Branch (932:17): [True: 752, False: 8.61k]
  ------------------
  933|  8.61k|            val_s = small[idx_s];
  934|  11.5k|        } else {
  935|  11.5k|            pos++;
  936|  11.5k|            idx_s++;
  937|  11.5k|            if (idx_s == size_s) break;
  ------------------
  |  Branch (937:17): [True: 1.06k, False: 10.4k]
  ------------------
  938|  10.4k|            val_s = small[idx_s];
  939|  10.4k|            idx_l = advanceUntil(large, (int32_t)idx_l, (int32_t)size_l, val_s);
  940|  10.4k|            if (idx_l == size_l) break;
  ------------------
  |  Branch (940:17): [True: 60, False: 10.4k]
  ------------------
  941|  10.4k|            val_l = large[idx_l];
  942|  10.4k|        }
  943|  26.3k|    }
  944|       |
  945|  2.02k|    return (int32_t)pos;
  946|  2.02k|}
intersect_skewed_uint16_nonempty:
  949|    506|                                      const uint16_t *large, size_t size_l) {
  950|    506|    size_t idx_l = 0, idx_s = 0;
  951|       |
  952|    506|    if (0 == size_s) {
  ------------------
  |  Branch (952:9): [True: 0, False: 506]
  ------------------
  953|      0|        return false;
  954|      0|    }
  955|       |
  956|    506|    uint16_t val_l = large[idx_l], val_s = small[idx_s];
  957|       |
  958|  1.96k|    while (true) {
  ------------------
  |  Branch (958:12): [True: 1.96k, Folded]
  ------------------
  959|  1.96k|        if (val_l < val_s) {
  ------------------
  |  Branch (959:13): [True: 758, False: 1.20k]
  ------------------
  960|    758|            idx_l = advanceUntil(large, (int32_t)idx_l, (int32_t)size_l, val_s);
  961|    758|            if (idx_l == size_l) break;
  ------------------
  |  Branch (961:17): [True: 34, False: 724]
  ------------------
  962|    724|            val_l = large[idx_l];
  963|  1.20k|        } else if (val_s < val_l) {
  ------------------
  |  Branch (963:20): [True: 802, False: 405]
  ------------------
  964|    802|            idx_s++;
  965|    802|            if (idx_s == size_s) break;
  ------------------
  |  Branch (965:17): [True: 67, False: 735]
  ------------------
  966|    735|            val_s = small[idx_s];
  967|    735|        } else {
  968|    405|            return true;
  969|    405|        }
  970|  1.96k|    }
  971|       |
  972|    101|    return false;
  973|    506|}
intersect_uint16_nonempty:
 1229|  2.94k|                               const uint16_t *B, const size_t lenB) {
 1230|  2.94k|    if (lenA == 0 || lenB == 0) return 0;
  ------------------
  |  Branch (1230:9): [True: 0, False: 2.94k]
  |  Branch (1230:22): [True: 0, False: 2.94k]
  ------------------
 1231|  2.94k|    const uint16_t *endA = A + lenA;
 1232|  2.94k|    const uint16_t *endB = B + lenB;
 1233|       |
 1234|  2.94k|    while (1) {
  ------------------
  |  Branch (1234:12): [True: 2.94k, Folded]
  ------------------
 1235|  16.8k|        while (*A < *B) {
  ------------------
  |  Branch (1235:16): [True: 13.2k, False: 3.61k]
  ------------------
 1236|  13.9k|        SKIP_FIRST_COMPARE:
 1237|  13.9k|            if (++A == endA) return false;
  ------------------
  |  Branch (1237:17): [True: 65, False: 13.9k]
  ------------------
 1238|  13.9k|        }
 1239|  9.02k|        while (*A > *B) {
  ------------------
  |  Branch (1239:16): [True: 5.42k, False: 3.60k]
  ------------------
 1240|  5.42k|            if (++B == endB) return false;
  ------------------
  |  Branch (1240:17): [True: 15, False: 5.41k]
  ------------------
 1241|  5.42k|        }
 1242|  3.60k|        if (*A == *B) {
  ------------------
  |  Branch (1242:13): [True: 2.86k, False: 731]
  ------------------
 1243|  2.86k|            return true;
 1244|  2.86k|        } else {
 1245|    731|            goto SKIP_FIRST_COMPARE;
 1246|    731|        }
 1247|  3.60k|    }
 1248|      0|    return false;  // NOTREACHED
 1249|  2.94k|}
union_uint16:
 1310|  6.89k|                    size_t size_2, uint16_t *buffer) {
 1311|       |    // Every write goes before buffer + idx_1 + size_2, so buffer may start
 1312|       |    // size_2 values before set_1 (array_array_container_inplace_union).
 1313|  6.89k|    if (croaring_skewed_sizes(size_1, size_2)) {
  ------------------
  |  Branch (1313:9): [True: 1.18k, False: 5.71k]
  ------------------
 1314|  1.18k|        return union_skewed_uint16(set_1, size_1, set_2, size_2, buffer);
 1315|  1.18k|    }
 1316|  5.71k|    if (croaring_skewed_sizes(size_2, size_1)) {
  ------------------
  |  Branch (1316:9): [True: 375, False: 5.33k]
  ------------------
 1317|    375|        return union_skewed_uint16(set_2, size_2, set_1, size_1, buffer);
 1318|    375|    }
 1319|  5.33k|    size_t pos = 0, idx_1 = 0, idx_2 = 0;
 1320|  19.3k|    while (idx_1 + 4 <= size_1 && idx_2 + 4 <= size_2) {
  ------------------
  |  Branch (1320:12): [True: 14.4k, False: 4.95k]
  |  Branch (1320:35): [True: 14.0k, False: 381]
  ------------------
 1321|  14.0k|        if (set_1[idx_1 + 3] < set_2[idx_2]) {
  ------------------
  |  Branch (1321:13): [True: 398, False: 13.6k]
  ------------------
 1322|    398|            memmove(buffer + pos, set_1 + idx_1, 4 * sizeof(uint16_t));
 1323|    398|            pos += 4;
 1324|    398|            idx_1 += 4;
 1325|  13.6k|        } else if (set_2[idx_2 + 3] < set_1[idx_1]) {
  ------------------
  |  Branch (1325:20): [True: 1.58k, False: 12.0k]
  ------------------
 1326|  1.58k|            memmove(buffer + pos, set_2 + idx_2, 4 * sizeof(uint16_t));
 1327|  1.58k|            pos += 4;
 1328|  1.58k|            idx_2 += 4;
 1329|  12.0k|        } else if (croaring_equal4_uint16(set_1 + idx_1, set_2 + idx_2)) {
  ------------------
  |  Branch (1329:20): [True: 5.37k, False: 6.68k]
  ------------------
 1330|  5.37k|            memmove(buffer + pos, set_1 + idx_1, 4 * sizeof(uint16_t));
 1331|  5.37k|            pos += 4;
 1332|  5.37k|            idx_1 += 4;
 1333|  5.37k|            idx_2 += 4;
 1334|  6.68k|        } else {
 1335|  33.4k|            for (int step = 0; step < 4; step++) {
  ------------------
  |  Branch (1335:32): [True: 26.7k, False: 6.68k]
  ------------------
 1336|  26.7k|                const uint16_t val_1 = set_1[idx_1], val_2 = set_2[idx_2];
 1337|  26.7k|                buffer[pos++] = val_1 < val_2 ? val_1 : val_2;
  ------------------
  |  Branch (1337:33): [True: 5.85k, False: 20.8k]
  ------------------
 1338|  26.7k|                idx_1 += (val_1 <= val_2);
 1339|  26.7k|                idx_2 += (val_1 >= val_2);
 1340|  26.7k|            }
 1341|  6.68k|        }
 1342|  14.0k|    }
 1343|       |    // Fewer than four values remain on one side. If many remain on the
 1344|       |    // other, gallop rather than step through them one at a time.
 1345|  5.33k|    const size_t rem_1 = size_1 - idx_1, rem_2 = size_2 - idx_2;
 1346|  5.33k|    if (croaring_skewed_sizes(rem_1, rem_2)) {
  ------------------
  |  Branch (1346:9): [True: 694, False: 4.64k]
  ------------------
 1347|    694|        return pos + union_skewed_uint16(set_1 + idx_1, rem_1, set_2 + idx_2,
 1348|    694|                                         rem_2, buffer + pos);
 1349|    694|    }
 1350|  4.64k|    if (croaring_skewed_sizes(rem_2, rem_1)) {
  ------------------
  |  Branch (1350:9): [True: 80, False: 4.56k]
  ------------------
 1351|     80|        return pos + union_skewed_uint16(set_2 + idx_2, rem_2, set_1 + idx_1,
 1352|     80|                                         rem_1, buffer + pos);
 1353|     80|    }
 1354|  17.3k|    while (idx_1 < size_1 && idx_2 < size_2) {
  ------------------
  |  Branch (1354:12): [True: 13.0k, False: 4.26k]
  |  Branch (1354:30): [True: 12.7k, False: 295]
  ------------------
 1355|  12.7k|        const uint16_t val_1 = set_1[idx_1], val_2 = set_2[idx_2];
 1356|  12.7k|        buffer[pos++] = val_1 < val_2 ? val_1 : val_2;
  ------------------
  |  Branch (1356:25): [True: 1.32k, False: 11.4k]
  ------------------
 1357|  12.7k|        idx_1 += (val_1 <= val_2);
 1358|  12.7k|        idx_2 += (val_1 >= val_2);
 1359|  12.7k|    }
 1360|  4.56k|    if (idx_1 < size_1) {
  ------------------
  |  Branch (1360:9): [True: 295, False: 4.26k]
  ------------------
 1361|    295|        const size_t n_elems = size_1 - idx_1;
 1362|    295|        memmove(buffer + pos, set_1 + idx_1, n_elems * sizeof(uint16_t));
 1363|    295|        pos += n_elems;
 1364|  4.26k|    } else if (idx_2 < size_2) {
  ------------------
  |  Branch (1364:16): [True: 970, False: 3.29k]
  ------------------
 1365|    970|        const size_t n_elems = size_2 - idx_2;
 1366|    970|        memmove(buffer + pos, set_2 + idx_2, n_elems * sizeof(uint16_t));
 1367|    970|        pos += n_elems;
 1368|    970|    }
 1369|  4.56k|    return pos;
 1370|  4.64k|}
difference_uint16:
 1374|  5.74k|                      int length2, uint16_t *a_out) {
 1375|       |    // Every write goes to a_out[k..] with k <= i, so a_out may be a1.
 1376|  5.74k|    if (croaring_skewed_sizes((size_t)length2, (size_t)length1)) {
  ------------------
  |  Branch (1376:9): [True: 1.06k, False: 4.68k]
  ------------------
 1377|  1.06k|        return difference_skewed_small_a2_uint16(a1, length1, a2, length2,
 1378|  1.06k|                                                 a_out);
 1379|  1.06k|    }
 1380|  4.68k|    if (croaring_skewed_sizes((size_t)length1, (size_t)length2)) {
  ------------------
  |  Branch (1380:9): [True: 286, False: 4.39k]
  ------------------
 1381|    286|        return difference_skewed_small_a1_uint16(a1, length1, a2, length2,
 1382|    286|                                                 a_out);
 1383|    286|    }
 1384|  4.39k|    int i = 0, j = 0, k = 0;
 1385|  79.6k|    while (i + 4 <= length1 && j + 4 <= length2) {
  ------------------
  |  Branch (1385:12): [True: 76.5k, False: 3.04k]
  |  Branch (1385:32): [True: 75.2k, False: 1.34k]
  ------------------
 1386|  75.2k|        if (a1[i + 3] < a2[j]) {
  ------------------
  |  Branch (1386:13): [True: 8.66k, False: 66.5k]
  ------------------
 1387|  8.66k|            memmove(a_out + k, a1 + i, 4 * sizeof(uint16_t));
 1388|  8.66k|            k += 4;
 1389|  8.66k|            i += 4;
 1390|  66.5k|        } else if (a2[j + 3] < a1[i]) {
  ------------------
  |  Branch (1390:20): [True: 38, False: 66.5k]
  ------------------
 1391|     38|            j += 4;
 1392|  66.5k|        } else if (croaring_equal4_uint16(a1 + i, a2 + j)) {
  ------------------
  |  Branch (1392:20): [True: 32.0k, False: 34.4k]
  ------------------
 1393|  32.0k|            i += 4;
 1394|  32.0k|            j += 4;
 1395|  34.4k|        } else {
 1396|   172k|            for (int step = 0; step < 4; step++) {
  ------------------
  |  Branch (1396:32): [True: 137k, False: 34.4k]
  ------------------
 1397|   137k|                const uint16_t a = a1[i], b = a2[j];
 1398|   137k|                a_out[k] = a;
 1399|   137k|                k += (a < b);
 1400|   137k|                i += (a <= b);
 1401|   137k|                j += (a >= b);
 1402|   137k|            }
 1403|  34.4k|        }
 1404|  75.2k|    }
 1405|       |    // Fewer than four values remain on one side. If many remain on the
 1406|       |    // other, gallop rather than step through them one at a time.
 1407|  4.39k|    const int rem_1 = length1 - i, rem_2 = length2 - j;
 1408|  4.39k|    if (croaring_skewed_sizes((size_t)rem_2, (size_t)rem_1)) {
  ------------------
  |  Branch (1408:9): [True: 359, False: 4.03k]
  ------------------
 1409|    359|        return k + difference_skewed_small_a2_uint16(a1 + i, rem_1, a2 + j,
 1410|    359|                                                     rem_2, a_out + k);
 1411|    359|    }
 1412|  4.03k|    if (croaring_skewed_sizes((size_t)rem_1, (size_t)rem_2)) {
  ------------------
  |  Branch (1412:9): [True: 85, False: 3.95k]
  ------------------
 1413|     85|        return k + difference_skewed_small_a1_uint16(a1 + i, rem_1, a2 + j,
 1414|     85|                                                     rem_2, a_out + k);
 1415|     85|    }
 1416|  14.9k|    while (i < length1 && j < length2) {
  ------------------
  |  Branch (1416:12): [True: 11.8k, False: 3.04k]
  |  Branch (1416:27): [True: 10.9k, False: 905]
  ------------------
 1417|  10.9k|        const uint16_t a = a1[i], b = a2[j];
 1418|  10.9k|        a_out[k] = a;
 1419|  10.9k|        k += (a < b);
 1420|  10.9k|        i += (a <= b);
 1421|  10.9k|        j += (a >= b);
 1422|  10.9k|    }
 1423|  3.95k|    if (i < length1) {
  ------------------
  |  Branch (1423:9): [True: 905, False: 3.04k]
  ------------------
 1424|    905|        memmove(a_out + k, a1 + i, sizeof(uint16_t) * (length1 - i));
 1425|    905|        k += length1 - i;
 1426|    905|    }
 1427|  3.95k|    return k;
 1428|  4.03k|}
xor_uint16:
 1432|  9.27k|                   const uint16_t *array_2, int32_t card_2, uint16_t *out) {
 1433|  9.27k|    if (croaring_skewed_sizes((size_t)card_1, (size_t)card_2)) {
  ------------------
  |  Branch (1433:9): [True: 1.67k, False: 7.60k]
  ------------------
 1434|  1.67k|        return xor_skewed_uint16(array_1, (size_t)card_1, array_2,
 1435|  1.67k|                                 (size_t)card_2, out);
 1436|  1.67k|    }
 1437|  7.60k|    if (croaring_skewed_sizes((size_t)card_2, (size_t)card_1)) {
  ------------------
  |  Branch (1437:9): [True: 440, False: 7.16k]
  ------------------
 1438|    440|        return xor_skewed_uint16(array_2, (size_t)card_2, array_1,
 1439|    440|                                 (size_t)card_1, out);
 1440|    440|    }
 1441|  7.16k|    int32_t pos1 = 0, pos2 = 0, pos_out = 0;
 1442|  22.3k|    while (pos1 + 4 <= card_1 && pos2 + 4 <= card_2) {
  ------------------
  |  Branch (1442:12): [True: 15.6k, False: 6.68k]
  |  Branch (1442:34): [True: 15.1k, False: 475]
  ------------------
 1443|  15.1k|        if (array_1[pos1 + 3] < array_2[pos2]) {
  ------------------
  |  Branch (1443:13): [True: 524, False: 14.6k]
  ------------------
 1444|    524|            memcpy(out + pos_out, array_1 + pos1, 4 * sizeof(uint16_t));
 1445|    524|            pos_out += 4;
 1446|    524|            pos1 += 4;
 1447|  14.6k|        } else if (array_2[pos2 + 3] < array_1[pos1]) {
  ------------------
  |  Branch (1447:20): [True: 2.66k, False: 12.0k]
  ------------------
 1448|  2.66k|            memcpy(out + pos_out, array_2 + pos2, 4 * sizeof(uint16_t));
 1449|  2.66k|            pos_out += 4;
 1450|  2.66k|            pos2 += 4;
 1451|  12.0k|        } else if (croaring_equal4_uint16(array_1 + pos1, array_2 + pos2)) {
  ------------------
  |  Branch (1451:20): [True: 4.04k, False: 7.95k]
  ------------------
 1452|  4.04k|            pos1 += 4;
 1453|  4.04k|            pos2 += 4;
 1454|  7.95k|        } else {
 1455|  39.7k|            for (int step = 0; step < 4; step++) {
  ------------------
  |  Branch (1455:32): [True: 31.8k, False: 7.95k]
  ------------------
 1456|  31.8k|                const uint16_t v1 = array_1[pos1], v2 = array_2[pos2];
 1457|  31.8k|                out[pos_out] = v1 < v2 ? v1 : v2;
  ------------------
  |  Branch (1457:32): [True: 6.13k, False: 25.6k]
  ------------------
 1458|  31.8k|                pos_out += (v1 != v2);
 1459|  31.8k|                pos1 += (v1 <= v2);
 1460|  31.8k|                pos2 += (v1 >= v2);
 1461|  31.8k|            }
 1462|  7.95k|        }
 1463|  15.1k|    }
 1464|       |    // Fewer than four values remain on one side. If many remain on the
 1465|       |    // other, gallop rather than step through them one at a time.
 1466|  7.16k|    const size_t rem_1 = (size_t)(card_1 - pos1),
 1467|  7.16k|                 rem_2 = (size_t)(card_2 - pos2);
 1468|  7.16k|    if (croaring_skewed_sizes(rem_1, rem_2)) {
  ------------------
  |  Branch (1468:9): [True: 518, False: 6.64k]
  ------------------
 1469|    518|        return pos_out + xor_skewed_uint16(array_1 + pos1, rem_1,
 1470|    518|                                           array_2 + pos2, rem_2,
 1471|    518|                                           out + pos_out);
 1472|    518|    }
 1473|  6.64k|    if (croaring_skewed_sizes(rem_2, rem_1)) {
  ------------------
  |  Branch (1473:9): [True: 180, False: 6.46k]
  ------------------
 1474|    180|        return pos_out + xor_skewed_uint16(array_2 + pos2, rem_2,
 1475|    180|                                           array_1 + pos1, rem_1,
 1476|    180|                                           out + pos_out);
 1477|    180|    }
 1478|  23.6k|    while (pos1 < card_1 && pos2 < card_2) {
  ------------------
  |  Branch (1478:12): [True: 17.6k, False: 6.09k]
  |  Branch (1478:29): [True: 17.2k, False: 372]
  ------------------
 1479|  17.2k|        const uint16_t v1 = array_1[pos1], v2 = array_2[pos2];
 1480|  17.2k|        out[pos_out] = v1 < v2 ? v1 : v2;
  ------------------
  |  Branch (1480:24): [True: 1.67k, False: 15.5k]
  ------------------
 1481|  17.2k|        pos_out += (v1 != v2);
 1482|  17.2k|        pos1 += (v1 <= v2);
 1483|  17.2k|        pos2 += (v1 >= v2);
 1484|  17.2k|    }
 1485|  6.46k|    if (pos1 < card_1) {
  ------------------
  |  Branch (1485:9): [True: 372, False: 6.09k]
  ------------------
 1486|    372|        const size_t n_elems = card_1 - pos1;
 1487|    372|        memcpy(out + pos_out, array_1 + pos1, n_elems * sizeof(uint16_t));
 1488|    372|        pos_out += (int32_t)n_elems;
 1489|  6.09k|    } else if (pos2 < card_2) {
  ------------------
  |  Branch (1489:16): [True: 1.07k, False: 5.01k]
  ------------------
 1490|  1.07k|        const size_t n_elems = card_2 - pos2;
 1491|  1.07k|        memcpy(out + pos_out, array_2 + pos2, n_elems * sizeof(uint16_t));
 1492|  1.07k|        pos_out += (int32_t)n_elems;
 1493|  1.07k|    }
 1494|  6.46k|    return pos_out;
 1495|  6.64k|}
union_vector16:
 1926|  5.98k|                        uint16_t *output) {
 1927|  5.98k|    if ((length1 < 8) || (length2 < 8)) {
  ------------------
  |  Branch (1927:9): [True: 1.10k, False: 4.88k]
  |  Branch (1927:26): [True: 0, False: 4.88k]
  ------------------
 1928|  1.10k|        return (uint32_t)union_uint16(array1, length1, array2, length2, output);
 1929|  1.10k|    }
 1930|  4.88k|    __m128i vA, vB, V, vecMin, vecMax;
 1931|  4.88k|    __m128i laststore;
 1932|  4.88k|    uint16_t *initoutput = output;
 1933|  4.88k|    uint32_t len1 = length1 / 8;
 1934|  4.88k|    uint32_t len2 = length2 / 8;
 1935|  4.88k|    uint32_t pos1 = 0;
 1936|  4.88k|    uint32_t pos2 = 0;
 1937|       |    // we start the machine
 1938|  4.88k|    vA = _mm_lddqu_si128((const __m128i *)array1 + pos1);
 1939|  4.88k|    pos1++;
 1940|  4.88k|    vB = _mm_lddqu_si128((const __m128i *)array2 + pos2);
 1941|  4.88k|    pos2++;
 1942|  4.88k|    sse_merge(vA, vB, &vecMin, &vecMax);
 1943|  4.88k|    laststore = _mm_set1_epi16(-1);
 1944|  4.88k|    output += store_unique(laststore, vecMin, output);
 1945|  4.88k|    laststore = vecMin;
 1946|  4.88k|    if ((pos1 < len1) && (pos2 < len2)) {
  ------------------
  |  Branch (1946:9): [True: 3.98k, False: 895]
  |  Branch (1946:26): [True: 3.98k, False: 0]
  ------------------
 1947|  3.98k|        uint16_t curA, curB;
 1948|  3.98k|        curA = array1[8 * pos1];
 1949|  3.98k|        curB = array2[8 * pos2];
 1950|   118k|        while (true) {
  ------------------
  |  Branch (1950:16): [True: 118k, Folded]
  ------------------
 1951|   118k|            if (curA <= curB) {
  ------------------
  |  Branch (1951:17): [True: 49.6k, False: 68.6k]
  ------------------
 1952|  49.6k|                V = _mm_lddqu_si128((const __m128i *)array1 + pos1);
 1953|  49.6k|                pos1++;
 1954|  49.6k|                if (pos1 < len1) {
  ------------------
  |  Branch (1954:21): [True: 46.5k, False: 3.12k]
  ------------------
 1955|  46.5k|                    curA = array1[8 * pos1];
 1956|  46.5k|                } else {
 1957|  3.12k|                    break;
 1958|  3.12k|                }
 1959|  68.6k|            } else {
 1960|  68.6k|                V = _mm_lddqu_si128((const __m128i *)array2 + pos2);
 1961|  68.6k|                pos2++;
 1962|  68.6k|                if (pos2 < len2) {
  ------------------
  |  Branch (1962:21): [True: 67.7k, False: 864]
  ------------------
 1963|  67.7k|                    curB = array2[8 * pos2];
 1964|  67.7k|                } else {
 1965|    864|                    break;
 1966|    864|                }
 1967|  68.6k|            }
 1968|   114k|            sse_merge(vecMax, V, &vecMin, &vecMax);
 1969|   114k|            output += store_unique(laststore, vecMin, output);
 1970|   114k|            laststore = vecMin;
 1971|   114k|        }
 1972|  3.98k|        sse_merge(vecMax, V, &vecMin, &vecMax);
 1973|  3.98k|        output += store_unique(laststore, vecMin, output);
 1974|  3.98k|        laststore = vecMin;
 1975|  3.98k|    }
 1976|       |    // we finish the rest off using a scalar algorithm
 1977|       |    // could be improved?
 1978|       |    //
 1979|       |    // copy the small end on a tmp buffer
 1980|  4.88k|    uint32_t len = (uint32_t)(output - initoutput);
 1981|  4.88k|    uint16_t buffer[16];
 1982|  4.88k|    uint32_t leftoversize = store_unique(laststore, vecMax, buffer);
 1983|  4.88k|    if (pos1 == len1) {
  ------------------
  |  Branch (1983:9): [True: 4.01k, False: 864]
  ------------------
 1984|  4.01k|        memcpy(buffer + leftoversize, array1 + 8 * pos1,
 1985|  4.01k|               (length1 - 8 * len1) * sizeof(uint16_t));
 1986|  4.01k|        leftoversize += length1 - 8 * len1;
 1987|  4.01k|        sort_uint16_short(buffer, leftoversize);
 1988|       |
 1989|  4.01k|        leftoversize = unique(buffer, leftoversize);
 1990|  4.01k|        len += (uint32_t)union_uint16(buffer, leftoversize, array2 + 8 * pos2,
 1991|  4.01k|                                      length2 - 8 * pos2, output);
 1992|  4.01k|    } else {
 1993|    864|        memcpy(buffer + leftoversize, array2 + 8 * pos2,
 1994|    864|               (length2 - 8 * len2) * sizeof(uint16_t));
 1995|    864|        leftoversize += length2 - 8 * len2;
 1996|    864|        sort_uint16_short(buffer, leftoversize);
 1997|    864|        leftoversize = unique(buffer, leftoversize);
 1998|    864|        len += (uint32_t)union_uint16(buffer, leftoversize, array1 + 8 * pos1,
 1999|    864|                                      length1 - 8 * pos1, output);
 2000|    864|    }
 2001|  4.88k|    return len;
 2002|  5.98k|}
xor_vector16:
 2235|  8.29k|                      uint16_t *output) {
 2236|  8.29k|    if ((length1 < 8) || (length2 < 8)) {
  ------------------
  |  Branch (2236:9): [True: 2.88k, False: 5.41k]
  |  Branch (2236:26): [True: 429, False: 4.98k]
  ------------------
 2237|  3.30k|        return xor_uint16(array1, length1, array2, length2, output);
 2238|  3.30k|    }
 2239|  4.98k|    __m128i vA, vB, V, vecMin, vecMax;
 2240|  4.98k|    __m128i laststore;
 2241|  4.98k|    uint16_t *initoutput = output;
 2242|  4.98k|    uint32_t len1 = length1 / 8;
 2243|  4.98k|    uint32_t len2 = length2 / 8;
 2244|  4.98k|    uint32_t pos1 = 0;
 2245|  4.98k|    uint32_t pos2 = 0;
 2246|       |    // we start the machine
 2247|  4.98k|    vA = _mm_lddqu_si128((const __m128i *)array1 + pos1);
 2248|  4.98k|    pos1++;
 2249|  4.98k|    vB = _mm_lddqu_si128((const __m128i *)array2 + pos2);
 2250|  4.98k|    pos2++;
 2251|  4.98k|    sse_merge(vA, vB, &vecMin, &vecMax);
 2252|  4.98k|    laststore = _mm_set1_epi16(-1);
 2253|  4.98k|    uint16_t buffer[17];
 2254|  4.98k|    output += store_unique_xor(laststore, vecMin, output);
 2255|       |
 2256|  4.98k|    laststore = vecMin;
 2257|  4.98k|    if ((pos1 < len1) && (pos2 < len2)) {
  ------------------
  |  Branch (2257:9): [True: 4.47k, False: 510]
  |  Branch (2257:26): [True: 4.13k, False: 332]
  ------------------
 2258|  4.13k|        uint16_t curA, curB;
 2259|  4.13k|        curA = array1[8 * pos1];
 2260|  4.13k|        curB = array2[8 * pos2];
 2261|   190k|        while (true) {
  ------------------
  |  Branch (2261:16): [True: 190k, Folded]
  ------------------
 2262|   190k|            if (curA <= curB) {
  ------------------
  |  Branch (2262:17): [True: 90.0k, False: 100k]
  ------------------
 2263|  90.0k|                V = _mm_lddqu_si128((const __m128i *)array1 + pos1);
 2264|  90.0k|                pos1++;
 2265|  90.0k|                if (pos1 < len1) {
  ------------------
  |  Branch (2265:21): [True: 87.4k, False: 2.64k]
  ------------------
 2266|  87.4k|                    curA = array1[8 * pos1];
 2267|  87.4k|                } else {
 2268|  2.64k|                    break;
 2269|  2.64k|                }
 2270|   100k|            } else {
 2271|   100k|                V = _mm_lddqu_si128((const __m128i *)array2 + pos2);
 2272|   100k|                pos2++;
 2273|   100k|                if (pos2 < len2) {
  ------------------
  |  Branch (2273:21): [True: 98.7k, False: 1.49k]
  ------------------
 2274|  98.7k|                    curB = array2[8 * pos2];
 2275|  98.7k|                } else {
 2276|  1.49k|                    break;
 2277|  1.49k|                }
 2278|   100k|            }
 2279|   186k|            sse_merge(vecMax, V, &vecMin, &vecMax);
 2280|       |            // conditionally stores the last value of laststore as well as all
 2281|       |            // but the
 2282|       |            // last value of vecMin
 2283|   186k|            output += store_unique_xor(laststore, vecMin, output);
 2284|   186k|            laststore = vecMin;
 2285|   186k|        }
 2286|  4.13k|        sse_merge(vecMax, V, &vecMin, &vecMax);
 2287|       |        // conditionally stores the last value of laststore as well as all but
 2288|       |        // the
 2289|       |        // last value of vecMin
 2290|  4.13k|        output += store_unique_xor(laststore, vecMin, output);
 2291|  4.13k|        laststore = vecMin;
 2292|  4.13k|    }
 2293|  4.98k|    uint32_t len = (uint32_t)(output - initoutput);
 2294|       |
 2295|       |    // we finish the rest off using a scalar algorithm
 2296|       |    // could be improved?
 2297|       |    // conditionally stores the last value of laststore as well as all but the
 2298|       |    // last value of vecMax,
 2299|       |    // we store to "buffer"
 2300|  4.98k|    int leftoversize = store_unique_xor(laststore, vecMax, buffer);
 2301|  4.98k|    uint16_t vec7 = (uint16_t)_mm_extract_epi16(vecMax, 7);
 2302|  4.98k|    uint16_t vec6 = (uint16_t)_mm_extract_epi16(vecMax, 6);
 2303|  4.98k|    if (vec7 != vec6) buffer[leftoversize++] = vec7;
  ------------------
  |  Branch (2303:9): [True: 4.92k, False: 52]
  ------------------
 2304|  4.98k|    if (pos1 == len1) {
  ------------------
  |  Branch (2304:9): [True: 3.15k, False: 1.83k]
  ------------------
 2305|  3.15k|        memcpy(buffer + leftoversize, array1 + 8 * pos1,
 2306|  3.15k|               (length1 - 8 * len1) * sizeof(uint16_t));
 2307|  3.15k|        leftoversize += length1 - 8 * len1;
 2308|  3.15k|        if (leftoversize == 0) {  // trivial case
  ------------------
  |  Branch (2308:13): [True: 6, False: 3.14k]
  ------------------
 2309|      6|            memcpy(output, array2 + 8 * pos2,
 2310|      6|                   (length2 - 8 * pos2) * sizeof(uint16_t));
 2311|      6|            len += (length2 - 8 * pos2);
 2312|  3.14k|        } else {
 2313|  3.14k|            sort_uint16_short(buffer, leftoversize);
 2314|  3.14k|            leftoversize = unique_xor(buffer, leftoversize);
 2315|  3.14k|            len += xor_uint16(buffer, leftoversize, array2 + 8 * pos2,
 2316|  3.14k|                              length2 - 8 * pos2, output);
 2317|  3.14k|        }
 2318|  3.15k|    } else {
 2319|  1.83k|        memcpy(buffer + leftoversize, array2 + 8 * pos2,
 2320|  1.83k|               (length2 - 8 * len2) * sizeof(uint16_t));
 2321|  1.83k|        leftoversize += length2 - 8 * len2;
 2322|  1.83k|        if (leftoversize == 0) {  // trivial case
  ------------------
  |  Branch (2322:13): [True: 3, False: 1.82k]
  ------------------
 2323|      3|            memcpy(output, array1 + 8 * pos1,
 2324|      3|                   (length1 - 8 * pos1) * sizeof(uint16_t));
 2325|      3|            len += (length1 - 8 * pos1);
 2326|  1.82k|        } else {
 2327|  1.82k|            sort_uint16_short(buffer, leftoversize);
 2328|  1.82k|            leftoversize = unique_xor(buffer, leftoversize);
 2329|  1.82k|            len += xor_uint16(buffer, leftoversize, array1 + 8 * pos1,
 2330|  1.82k|                              length1 - 8 * pos1, output);
 2331|  1.82k|        }
 2332|  1.83k|    }
 2333|  4.98k|    return len;
 2334|  8.29k|}
fast_union_uint16:
 2437|  6.89k|                         uint16_t *buffer) {
 2438|  6.89k|#if CROARING_IS_X64
 2439|  6.89k|    if (size_1 * CROARING_SKEWED_VECTOR_MERGE_RATIO < size_2 ||
  ------------------
  |  |  291|  6.89k|#define CROARING_SKEWED_VECTOR_MERGE_RATIO 32
  ------------------
  |  Branch (2439:9): [True: 608, False: 6.28k]
  ------------------
 2440|  6.28k|        size_2 * CROARING_SKEWED_VECTOR_MERGE_RATIO < size_1) {
  ------------------
  |  |  291|  6.28k|#define CROARING_SKEWED_VECTOR_MERGE_RATIO 32
  ------------------
  |  Branch (2440:9): [True: 295, False: 5.98k]
  ------------------
 2441|    903|        return union_uint16(set_1, size_1, set_2, size_2, buffer);
 2442|    903|    }
 2443|  5.98k|    const unsigned support = (unsigned)croaring_hardware_support();
 2444|  5.98k|#if CROARING_COMPILER_SUPPORTS_AVX512
 2445|  5.98k|    if (support & ROARING_SUPPORTS_AVX512) {
  ------------------
  |  Branch (2445:9): [True: 0, False: 5.98k]
  ------------------
 2446|       |        // compute union with smallest array first
 2447|      0|        if (size_1 < size_2) {
  ------------------
  |  Branch (2447:13): [True: 0, False: 0]
  ------------------
 2448|      0|            return avx512_union_uint16(set_1, (uint32_t)size_1, set_2,
 2449|      0|                                       (uint32_t)size_2, buffer);
 2450|      0|        } else {
 2451|      0|            return avx512_union_uint16(set_2, (uint32_t)size_2, set_1,
 2452|      0|                                       (uint32_t)size_1, buffer);
 2453|      0|        }
 2454|      0|    }
 2455|  5.98k|#endif  // CROARING_COMPILER_SUPPORTS_AVX512
 2456|  5.98k|    if (support & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (2456:9): [True: 5.98k, False: 0]
  ------------------
 2457|       |        // compute union with smallest array first
 2458|  5.98k|        if (size_1 < size_2) {
  ------------------
  |  Branch (2458:13): [True: 2.66k, False: 3.32k]
  ------------------
 2459|  2.66k|            return union_vector16(set_1, (uint32_t)size_1, set_2,
 2460|  2.66k|                                  (uint32_t)size_2, buffer);
 2461|  3.32k|        } else {
 2462|  3.32k|            return union_vector16(set_2, (uint32_t)size_2, set_1,
 2463|  3.32k|                                  (uint32_t)size_1, buffer);
 2464|  3.32k|        }
 2465|  5.98k|    } else {
 2466|       |        // compute union with smallest array first
 2467|      0|        if (size_1 < size_2) {
  ------------------
  |  Branch (2467:13): [True: 0, False: 0]
  ------------------
 2468|      0|            return union_uint16(set_1, size_1, set_2, size_2, buffer);
 2469|      0|        } else {
 2470|      0|            return union_uint16(set_2, size_2, set_1, size_1, buffer);
 2471|      0|        }
 2472|      0|    }
 2473|       |#else
 2474|       |    // compute union with smallest array first
 2475|       |    if (size_1 < size_2) {
 2476|       |        return union_uint16(set_1, size_1, set_2, size_2, buffer);
 2477|       |    } else {
 2478|       |        return union_uint16(set_2, size_2, set_1, size_1, buffer);
 2479|       |    }
 2480|       |#endif
 2481|  5.98k|}
memequals:
 2587|  7.85k|bool memequals(const void *s1, const void *s2, size_t n) {
 2588|  7.85k|    if (n == 0) {
  ------------------
  |  Branch (2588:9): [True: 0, False: 7.85k]
  ------------------
 2589|      0|        return true;
 2590|      0|    }
 2591|  7.85k|#if CROARING_IS_X64
 2592|  7.85k|    int support = croaring_hardware_support();
 2593|  7.85k|#if CROARING_COMPILER_SUPPORTS_AVX512
 2594|  7.85k|    if (support & ROARING_SUPPORTS_AVX512) {
  ------------------
  |  Branch (2594:9): [True: 0, False: 7.85k]
  ------------------
 2595|      0|        return _avx512_memequals(s1, s2, n);
 2596|      0|    } else
 2597|  7.85k|#endif  // CROARING_COMPILER_SUPPORTS_AVX512
 2598|  7.85k|        if (support & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (2598:13): [True: 7.85k, False: 0]
  ------------------
 2599|  7.85k|            return _avx2_memequals(s1, s2, n);
 2600|  7.85k|        } else {
 2601|      0|            return memcmp(s1, s2, n) == 0;
 2602|      0|        }
 2603|       |#else
 2604|       |    return memcmp(s1, s2, n) == 0;
 2605|       |#endif
 2606|  7.85k|}
array_util.c:binarySearch4:
  808|  1.13k|                          int32_t *index4) {
  809|  1.13k|    const uint16_t *base1 = array;
  810|  1.13k|    const uint16_t *base2 = array;
  811|  1.13k|    const uint16_t *base3 = array;
  812|  1.13k|    const uint16_t *base4 = array;
  813|  1.13k|    if (n == 0) return;
  ------------------
  |  Branch (813:9): [True: 0, False: 1.13k]
  ------------------
  814|  14.2k|    while (n > 1) {
  ------------------
  |  Branch (814:12): [True: 13.0k, False: 1.13k]
  ------------------
  815|  13.0k|        int32_t half = n >> 1;
  816|  13.0k|        base1 = (base1[half] < target1) ? &base1[half] : base1;
  ------------------
  |  Branch (816:17): [True: 1.01k, False: 12.0k]
  ------------------
  817|  13.0k|        base2 = (base2[half] < target2) ? &base2[half] : base2;
  ------------------
  |  Branch (817:17): [True: 1.97k, False: 11.1k]
  ------------------
  818|  13.0k|        base3 = (base3[half] < target3) ? &base3[half] : base3;
  ------------------
  |  Branch (818:17): [True: 2.46k, False: 10.6k]
  ------------------
  819|  13.0k|        base4 = (base4[half] < target4) ? &base4[half] : base4;
  ------------------
  |  Branch (819:17): [True: 2.85k, False: 10.2k]
  ------------------
  820|  13.0k|        n -= half;
  821|  13.0k|    }
  822|  1.13k|    *index1 = (int32_t)((*base1 < target1) + base1 - array);
  823|  1.13k|    *index2 = (int32_t)((*base2 < target2) + base2 - array);
  824|  1.13k|    *index3 = (int32_t)((*base3 < target3) + base3 - array);
  825|  1.13k|    *index4 = (int32_t)((*base4 < target4) + base4 - array);
  826|  1.13k|}
array_util.c:binarySearch2:
  837|    402|                          uint16_t target2, int32_t *index1, int32_t *index2) {
  838|    402|    const uint16_t *base1 = array;
  839|    402|    const uint16_t *base2 = array;
  840|    402|    if (n == 0) return;
  ------------------
  |  Branch (840:9): [True: 0, False: 402]
  ------------------
  841|  3.79k|    while (n > 1) {
  ------------------
  |  Branch (841:12): [True: 3.39k, False: 402]
  ------------------
  842|  3.39k|        int32_t half = n >> 1;
  843|  3.39k|        base1 = (base1[half] < target1) ? &base1[half] : base1;
  ------------------
  |  Branch (843:17): [True: 848, False: 2.54k]
  ------------------
  844|  3.39k|        base2 = (base2[half] < target2) ? &base2[half] : base2;
  ------------------
  |  Branch (844:17): [True: 1.41k, False: 1.97k]
  ------------------
  845|  3.39k|        n -= half;
  846|  3.39k|    }
  847|    402|    *index1 = (int32_t)((*base1 < target1) + base1 - array);
  848|    402|    *index2 = (int32_t)((*base2 < target2) + base2 - array);
  849|    402|}
array_util.c:croaring_equal4_uint16:
  985|  90.5k|                                          const uint16_t *b) {
  986|  90.5k|    uint64_t x, y;
  987|  90.5k|    memcpy(&x, a, sizeof(x));
  988|  90.5k|    memcpy(&y, b, sizeof(y));
  989|  90.5k|    return x == y;
  990|  90.5k|}
array_util.c:croaring_gallop_uint16:
 1000|  55.8k|                                            size_t n, uint16_t key) {
 1001|  55.8k|    if (lo >= n || array[lo] >= key) return lo;
  ------------------
  |  Branch (1001:9): [True: 318, False: 55.5k]
  |  Branch (1001:20): [True: 25.2k, False: 30.3k]
  ------------------
 1002|       |    // Invariant: array[lo] < key, and the answer is in (lo, hi], where
 1003|       |    // hi == n stands for a value >= key past the end.
 1004|  30.3k|    size_t step = 1, hi = lo + 1;
 1005|   101k|    while (hi < n && array[hi] < key) {
  ------------------
  |  Branch (1005:12): [True: 98.5k, False: 3.29k]
  |  Branch (1005:22): [True: 71.5k, False: 27.0k]
  ------------------
 1006|  71.5k|        lo = hi;
 1007|  71.5k|        step <<= 1;
 1008|  71.5k|        hi = lo + step;
 1009|  71.5k|    }
 1010|  30.3k|    if (hi > n) hi = n;
  ------------------
  |  Branch (1010:9): [True: 2.94k, False: 27.3k]
  ------------------
 1011|  30.3k|    size_t len = hi - lo;
 1012|  99.2k|    while (len > 1) {
  ------------------
  |  Branch (1012:12): [True: 68.9k, False: 30.3k]
  ------------------
 1013|  68.9k|        const size_t half = len >> 1;
 1014|  68.9k|        if (array[lo + half] < key) lo += half;
  ------------------
  |  Branch (1014:13): [True: 31.2k, False: 37.6k]
  ------------------
 1015|  68.9k|        len -= half;
 1016|  68.9k|    }
 1017|  30.3k|    return lo + 1;
 1018|  55.8k|}
array_util.c:union_skewed_uint16:
 1025|  2.32k|                                  uint16_t *out) {
 1026|  2.32k|    size_t pos = 0, j = 0;
 1027|  17.2k|    for (size_t i = 0; i < size_s; i++) {
  ------------------
  |  Branch (1027:24): [True: 14.9k, False: 2.32k]
  ------------------
 1028|  14.9k|        const uint16_t v = small[i];
 1029|  14.9k|        const size_t p = croaring_gallop_uint16(large, j, size_l, v);
 1030|  14.9k|        memmove(out + pos, large + j, (p - j) * sizeof(uint16_t));
 1031|  14.9k|        pos += p - j;
 1032|  14.9k|        j = p;
 1033|  14.9k|        out[pos++] = v;
 1034|  14.9k|        j += (j < size_l && large[j] == v);
  ------------------
  |  Branch (1034:15): [True: 14.6k, False: 303]
  |  Branch (1034:29): [True: 10.7k, False: 3.89k]
  ------------------
 1035|  14.9k|    }
 1036|  2.32k|    memmove(out + pos, large + j, (size_l - j) * sizeof(uint16_t));
 1037|  2.32k|    return pos + size_l - j;
 1038|  2.32k|}
array_util.c:difference_skewed_small_a2_uint16:
 1065|  1.42k|                                             uint16_t *a_out) {
 1066|  1.42k|    size_t i = 0, k = 0;
 1067|  24.8k|    for (int j = 0; j < length2 && i < (size_t)length1; j++) {
  ------------------
  |  Branch (1067:21): [True: 23.4k, False: 1.40k]
  |  Branch (1067:36): [True: 23.4k, False: 22]
  ------------------
 1068|  23.4k|        const uint16_t v = a2[j];
 1069|  23.4k|        const size_t p = croaring_gallop_uint16(a1, i, (size_t)length1, v);
 1070|  23.4k|        memmove(a_out + k, a1 + i, (p - i) * sizeof(uint16_t));
 1071|  23.4k|        k += p - i;
 1072|  23.4k|        i = p;
 1073|  23.4k|        i += (i < (size_t)length1 && a1[i] == v);
  ------------------
  |  Branch (1073:15): [True: 23.3k, False: 77]
  |  Branch (1073:38): [True: 23.1k, False: 239]
  ------------------
 1074|  23.4k|    }
 1075|  1.42k|    memmove(a_out + k, a1 + i, ((size_t)length1 - i) * sizeof(uint16_t));
 1076|  1.42k|    return (int)(k + (size_t)length1 - i);
 1077|  1.42k|}
array_util.c:difference_skewed_small_a1_uint16:
 1083|    371|                                             uint16_t *a_out) {
 1084|    371|    size_t j = 0, k = 0;
 1085|  2.23k|    for (int i = 0; i < length1; i++) {
  ------------------
  |  Branch (1085:21): [True: 1.86k, False: 371]
  ------------------
 1086|  1.86k|        const uint16_t v = a1[i];
 1087|  1.86k|        j = croaring_gallop_uint16(a2, j, (size_t)length2, v);
 1088|  1.86k|        a_out[k] = v;
 1089|  1.86k|        k += (j == (size_t)length2 || a2[j] != v);
  ------------------
  |  Branch (1089:15): [True: 54, False: 1.81k]
  |  Branch (1089:39): [True: 781, False: 1.03k]
  ------------------
 1090|  1.86k|    }
 1091|    371|    return (int)k;
 1092|    371|}
array_util.c:xor_skewed_uint16:
 1043|  2.81k|                                 uint16_t *out) {
 1044|  2.81k|    size_t pos = 0, j = 0;
 1045|  18.4k|    for (size_t i = 0; i < size_s; i++) {
  ------------------
  |  Branch (1045:24): [True: 15.5k, False: 2.81k]
  ------------------
 1046|  15.5k|        const uint16_t v = small[i];
 1047|  15.5k|        const size_t p = croaring_gallop_uint16(large, j, size_l, v);
 1048|  15.5k|        memcpy(out + pos, large + j, (p - j) * sizeof(uint16_t));
 1049|  15.5k|        pos += p - j;
 1050|  15.5k|        j = p;
 1051|  15.5k|        if (j < size_l && large[j] == v) {
  ------------------
  |  Branch (1051:13): [True: 15.2k, False: 340]
  |  Branch (1051:27): [True: 10.3k, False: 4.93k]
  ------------------
 1052|  10.3k|            j++;
 1053|  10.3k|        } else {
 1054|  5.27k|            out[pos++] = v;
 1055|  5.27k|        }
 1056|  15.5k|    }
 1057|  2.81k|    memcpy(out + pos, large + j, (size_l - j) * sizeof(uint16_t));
 1058|  2.81k|    return (int32_t)(pos + size_l - j);
 1059|  2.81k|}
array_util.c:sse_merge:
 1518|   318k|                             __m128i *vecMax) {
 1519|   318k|    const __m128i rev =
 1520|   318k|        _mm_setr_epi8(14, 15, 12, 13, 10, 11, 8, 9, 6, 7, 4, 5, 2, 3, 0, 1);
 1521|   318k|    __m128i x = a;
 1522|   318k|    __m128i y = _mm_shuffle_epi8(b, rev);
 1523|  1.59M|    for (int i = 0; i < 4; i++) {
  ------------------
  |  Branch (1523:21): [True: 1.27M, False: 318k]
  ------------------
 1524|  1.27M|        __m128i mn = _mm_min_epu16(x, y);
 1525|  1.27M|        __m128i mx = _mm_max_epu16(x, y);
 1526|  1.27M|        x = _mm_unpacklo_epi16(mn, mx);
 1527|  1.27M|        y = _mm_unpackhi_epi16(mn, mx);
 1528|  1.27M|    }
 1529|   318k|    *vecMin = x;
 1530|   318k|    *vecMax = y;
 1531|   318k|}
array_util.c:store_unique:
 1880|   128k|static inline int store_unique(__m128i old, __m128i newval, uint16_t *output) {
 1881|   128k|    __m128i vecTmp = _mm_alignr_epi8(newval, old, 16 - 2);
 1882|       |    // lots of high latency instructions follow (optimize?)
 1883|   128k|    int M = _mm_movemask_epi8(
 1884|   128k|        _mm_packs_epi16(_mm_cmpeq_epi16(vecTmp, newval), _mm_setzero_si128()));
 1885|   128k|    int numberofnewvalues = 8 - _mm_popcnt_u32(M);
 1886|   128k|    __m128i key = _mm_lddqu_si128((const __m128i *)uniqshuf + M);
 1887|   128k|    __m128i val = _mm_shuffle_epi8(newval, key);
 1888|   128k|    _mm_storeu_si128((__m128i *)output, val);
 1889|   128k|    return numberofnewvalues;
 1890|   128k|}
array_util.c:sort_uint16_short:
 1908|  9.85k|static inline void sort_uint16_short(uint16_t *z, uint32_t n) {
 1909|  98.2k|    for (uint32_t i = 1; i < n; i++) {
  ------------------
  |  Branch (1909:26): [True: 88.3k, False: 9.85k]
  ------------------
 1910|  88.3k|        uint16_t v = z[i];
 1911|  88.3k|        uint32_t j = i;
 1912|  91.4k|        while (j > 0 && z[j - 1] > v) {
  ------------------
  |  Branch (1912:16): [True: 91.4k, False: 18]
  |  Branch (1912:25): [True: 3.11k, False: 88.3k]
  ------------------
 1913|  3.11k|            z[j] = z[j - 1];
 1914|  3.11k|            j--;
 1915|  3.11k|        }
 1916|  88.3k|        z[j] = v;
 1917|  88.3k|    }
 1918|  9.85k|}
array_util.c:unique:
 1895|  4.88k|static inline uint32_t unique(uint16_t *out, uint32_t len) {
 1896|  4.88k|    uint32_t pos = 1;
 1897|  49.9k|    for (uint32_t i = 1; i < len; ++i) {
  ------------------
  |  Branch (1897:26): [True: 45.0k, False: 4.88k]
  ------------------
 1898|  45.0k|        if (out[i] != out[i - 1]) {
  ------------------
  |  Branch (1898:13): [True: 44.9k, False: 172]
  ------------------
 1899|  44.9k|            out[pos++] = out[i];
 1900|  44.9k|        }
 1901|  45.0k|    }
 1902|  4.88k|    return pos;
 1903|  4.88k|}
array_util.c:store_unique_xor:
 2202|   200k|                                   uint16_t *output) {
 2203|   200k|    __m128i vecTmp1 = _mm_alignr_epi8(newval, old, 16 - 4);
 2204|       |    __m128i vecTmp2 = _mm_alignr_epi8(newval, old, 16 - 2);
 2205|   200k|    __m128i equalleft = _mm_cmpeq_epi16(vecTmp2, vecTmp1);
 2206|   200k|    __m128i equalright = _mm_cmpeq_epi16(vecTmp2, newval);
 2207|   200k|    __m128i equalleftoright = _mm_or_si128(equalleft, equalright);
 2208|   200k|    int M = _mm_movemask_epi8(
 2209|   200k|        _mm_packs_epi16(equalleftoright, _mm_setzero_si128()));
 2210|   200k|    int numberofnewvalues = 8 - _mm_popcnt_u32(M);
 2211|   200k|    __m128i key = _mm_lddqu_si128((const __m128i *)uniqshuf + M);
 2212|   200k|    __m128i val = _mm_shuffle_epi8(vecTmp2, key);
 2213|   200k|    _mm_storeu_si128((__m128i *)output, val);
 2214|   200k|    return numberofnewvalues;
 2215|   200k|}
array_util.c:unique_xor:
 2220|  4.97k|static inline uint32_t unique_xor(uint16_t *out, uint32_t len) {
 2221|  4.97k|    uint32_t pos = 1;
 2222|  48.2k|    for (uint32_t i = 1; i < len; ++i) {
  ------------------
  |  Branch (2222:26): [True: 43.3k, False: 4.97k]
  ------------------
 2223|  43.3k|        if (out[i] != out[i - 1]) {
  ------------------
  |  Branch (2223:13): [True: 42.9k, False: 341]
  ------------------
 2224|  42.9k|            out[pos++] = out[i];
 2225|  42.9k|        } else
 2226|    341|            pos--;  // if it is identical to previous, delete it
 2227|  43.3k|    }
 2228|  4.97k|    return pos;
 2229|  4.97k|}
array_util.c:_avx2_memequals:
 2545|  7.85k|static inline bool _avx2_memequals(const void *s1, const void *s2, size_t n) {
 2546|  7.85k|    const uint8_t *ptr1 = (const uint8_t *)s1;
 2547|  7.85k|    const uint8_t *ptr2 = (const uint8_t *)s2;
 2548|  7.85k|    const uint8_t *end1 = ptr1 + n;
 2549|  7.85k|    const uint8_t *end8 = ptr1 + n / 8 * 8;
 2550|  7.85k|    const uint8_t *end32 = ptr1 + n / 32 * 32;
 2551|       |
 2552|   133k|    while (ptr1 < end32) {
  ------------------
  |  Branch (2552:12): [True: 126k, False: 7.80k]
  ------------------
 2553|   126k|        __m256i r1 = _mm256_loadu_si256((const __m256i *)ptr1);
 2554|   126k|        __m256i r2 = _mm256_loadu_si256((const __m256i *)ptr2);
 2555|   126k|        int mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(r1, r2));
 2556|   126k|        if ((uint32_t)mask != UINT32_MAX) {
  ------------------
  |  Branch (2556:13): [True: 54, False: 126k]
  ------------------
 2557|     54|            return false;
 2558|     54|        }
 2559|   126k|        ptr1 += 32;
 2560|   126k|        ptr2 += 32;
 2561|   126k|    }
 2562|       |
 2563|  14.9k|    while (ptr1 < end8) {
  ------------------
  |  Branch (2563:12): [True: 7.27k, False: 7.70k]
  ------------------
 2564|  7.27k|        uint64_t v1, v2;
 2565|  7.27k|        memcpy(&v1, ptr1, sizeof(uint64_t));
 2566|  7.27k|        memcpy(&v2, ptr2, sizeof(uint64_t));
 2567|  7.27k|        if (v1 != v2) {
  ------------------
  |  Branch (2567:13): [True: 103, False: 7.17k]
  ------------------
 2568|    103|            return false;
 2569|    103|        }
 2570|  7.17k|        ptr1 += 8;
 2571|  7.17k|        ptr2 += 8;
 2572|  7.17k|    }
 2573|       |
 2574|  27.7k|    while (ptr1 < end1) {
  ------------------
  |  Branch (2574:12): [True: 20.0k, False: 7.66k]
  ------------------
 2575|  20.0k|        if (*ptr1 != *ptr2) {
  ------------------
  |  Branch (2575:13): [True: 37, False: 20.0k]
  ------------------
 2576|     37|            return false;
 2577|     37|        }
 2578|  20.0k|        ptr1++;
 2579|  20.0k|        ptr2++;
 2580|  20.0k|    }
 2581|       |
 2582|  7.66k|    return true;
 2583|  7.70k|}

bitset_extract_setbits_avx2:
  762|  1.01k|                                   uint32_t base) {
  763|  1.01k|    if (outcapacity == 0) return 0;
  ------------------
  |  Branch (763:9): [True: 0, False: 1.01k]
  ------------------
  764|  1.01k|    uint32_t *initout = out;
  765|  1.01k|    __m256i baseVec = _mm256_set1_epi32(base - 1);
  766|  1.01k|    __m256i incVec = _mm256_set1_epi32(64);
  767|  1.01k|    __m256i add8 = _mm256_set1_epi32(8);
  768|  1.01k|    uint32_t *safeout = out + outcapacity;
  769|  1.01k|    size_t i = 0;
  770|   851k|    for (; (i < length) && (out + 64 <= safeout); ++i) {
  ------------------
  |  Branch (770:12): [True: 851k, False: 254]
  |  Branch (770:28): [True: 850k, False: 759]
  ------------------
  771|   850k|        uint64_t w = words[i];
  772|   850k|        if (w == 0) {
  ------------------
  |  Branch (772:13): [True: 98.1k, False: 752k]
  ------------------
  773|  98.1k|            baseVec = _mm256_add_epi32(baseVec, incVec);
  774|   752k|        } else {
  775|  3.76M|            for (int k = 0; k < 4; ++k) {
  ------------------
  |  Branch (775:29): [True: 3.01M, False: 752k]
  ------------------
  776|  3.01M|                uint8_t byteA = (uint8_t)w;
  777|  3.01M|                uint8_t byteB = (uint8_t)(w >> 8);
  778|  3.01M|                w >>= 16;
  779|  3.01M|                __m256i vecA =
  780|  3.01M|                    _mm256_loadu_si256((const __m256i *)vecDecodeTable[byteA]);
  781|  3.01M|                __m256i vecB =
  782|  3.01M|                    _mm256_loadu_si256((const __m256i *)vecDecodeTable[byteB]);
  783|  3.01M|                uint8_t advanceA = lengthTable[byteA];
  784|  3.01M|                uint8_t advanceB = lengthTable[byteB];
  785|  3.01M|                vecA = _mm256_add_epi32(baseVec, vecA);
  786|  3.01M|                baseVec = _mm256_add_epi32(baseVec, add8);
  787|  3.01M|                vecB = _mm256_add_epi32(baseVec, vecB);
  788|  3.01M|                baseVec = _mm256_add_epi32(baseVec, add8);
  789|  3.01M|                _mm256_storeu_si256((__m256i *)out, vecA);
  790|  3.01M|                out += advanceA;
  791|  3.01M|                _mm256_storeu_si256((__m256i *)out, vecB);
  792|  3.01M|                out += advanceB;
  793|  3.01M|            }
  794|   752k|        }
  795|   850k|    }
  796|  1.01k|    base += i * 64;
  797|  17.5k|    for (; (i < length) && (out < safeout); ++i) {
  ------------------
  |  Branch (797:12): [True: 17.1k, False: 390]
  |  Branch (797:28): [True: 16.5k, False: 623]
  ------------------
  798|  16.5k|        uint64_t w = words[i];
  799|  36.7k|        while ((w != 0) && (out < safeout)) {
  ------------------
  |  Branch (799:16): [True: 20.2k, False: 16.5k]
  |  Branch (799:28): [True: 20.2k, False: 0]
  ------------------
  800|  20.2k|            int r =
  801|  20.2k|                roaring_trailing_zeroes(w);  // on x64, should compile to TZCNT
  802|  20.2k|            uint32_t val = r + base;
  803|  20.2k|            memcpy(out, &val,
  804|  20.2k|                   sizeof(uint32_t));  // should be compiled as a MOV on x64
  805|  20.2k|            out++;
  806|  20.2k|            w &= (w - 1);
  807|  20.2k|        }
  808|  16.5k|        base += 64;
  809|  16.5k|    }
  810|  1.01k|    return out - initout;
  811|  1.01k|}
bitset_extract_setbits:
  817|    394|                              uint32_t *out, uint32_t base) {
  818|    394|    int outpos = 0;
  819|   403k|    for (size_t i = 0; i < length; ++i) {
  ------------------
  |  Branch (819:24): [True: 403k, False: 394]
  ------------------
  820|   403k|        uint64_t w = words[i];
  821|  2.25M|        while (w != 0) {
  ------------------
  |  Branch (821:16): [True: 1.84M, False: 403k]
  ------------------
  822|  1.84M|            int r =
  823|  1.84M|                roaring_trailing_zeroes(w);  // on x64, should compile to TZCNT
  824|  1.84M|            uint32_t val = r + base;
  825|  1.84M|            memcpy(out + outpos, &val,
  826|  1.84M|                   sizeof(uint32_t));  // should be compiled as a MOV on x64
  827|  1.84M|            outpos++;
  828|  1.84M|            w &= (w - 1);
  829|  1.84M|        }
  830|   403k|        base += 64;
  831|   403k|    }
  832|    394|    return outpos;
  833|    394|}
bitset_extract_setbits_uint16:
 1005|  2.84k|                                     uint16_t *out, uint16_t base) {
 1006|  2.84k|    int outpos = 0;
 1007|  2.91M|    for (size_t i = 0; i < length; ++i) {
  ------------------
  |  Branch (1007:24): [True: 2.91M, False: 2.84k]
  ------------------
 1008|  2.91M|        uint64_t w = words[i];
 1009|  5.97M|        while (w != 0) {
  ------------------
  |  Branch (1009:16): [True: 3.06M, False: 2.91M]
  ------------------
 1010|  3.06M|            int r = roaring_trailing_zeroes(w);
 1011|  3.06M|            out[outpos++] = (uint16_t)(r + base);
 1012|  3.06M|            w &= (w - 1);
 1013|  3.06M|        }
 1014|  2.91M|        base += 64;
 1015|  2.91M|    }
 1016|  2.84k|    return outpos;
 1017|  2.84k|}
bitset_clear_list:
 1185|  1.41k|                           uint64_t length) {
 1186|  1.41k|    if (croaring_hardware_support() & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (1186:9): [True: 1.41k, False: 0]
  ------------------
 1187|  1.41k|        return _asm_bitset_clear_list(words, card, list, length);
 1188|  1.41k|    } else {
 1189|      0|        return _scalar_bitset_clear_list(words, card, list, length);
 1190|      0|    }
 1191|  1.41k|}
bitset_set_list_withcard:
 1194|  1.36k|                                  const uint16_t *list, uint64_t length) {
 1195|  1.36k|    if (croaring_hardware_support() & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (1195:9): [True: 1.36k, False: 0]
  ------------------
 1196|  1.36k|        return _asm_bitset_set_list_withcard(words, card, list, length);
 1197|  1.36k|    } else {
 1198|      0|        return _scalar_bitset_set_list_withcard(words, card, list, length);
 1199|      0|    }
 1200|  1.36k|}
bitset_set_list:
 1202|    186|void bitset_set_list(uint64_t *words, const uint16_t *list, uint64_t length) {
 1203|    186|    if (croaring_hardware_support() & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (1203:9): [True: 186, False: 0]
  ------------------
 1204|    186|        _asm_bitset_set_list(words, list, length);
 1205|    186|    } else {
 1206|      0|        _scalar_bitset_set_list(words, list, length);
 1207|      0|    }
 1208|    186|}
bitset_flip_list_withcard:
 1264|  1.41k|                                   const uint16_t *list, uint64_t length) {
 1265|  1.41k|    uint64_t offset, load, newload, pos, index;
 1266|  1.41k|    const uint16_t *end = list + length;
 1267|  2.65M|    while (list != end) {
  ------------------
  |  Branch (1267:12): [True: 2.65M, False: 1.41k]
  ------------------
 1268|  2.65M|        pos = *list;
 1269|  2.65M|        offset = pos >> 6;
 1270|  2.65M|        index = pos % 64;
 1271|  2.65M|        load = words[offset];
 1272|  2.65M|        newload = load ^ (UINT64_C(1) << index);
 1273|       |        // todo: is a branch here all that bad?
 1274|  2.65M|        card +=
 1275|       |            (1 - 2 * (((UINT64_C(1) << index) & load) >> index));  // +1 or -1
 1276|  2.65M|        words[offset] = newload;
 1277|  2.65M|        list++;
 1278|  2.65M|    }
 1279|  1.41k|    return card;
 1280|  1.41k|}
bitset_util.c:_asm_bitset_clear_list:
 1106|  1.41k|                                              uint64_t length) {
 1107|  1.41k|    uint64_t offset, load, pos;
 1108|  1.41k|    uint64_t shift = 6;
 1109|  1.41k|    const uint16_t *end = list + length;
 1110|  1.41k|    if (!length) return card;
  ------------------
  |  Branch (1110:9): [True: 0, False: 1.41k]
  ------------------
 1111|       |    // btr is not available as an intrinsic in GCC
 1112|  1.41k|    __asm volatile(
 1113|  1.41k|        "1:\n"
 1114|  1.41k|        "movzwq (%[list]), %[pos]\n"
 1115|  1.41k|        "shrx %[shift], %[pos], %[offset]\n"
 1116|  1.41k|        "mov (%[words],%[offset],8), %[load]\n"
 1117|  1.41k|        "btr %[pos], %[load]\n"
 1118|  1.41k|        "mov %[load], (%[words],%[offset],8)\n"
 1119|  1.41k|        "sbb $0, %[card]\n"
 1120|  1.41k|        "add $2, %[list]\n"
 1121|  1.41k|        "cmp %[list], %[end]\n"
 1122|  1.41k|        "jnz 1b"
 1123|  1.41k|        : [card] "+&r"(card), [list] "+&r"(list), [load] "=&r"(load),
 1124|  1.41k|          [pos] "=&r"(pos), [offset] "=&r"(offset)
 1125|  1.41k|        : [end] "r"(end), [words] "r"(words), [shift] "r"(shift)
 1126|  1.41k|        :
 1127|  1.41k|        /* clobbers */ "memory");
 1128|  1.41k|    return card;
 1129|  1.41k|}
bitset_util.c:_asm_bitset_set_list_withcard:
 1024|  1.36k|                                                     uint64_t length) {
 1025|  1.36k|    uint64_t offset, load, pos;
 1026|  1.36k|    uint64_t shift = 6;
 1027|  1.36k|    const uint16_t *end = list + length;
 1028|  1.36k|    if (!length) return card;
  ------------------
  |  Branch (1028:9): [True: 0, False: 1.36k]
  ------------------
 1029|       |    // TODO: could unroll for performance, see bitset_set_list
 1030|       |    // bts is not available as an intrinsic in GCC
 1031|  1.36k|    __asm volatile(
 1032|  1.36k|        "1:\n"
 1033|  1.36k|        "movzwq (%[list]), %[pos]\n"
 1034|  1.36k|        "shrx %[shift], %[pos], %[offset]\n"
 1035|  1.36k|        "mov (%[words],%[offset],8), %[load]\n"
 1036|  1.36k|        "bts %[pos], %[load]\n"
 1037|  1.36k|        "mov %[load], (%[words],%[offset],8)\n"
 1038|  1.36k|        "sbb $-1, %[card]\n"
 1039|  1.36k|        "add $2, %[list]\n"
 1040|  1.36k|        "cmp %[list], %[end]\n"
 1041|  1.36k|        "jnz 1b"
 1042|  1.36k|        : [card] "+&r"(card), [list] "+&r"(list), [load] "=&r"(load),
 1043|  1.36k|          [pos] "=&r"(pos), [offset] "=&r"(offset)
 1044|  1.36k|        : [end] "r"(end), [words] "r"(words), [shift] "r"(shift));
 1045|  1.36k|    return card;
 1046|  1.36k|}
bitset_util.c:_asm_bitset_set_list:
 1049|    186|                                        uint64_t length) {
 1050|    186|    uint64_t pos;
 1051|    186|    const uint16_t *end = list + length;
 1052|       |
 1053|    186|    uint64_t shift = 6;
 1054|    186|    uint64_t offset;
 1055|    186|    uint64_t load;
 1056|  5.36k|    for (; list + 3 < end; list += 4) {
  ------------------
  |  Branch (1056:12): [True: 5.17k, False: 186]
  ------------------
 1057|  5.17k|        pos = list[0];
 1058|  5.17k|        __asm volatile(
 1059|  5.17k|            "shrx %[shift], %[pos], %[offset]\n"
 1060|  5.17k|            "mov (%[words],%[offset],8), %[load]\n"
 1061|  5.17k|            "bts %[pos], %[load]\n"
 1062|  5.17k|            "mov %[load], (%[words],%[offset],8)"
 1063|  5.17k|            : [load] "=&r"(load), [offset] "=&r"(offset)
 1064|  5.17k|            : [words] "r"(words), [shift] "r"(shift), [pos] "r"(pos));
 1065|  5.17k|        pos = list[1];
 1066|  5.17k|        __asm volatile(
 1067|  5.17k|            "shrx %[shift], %[pos], %[offset]\n"
 1068|  5.17k|            "mov (%[words],%[offset],8), %[load]\n"
 1069|  5.17k|            "bts %[pos], %[load]\n"
 1070|  5.17k|            "mov %[load], (%[words],%[offset],8)"
 1071|  5.17k|            : [load] "=&r"(load), [offset] "=&r"(offset)
 1072|  5.17k|            : [words] "r"(words), [shift] "r"(shift), [pos] "r"(pos));
 1073|  5.17k|        pos = list[2];
 1074|  5.17k|        __asm volatile(
 1075|  5.17k|            "shrx %[shift], %[pos], %[offset]\n"
 1076|  5.17k|            "mov (%[words],%[offset],8), %[load]\n"
 1077|  5.17k|            "bts %[pos], %[load]\n"
 1078|  5.17k|            "mov %[load], (%[words],%[offset],8)"
 1079|  5.17k|            : [load] "=&r"(load), [offset] "=&r"(offset)
 1080|  5.17k|            : [words] "r"(words), [shift] "r"(shift), [pos] "r"(pos));
 1081|  5.17k|        pos = list[3];
 1082|  5.17k|        __asm volatile(
 1083|  5.17k|            "shrx %[shift], %[pos], %[offset]\n"
 1084|  5.17k|            "mov (%[words],%[offset],8), %[load]\n"
 1085|  5.17k|            "bts %[pos], %[load]\n"
 1086|  5.17k|            "mov %[load], (%[words],%[offset],8)"
 1087|  5.17k|            : [load] "=&r"(load), [offset] "=&r"(offset)
 1088|  5.17k|            : [words] "r"(words), [shift] "r"(shift), [pos] "r"(pos));
 1089|  5.17k|    }
 1090|       |
 1091|    451|    while (list != end) {
  ------------------
  |  Branch (1091:12): [True: 265, False: 186]
  ------------------
 1092|    265|        pos = list[0];
 1093|    265|        __asm volatile(
 1094|    265|            "shrx %[shift], %[pos], %[offset]\n"
 1095|    265|            "mov (%[words],%[offset],8), %[load]\n"
 1096|    265|            "bts %[pos], %[load]\n"
 1097|    265|            "mov %[load], (%[words],%[offset],8)"
 1098|    265|            : [load] "=&r"(load), [offset] "=&r"(offset)
 1099|    265|            : [words] "r"(words), [shift] "r"(shift), [pos] "r"(pos));
 1100|    265|        list++;
 1101|    265|    }
 1102|    186|}

array_container_create_given_capacity:
   49|   149k|array_container_t *array_container_create_given_capacity(int32_t size) {
   50|   149k|    array_container_t *container;
   51|       |
   52|   149k|    if ((container = (array_container_t *)roaring_malloc(
  ------------------
  |  Branch (52:9): [True: 0, False: 149k]
  ------------------
   53|   149k|             sizeof(array_container_t))) == NULL) {
   54|      0|        return NULL;
   55|      0|    }
   56|       |
   57|   149k|    if (size <= 0) {  // we don't want to rely on malloc(0)
  ------------------
  |  Branch (57:9): [True: 88.4k, False: 61.5k]
  ------------------
   58|  88.4k|        container->array = NULL;
   59|  88.4k|    } else if ((container->array = (uint16_t *)roaring_malloc(sizeof(uint16_t) *
  ------------------
  |  Branch (59:16): [True: 0, False: 61.5k]
  ------------------
   60|  61.5k|                                                              size)) == NULL) {
   61|      0|        roaring_free(container);
   62|      0|        return NULL;
   63|      0|    }
   64|       |
   65|   149k|    container->capacity = size;
   66|   149k|    container->cardinality = 0;
   67|       |
   68|   149k|    return container;
   69|   149k|}
array_container_create:
   72|  28.9k|array_container_t *array_container_create(void) {
   73|  28.9k|    return array_container_create_given_capacity(ARRAY_DEFAULT_INIT_SIZE);
   74|  28.9k|}
array_container_create_range:
   77|    124|array_container_t *array_container_create_range(uint32_t min, uint32_t max) {
   78|    124|    array_container_t *answer =
   79|    124|        array_container_create_given_capacity(max - min + 1);
   80|    124|    if (answer == NULL) return answer;
  ------------------
  |  Branch (80:9): [True: 0, False: 124]
  ------------------
   81|    124|    answer->cardinality = 0;
   82|    248|    for (uint32_t k = min; k < max; k++) {
  ------------------
  |  Branch (82:28): [True: 124, False: 124]
  ------------------
   83|    124|        answer->array[answer->cardinality++] = k;
   84|    124|    }
   85|    124|    return answer;
   86|    124|}
array_container_clone:
   90|  23.5k|array_container_t *array_container_clone(const array_container_t *src) {
   91|  23.5k|    array_container_t *newcontainer =
   92|  23.5k|        array_container_create_given_capacity(src->capacity);
   93|  23.5k|    if (newcontainer == NULL) return NULL;
  ------------------
  |  Branch (93:9): [True: 0, False: 23.5k]
  ------------------
   94|       |
   95|  23.5k|    newcontainer->cardinality = src->cardinality;
   96|       |
   97|  23.5k|    memcpy(newcontainer->array, src->array,
   98|  23.5k|           src->cardinality * sizeof(uint16_t));
   99|       |
  100|  23.5k|    return newcontainer;
  101|  23.5k|}
array_container_shrink_to_fit:
  134|  4.76k|int array_container_shrink_to_fit(array_container_t *src) {
  135|  4.76k|    if (src->cardinality == src->capacity) return 0;  // nothing to do
  ------------------
  |  Branch (135:9): [True: 552, False: 4.21k]
  ------------------
  136|  4.21k|    int savings = src->capacity - src->cardinality;
  137|  4.21k|    src->capacity = src->cardinality;
  138|  4.21k|    if (src->capacity ==
  ------------------
  |  Branch (138:9): [True: 0, False: 4.21k]
  ------------------
  139|  4.21k|        0) {  // we do not want to rely on realloc for zero allocs
  140|      0|        roaring_free(src->array);
  141|      0|        src->array = NULL;
  142|  4.21k|    } else {
  143|  4.21k|        uint16_t *oldarray = src->array;
  144|  4.21k|        src->array = (uint16_t *)roaring_realloc(
  145|  4.21k|            oldarray, src->capacity * sizeof(uint16_t));
  146|  4.21k|        if (src->array == NULL) roaring_free(oldarray);  // should never happen?
  ------------------
  |  Branch (146:13): [True: 0, False: 4.21k]
  ------------------
  147|  4.21k|    }
  148|  4.21k|    return savings;
  149|  4.76k|}
array_container_free:
  152|   149k|void array_container_free(array_container_t *arr) {
  153|   149k|    if (arr == NULL) return;
  ------------------
  |  Branch (153:9): [True: 0, False: 149k]
  ------------------
  154|   149k|    roaring_free(arr->array);
  155|   149k|    roaring_free(arr);
  156|   149k|}
array_container_grow:
  170|   127k|                          bool preserve) {
  171|   127k|    int32_t max = (min <= DEFAULT_MAX_SIZE ? DEFAULT_MAX_SIZE : 65536);
  ------------------
  |  Branch (171:20): [True: 127k, False: 0]
  ------------------
  172|   127k|    int32_t new_capacity = clamp(grow_capacity(container->capacity), min, max);
  173|       |
  174|   127k|    container->capacity = new_capacity;
  175|   127k|    uint16_t *array = container->array;
  176|       |
  177|   127k|    if (preserve) {
  ------------------
  |  Branch (177:9): [True: 115k, False: 11.6k]
  ------------------
  178|   115k|        container->array =
  179|   115k|            (uint16_t *)roaring_realloc(array, new_capacity * sizeof(uint16_t));
  180|   115k|        if (container->array == NULL) roaring_free(array);
  ------------------
  |  Branch (180:13): [True: 0, False: 115k]
  ------------------
  181|   115k|    } else {
  182|  11.6k|        roaring_free(array);
  183|  11.6k|        container->array =
  184|  11.6k|            (uint16_t *)roaring_malloc(new_capacity * sizeof(uint16_t));
  185|  11.6k|    }
  186|       |
  187|       |    // if realloc fails, we have container->array == NULL.
  188|   127k|}
array_container_copy:
  192|     16|                          array_container_t *dst) {
  193|     16|    const int32_t cardinality = src->cardinality;
  194|     16|    if (cardinality > dst->capacity) {
  ------------------
  |  Branch (194:9): [True: 16, False: 0]
  ------------------
  195|     16|        array_container_grow(dst, cardinality, false);
  196|     16|    }
  197|       |
  198|     16|    dst->cardinality = cardinality;
  199|     16|    memcpy(dst->array, src->array, cardinality * sizeof(uint16_t));
  200|     16|}
array_container_union:
  214|  6.89k|                           array_container_t *out) {
  215|  6.89k|    const int32_t card_1 = array_1->cardinality, card_2 = array_2->cardinality;
  216|  6.89k|    const int32_t max_cardinality = card_1 + card_2;
  217|       |
  218|  6.89k|    if (out->capacity < max_cardinality) {
  ------------------
  |  Branch (218:9): [True: 0, False: 6.89k]
  ------------------
  219|       |        array_container_grow(out, max_cardinality, false);
  220|      0|    }
  221|  6.89k|    out->cardinality = (int32_t)fast_union_uint16(
  222|  6.89k|        array_1->array, card_1, array_2->array, card_2, out->array);
  223|  6.89k|}
array_container_andnot:
  231|  7.92k|                            array_container_t *out) {
  232|  7.92k|    if (out->capacity < array_1->cardinality)
  ------------------
  |  Branch (232:9): [True: 3.45k, False: 4.47k]
  ------------------
  233|  3.45k|        array_container_grow(out, array_1->cardinality, false);
  234|  7.92k|#if CROARING_IS_X64
  235|       |    // difference_vector16 only vectorizes while 8 values remain on each
  236|       |    // side, and loses to the galloping scalar code when one side is
  237|       |    // much shorter.
  238|  7.92k|    const int32_t card_1 = array_1->cardinality, card_2 = array_2->cardinality;
  239|  7.92k|    const int32_t card_min = card_1 < card_2 ? card_1 : card_2;
  ------------------
  |  Branch (239:30): [True: 1.26k, False: 6.66k]
  ------------------
  240|  7.92k|    const int32_t card_max = card_1 < card_2 ? card_2 : card_1;
  ------------------
  |  Branch (240:30): [True: 1.26k, False: 6.66k]
  ------------------
  241|  7.92k|    const bool skewed = card_min < 8 || card_min * 128 < card_max;
  ------------------
  |  Branch (241:25): [True: 2.78k, False: 5.14k]
  |  Branch (241:41): [True: 117, False: 5.03k]
  ------------------
  242|  7.92k|    if (!skewed && (croaring_hardware_support() & ROARING_SUPPORTS_AVX2) &&
  ------------------
  |  Branch (242:9): [True: 5.03k, False: 2.89k]
  |  Branch (242:20): [True: 5.03k, False: 0]
  ------------------
  243|  5.03k|        (out != array_1) && (out != array_2)) {
  ------------------
  |  Branch (243:9): [True: 2.18k, False: 2.84k]
  |  Branch (243:29): [True: 2.18k, False: 0]
  ------------------
  244|  2.18k|        out->cardinality = difference_vector16(
  245|  2.18k|            array_1->array, array_1->cardinality, array_2->array,
  246|  2.18k|            array_2->cardinality, out->array);
  247|  5.74k|    } else {
  248|  5.74k|        out->cardinality =
  249|  5.74k|            difference_uint16(array_1->array, array_1->cardinality,
  250|  5.74k|                              array_2->array, array_2->cardinality, out->array);
  251|  5.74k|    }
  252|       |#else
  253|       |    out->cardinality =
  254|       |        difference_uint16(array_1->array, array_1->cardinality, array_2->array,
  255|       |                          array_2->cardinality, out->array);
  256|       |#endif
  257|  7.92k|}
array_container_xor:
  266|  9.28k|                         array_container_t *out) {
  267|  9.28k|    const int32_t card_1 = array_1->cardinality, card_2 = array_2->cardinality;
  268|  9.28k|    const int32_t max_cardinality = card_1 + card_2;
  269|  9.28k|    if (out->capacity < max_cardinality) {
  ------------------
  |  Branch (269:9): [True: 0, False: 9.28k]
  ------------------
  270|      0|        array_container_grow(out, max_cardinality, false);
  271|      0|    }
  272|       |
  273|  9.28k|#if CROARING_IS_X64
  274|  9.28k|    if (!(card_1 * CROARING_SKEWED_VECTOR_MERGE_RATIO < card_2 ||
  ------------------
  |  |  291|  9.28k|#define CROARING_SKEWED_VECTOR_MERGE_RATIO 32
  ------------------
  |  Branch (274:11): [True: 677, False: 8.60k]
  ------------------
  275|  8.60k|          card_2 * CROARING_SKEWED_VECTOR_MERGE_RATIO < card_1) &&
  ------------------
  |  |  291|  8.60k|#define CROARING_SKEWED_VECTOR_MERGE_RATIO 32
  ------------------
  |  Branch (275:11): [True: 315, False: 8.29k]
  ------------------
  276|  8.29k|        (croaring_hardware_support() & ROARING_SUPPORTS_AVX2)) {
  ------------------
  |  Branch (276:9): [True: 8.29k, False: 0]
  ------------------
  277|  8.29k|        out->cardinality =
  278|  8.29k|            xor_vector16(array_1->array, array_1->cardinality, array_2->array,
  279|  8.29k|                         array_2->cardinality, out->array);
  280|  8.29k|    } else {
  281|    992|        out->cardinality =
  282|    992|            xor_uint16(array_1->array, array_1->cardinality, array_2->array,
  283|    992|                       array_2->cardinality, out->array);
  284|    992|    }
  285|       |#else
  286|       |    out->cardinality =
  287|       |        xor_uint16(array_1->array, array_1->cardinality, array_2->array,
  288|       |                   array_2->cardinality, out->array);
  289|       |#endif
  290|  9.28k|}
array_container_intersection:
  302|  3.45k|                                  array_container_t *out) {
  303|  3.45k|    int32_t card_1 = array1->cardinality, card_2 = array2->cardinality,
  304|  3.45k|            min_card = minimum_int32(card_1, card_2);
  305|  3.45k|    const int threshold = 64;  // subject to tuning
  306|  3.45k|#if CROARING_IS_X64
  307|  3.45k|    if (out->capacity < min_card) {
  ------------------
  |  Branch (307:9): [True: 3.45k, False: 0]
  ------------------
  308|  3.45k|        array_container_grow(out, min_card + sizeof(__m128i) / sizeof(uint16_t),
  309|  3.45k|                             false);
  310|  3.45k|    }
  311|       |#else
  312|       |    if (out->capacity < min_card) {
  313|       |        array_container_grow(out, min_card, false);
  314|       |    }
  315|       |#endif
  316|       |
  317|  3.45k|    if (card_1 * threshold < card_2) {
  ------------------
  |  Branch (317:9): [True: 314, False: 3.14k]
  ------------------
  318|    314|        out->cardinality = intersect_skewed_uint16(
  319|    314|            array1->array, card_1, array2->array, card_2, out->array);
  320|  3.14k|    } else if (card_2 * threshold < card_1) {
  ------------------
  |  Branch (320:16): [True: 192, False: 2.94k]
  ------------------
  321|    192|        out->cardinality = intersect_skewed_uint16(
  322|    192|            array2->array, card_2, array1->array, card_1, out->array);
  323|  2.94k|    } else {
  324|  2.94k|#if CROARING_IS_X64
  325|  2.94k|        if (croaring_hardware_support() & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (325:13): [True: 2.94k, False: 0]
  ------------------
  326|  2.94k|            out->cardinality = intersect_vector16(
  327|  2.94k|                array1->array, card_1, array2->array, card_2, out->array);
  328|  2.94k|        } else {
  329|      0|            out->cardinality = intersect_uint16(
  330|      0|                array1->array, card_1, array2->array, card_2, out->array);
  331|      0|        }
  332|       |#else
  333|       |        out->cardinality = intersect_uint16(array1->array, card_1,
  334|       |                                            array2->array, card_2, out->array);
  335|       |#endif
  336|  2.94k|    }
  337|  3.45k|}
array_container_intersection_cardinality:
  342|  13.8k|                                             const array_container_t *array2) {
  343|  13.8k|    int32_t card_1 = array1->cardinality, card_2 = array2->cardinality;
  344|  13.8k|    const int threshold = 64;  // subject to tuning
  345|  13.8k|    if (card_1 * threshold < card_2) {
  ------------------
  |  Branch (345:9): [True: 1.25k, False: 12.5k]
  ------------------
  346|  1.25k|        return intersect_skewed_uint16_cardinality(array1->array, card_1,
  347|  1.25k|                                                   array2->array, card_2);
  348|  12.5k|    } else if (card_2 * threshold < card_1) {
  ------------------
  |  Branch (348:16): [True: 768, False: 11.7k]
  ------------------
  349|    768|        return intersect_skewed_uint16_cardinality(array2->array, card_2,
  350|    768|                                                   array1->array, card_1);
  351|  11.7k|    } else {
  352|  11.7k|#if CROARING_IS_X64
  353|  11.7k|        if (croaring_hardware_support() & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (353:13): [True: 11.7k, False: 0]
  ------------------
  354|  11.7k|            return intersect_vector16_cardinality(array1->array, card_1,
  355|  11.7k|                                                  array2->array, card_2);
  356|  11.7k|        } else {
  357|      0|            return intersect_uint16_cardinality(array1->array, card_1,
  358|      0|                                                array2->array, card_2);
  359|      0|        }
  360|       |#else
  361|       |        return intersect_uint16_cardinality(array1->array, card_1,
  362|       |                                            array2->array, card_2);
  363|       |#endif
  364|  11.7k|    }
  365|  13.8k|}
array_container_intersect:
  368|  3.45k|                               const array_container_t *array2) {
  369|  3.45k|    int32_t card_1 = array1->cardinality, card_2 = array2->cardinality;
  370|  3.45k|    const int threshold = 64;  // subject to tuning
  371|  3.45k|    if (card_1 * threshold < card_2) {
  ------------------
  |  Branch (371:9): [True: 314, False: 3.14k]
  ------------------
  372|    314|        return intersect_skewed_uint16_nonempty(array1->array, card_1,
  373|    314|                                                array2->array, card_2);
  374|  3.14k|    } else if (card_2 * threshold < card_1) {
  ------------------
  |  Branch (374:16): [True: 192, False: 2.94k]
  ------------------
  375|    192|        return intersect_skewed_uint16_nonempty(array2->array, card_2,
  376|    192|                                                array1->array, card_1);
  377|  2.94k|    } else {
  378|       |        // we do not bother vectorizing
  379|  2.94k|        return intersect_uint16_nonempty(array1->array, card_1, array2->array,
  380|  2.94k|                                         card_2);
  381|  2.94k|    }
  382|  3.45k|}
array_container_intersection_inplace:
  388|  5.67k|                                          const array_container_t *src_2) {
  389|  5.67k|    int32_t card_1 = src_1->cardinality, card_2 = src_2->cardinality;
  390|  5.67k|    const int threshold = 64;  // subject to tuning
  391|  5.67k|    if (card_1 * threshold < card_2) {
  ------------------
  |  Branch (391:9): [True: 0, False: 5.67k]
  ------------------
  392|      0|        src_1->cardinality = intersect_skewed_uint16(
  393|      0|            src_1->array, card_1, src_2->array, card_2, src_1->array);
  394|  5.67k|    } else if (card_2 * threshold < card_1) {
  ------------------
  |  Branch (394:16): [True: 198, False: 5.47k]
  ------------------
  395|    198|        src_1->cardinality = intersect_skewed_uint16(
  396|    198|            src_2->array, card_2, src_1->array, card_1, src_1->array);
  397|  5.47k|    } else {
  398|  5.47k|#if CROARING_IS_X64
  399|  5.47k|        if (croaring_hardware_support() & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (399:13): [True: 5.47k, False: 0]
  ------------------
  400|  5.47k|            src_1->cardinality = intersect_vector16_inplace(
  401|  5.47k|                src_1->array, card_1, src_2->array, card_2);
  402|  5.47k|        } else {
  403|      0|            src_1->cardinality = intersect_uint16(
  404|      0|                src_1->array, card_1, src_2->array, card_2, src_1->array);
  405|      0|        }
  406|       |#else
  407|       |        src_1->cardinality = intersect_uint16(
  408|       |            src_1->array, card_1, src_2->array, card_2, src_1->array);
  409|       |#endif
  410|  5.47k|    }
  411|  5.67k|}
array_container_to_uint32_array:
  424|  6.59k|                                    uint32_t base) {
  425|  6.59k|#if CROARING_IS_X64
  426|  6.59k|    int support = croaring_hardware_support();
  427|  6.59k|#if CROARING_COMPILER_SUPPORTS_AVX512
  428|  6.59k|    if (support & ROARING_SUPPORTS_AVX512) {
  ------------------
  |  Branch (428:9): [True: 0, False: 6.59k]
  ------------------
  429|      0|        return avx512_array_container_to_uint32_array(vout, cont->array,
  430|      0|                                                      cont->cardinality, base);
  431|      0|    }
  432|  6.59k|#endif
  433|  6.59k|    if (support & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (433:9): [True: 6.59k, False: 0]
  ------------------
  434|  6.59k|        return array_container_to_uint32_array_vector16(
  435|  6.59k|            vout, cont->array, cont->cardinality, base);
  436|  6.59k|    }
  437|      0|#endif  // CROARING_IS_X64
  438|      0|    const size_t cardinality = (size_t)cont->cardinality;
  439|      0|    const uint16_t *array = cont->array;
  440|       |    // Typed stores vectorize on every compiler; all callers but
  441|       |    // roaring_bitmap_serialize pass an aligned vout.
  442|      0|    if (cardinality >= 4 && ((uintptr_t)vout & 3) == 0) {
  ------------------
  |  Branch (442:9): [True: 0, False: 0]
  |  Branch (442:29): [True: 0, False: 0]
  ------------------
  443|      0|        uint32_t *out = (uint32_t *)vout;
  444|      0|        uint32_t *out_end = out + cardinality;
  445|      0|        const uint16_t *array_end = array + cardinality;
  446|      0|        if (cardinality < 8) {  // overlapping writes end at cardinality
  ------------------
  |  Branch (446:13): [True: 0, False: 0]
  ------------------
  447|      0|            array_put(out, array, base, 4);
  448|      0|            array_put(out_end - 4, array_end - 4, base, 4);
  449|      0|            return (int)cardinality;
  450|      0|        }
  451|      0|        const size_t full = cardinality & ~(size_t)15;
  452|      0|        for (size_t i = 0; i < full; i += 16) {
  ------------------
  |  Branch (452:28): [True: 0, False: 0]
  ------------------
  453|      0|            array_put(out + i, array + i, base, 16);
  454|      0|        }
  455|      0|        if (cardinality - full > 8) {
  ------------------
  |  Branch (455:13): [True: 0, False: 0]
  ------------------
  456|      0|            array_put(out + full, array + full, base, 8);
  457|      0|        }
  458|      0|        if (full != cardinality) {
  ------------------
  |  Branch (458:13): [True: 0, False: 0]
  ------------------
  459|      0|            array_put(out_end - 8, array_end - 8, base, 8);
  460|      0|        }
  461|      0|        return (int)cardinality;
  462|      0|    }
  463|      0|    int outpos = 0;
  464|      0|    uint32_t *out = (uint32_t *)vout;
  465|      0|    size_t i = 0;
  466|      0|    for (; i < (size_t)cont->cardinality; ++i) {
  ------------------
  |  Branch (466:12): [True: 0, False: 0]
  ------------------
  467|      0|        const uint32_t val = base + cont->array[i];
  468|      0|        memcpy(out + outpos, &val,
  469|      0|               sizeof(uint32_t));  // should be compiled as a MOV on x64
  470|      0|        outpos++;
  471|      0|    }
  472|      0|    return outpos;
  473|      0|}
array_container_number_of_runs:
  542|  14.3k|int32_t array_container_number_of_runs(const array_container_t *ac) {
  543|  14.3k|    const uint16_t *array = ac->array;
  544|  14.3k|    const int32_t card = ac->cardinality;
  545|  14.3k|    if (card == 0) return 0;
  ------------------
  |  Branch (545:9): [True: 0, False: 14.3k]
  ------------------
  546|       |    // Every value starts a run unless it follows its predecessor. The values
  547|       |    // are strictly increasing, so array[i - 1] + 1 cannot wrap around to a
  548|       |    // match. The loop has no branch on the data and compilers vectorize it.
  549|  14.3k|    int32_t continuing = 0;
  550|  1.54M|    for (int32_t i = 1; i < card; ++i) {
  ------------------
  |  Branch (550:25): [True: 1.53M, False: 14.3k]
  ------------------
  551|  1.53M|        continuing += (array[i] == (uint16_t)(array[i - 1] + 1));
  552|  1.53M|    }
  553|  14.3k|    return card - continuing;
  554|  14.3k|}
array_container_write:
  562|  7.66k|int32_t array_container_write(const array_container_t *container, char *buf) {
  563|       |#if CROARING_IS_BIG_ENDIAN
  564|       |    for (int32_t i = 0; i < container->cardinality; ++i) {
  565|       |        uint16_t v_le = croaring_htole16(container->array[i]);
  566|       |        memcpy(buf + i * sizeof(uint16_t), &v_le, sizeof(uint16_t));
  567|       |    }
  568|       |#else
  569|  7.66k|    memcpy(buf, container->array, container->cardinality * sizeof(uint16_t));
  570|  7.66k|#endif
  571|  7.66k|    return array_container_size_in_bytes(container);
  572|  7.66k|}
array_container_is_subset:
  576|  7.18k|                               const array_container_t *container2) {
  577|  7.18k|    if (container1->cardinality > container2->cardinality) {
  ------------------
  |  Branch (577:9): [True: 1.20k, False: 5.98k]
  ------------------
  578|  1.20k|        return false;
  579|  1.20k|    }
  580|  5.98k|    int i1 = 0, i2 = 0;
  581|  45.6k|    while (i1 < container1->cardinality && i2 < container2->cardinality) {
  ------------------
  |  Branch (581:12): [True: 45.6k, False: 0]
  |  Branch (581:44): [True: 45.5k, False: 30]
  ------------------
  582|  45.5k|        if (container1->array[i1] == container2->array[i2]) {
  ------------------
  |  Branch (582:13): [True: 0, False: 45.5k]
  ------------------
  583|      0|            i1++;
  584|      0|            i2++;
  585|  45.5k|        } else if (container1->array[i1] > container2->array[i2]) {
  ------------------
  |  Branch (585:20): [True: 39.6k, False: 5.95k]
  ------------------
  586|  39.6k|            i2++;
  587|  39.6k|        } else {  // container1->array[i1] < container2->array[i2]
  588|  5.95k|            return false;
  589|  5.95k|        }
  590|  45.5k|    }
  591|     30|    if (i1 == container1->cardinality) {
  ------------------
  |  Branch (591:9): [True: 0, False: 30]
  ------------------
  592|      0|        return true;
  593|     30|    } else {
  594|       |        return false;
  595|     30|    }
  596|     30|}
array_container_read:
  599|  7.71k|                             const char *buf) {
  600|  7.71k|    if (container->capacity < cardinality) {
  ------------------
  |  Branch (600:9): [True: 0, False: 7.71k]
  ------------------
  601|      0|        array_container_grow(container, cardinality, false);
  602|      0|    }
  603|  7.71k|    container->cardinality = cardinality;
  604|       |#if CROARING_IS_BIG_ENDIAN
  605|       |    for (int32_t i = 0; i < cardinality; ++i) {
  606|       |        uint16_t v_le;
  607|       |        memcpy(&v_le, buf + i * sizeof(uint16_t), sizeof(uint16_t));
  608|       |        container->array[i] = croaring_letoh16(v_le);
  609|       |    }
  610|       |#else
  611|  7.71k|    memcpy(container->array, buf, container->cardinality * sizeof(uint16_t));
  612|  7.71k|#endif
  613|       |
  614|  7.71k|    return array_container_size_in_bytes(container);
  615|  7.71k|}
array_container_iterate:
  619|  7.26k|                             roaring_iterator iterator, void *ptr) {
  620|  2.37M|    for (int i = 0; i < cont->cardinality; i++)
  ------------------
  |  Branch (620:21): [True: 2.36M, False: 7.26k]
  ------------------
  621|  2.36M|        if (!iterator(cont->array[i] + base, ptr)) return false;
  ------------------
  |  Branch (621:13): [True: 0, False: 2.36M]
  ------------------
  622|  7.26k|    return true;
  623|  7.26k|}
array.c:clamp:
  165|   127k|static inline int32_t clamp(int32_t val, int32_t min, int32_t max) {
  166|   127k|    return ((val < min) ? min : (val > max) ? max : val);
  ------------------
  |  Branch (166:13): [True: 29.5k, False: 97.7k]
  |  Branch (166:33): [True: 250, False: 97.4k]
  ------------------
  167|   127k|}
array.c:grow_capacity:
  158|   127k|static inline int32_t grow_capacity(int32_t capacity) {
  159|   127k|    return (capacity <= 0)   ? ARRAY_DEFAULT_INIT_SIZE
  ------------------
  |  Branch (159:12): [True: 28.9k, False: 98.3k]
  ------------------
  160|   127k|           : capacity < 64   ? capacity * 2
  ------------------
  |  Branch (160:14): [True: 74.4k, False: 23.9k]
  ------------------
  161|  98.3k|           : capacity < 1024 ? capacity * 3 / 2
  ------------------
  |  Branch (161:14): [True: 23.6k, False: 310]
  ------------------
  162|  23.9k|                             : capacity * 5 / 4;
  163|   127k|}
array.c:minimum_int32:
  292|  3.45k|static inline int32_t minimum_int32(int32_t a, int32_t b) {
  293|  3.45k|    return (a < b) ? a : b;
  ------------------
  |  Branch (293:12): [True: 1.26k, False: 2.19k]
  ------------------
  294|  3.45k|}

bitset_container_clear:
   51|  71.4k|void bitset_container_clear(bitset_container_t *bitset) {
   52|  71.4k|    memset(bitset->words, 0, sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS);
   53|  71.4k|    bitset->cardinality = 0;
   54|  71.4k|}
bitset_container_set_all:
   56|     23|void bitset_container_set_all(bitset_container_t *bitset) {
   57|       |    memset(bitset->words, INT64_C(-1),
   58|     23|           sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS);
   59|     23|    bitset->cardinality = (1 << 16);
   60|     23|}
bitset_container_create:
   91|  71.4k|bitset_container_t *bitset_container_create(void) {
   92|  71.4k|    bitset_container_t *bitset = bitset_container_allocate();
   93|  71.4k|    if (bitset) {
  ------------------
  |  Branch (93:9): [True: 71.4k, False: 0]
  ------------------
   94|  71.4k|        bitset_container_clear(bitset);
   95|  71.4k|    }
   96|  71.4k|    return bitset;
   97|  71.4k|}
bitset_container_create_uninitialized:
   99|  66.2k|bitset_container_t *bitset_container_create_uninitialized(void) {
  100|  66.2k|    bitset_container_t *bitset = bitset_container_allocate();
  101|  66.2k|    if (bitset) {
  ------------------
  |  Branch (101:9): [True: 66.2k, False: 0]
  ------------------
  102|  66.2k|        bitset->cardinality = 0;
  103|  66.2k|    }
  104|  66.2k|    return bitset;
  105|  66.2k|}
bitset_container_copy:
  109|  3.67k|                           bitset_container_t *dest) {
  110|  3.67k|    dest->cardinality = source->cardinality;
  111|  3.67k|    memcpy(dest->words, source->words,
  112|  3.67k|           sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS);
  113|  3.67k|}
bitset_container_free:
  144|   271k|void bitset_container_free(bitset_container_t *bitset) {
  145|   271k|    if (bitset == NULL) return;
  ------------------
  |  Branch (145:9): [True: 0, False: 271k]
  ------------------
  146|   271k|    roaring_aligned_free(bitset->words);
  147|   271k|    roaring_free(bitset);
  148|   271k|}
bitset_container_clone:
  152|   133k|bitset_container_t *bitset_container_clone(const bitset_container_t *src) {
  153|   133k|    bitset_container_t *bitset =
  154|   133k|        (bitset_container_t *)roaring_malloc(sizeof(bitset_container_t));
  155|       |
  156|   133k|    if (!bitset) {
  ------------------
  |  Branch (156:9): [True: 0, False: 133k]
  ------------------
  157|      0|        return NULL;
  158|      0|    }
  159|       |
  160|   133k|    size_t align_size = 32;
  161|   133k|#if CROARING_IS_X64
  162|   133k|    if (croaring_hardware_support() & ROARING_SUPPORTS_AVX512) {
  ------------------
  |  Branch (162:9): [True: 0, False: 133k]
  ------------------
  163|       |        // sizeof(__m512i) == 64
  164|      0|        align_size = 64;
  165|   133k|    } else {
  166|       |        // sizeof(__m256i) == 32
  167|   133k|        align_size = 32;
  168|   133k|    }
  169|   133k|#endif
  170|   133k|    bitset->words = (uint64_t *)roaring_aligned_malloc(
  171|   133k|        align_size, sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS);
  172|   133k|    if (!bitset->words) {
  ------------------
  |  Branch (172:9): [True: 0, False: 133k]
  ------------------
  173|      0|        roaring_free(bitset);
  174|      0|        return NULL;
  175|      0|    }
  176|   133k|    bitset->cardinality = src->cardinality;
  177|   133k|    memcpy(bitset->words, src->words,
  178|   133k|           sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS);
  179|   133k|    return bitset;
  180|   133k|}
bitset_container_compute_cardinality:
  289|  3.12k|int bitset_container_compute_cardinality(const bitset_container_t *bitset) {
  290|  3.12k|    int support = croaring_hardware_support();
  291|  3.12k|#if CROARING_COMPILER_SUPPORTS_AVX512
  292|  3.12k|    if (support & ROARING_SUPPORTS_AVX512) {
  ------------------
  |  Branch (292:9): [True: 0, False: 3.12k]
  ------------------
  293|      0|        return (int)avx512_vpopcount(
  294|      0|            (const __m512i *)bitset->words,
  295|      0|            BITSET_CONTAINER_SIZE_IN_WORDS / (WORDS_IN_AVX512_REG));
  ------------------
  |  |  272|      0|#define WORDS_IN_AVX512_REG sizeof(__m512i) / sizeof(uint64_t)
  ------------------
  296|      0|    } else
  297|  3.12k|#endif  // CROARING_COMPILER_SUPPORTS_AVX512
  298|  3.12k|        if (support & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (298:13): [True: 3.12k, False: 0]
  ------------------
  299|  3.12k|            return (int)avx2_harley_seal_popcount256(
  300|  3.12k|                (const __m256i *)bitset->words,
  301|  3.12k|                BITSET_CONTAINER_SIZE_IN_WORDS / (CROARING_WORDS_IN_AVX2_REG));
  ------------------
  |  |  269|  3.12k|#define CROARING_WORDS_IN_AVX2_REG sizeof(__m256i) / sizeof(uint64_t)
  ------------------
  302|  3.12k|        } else {
  303|      0|            return _scalar_bitset_container_compute_cardinality(bitset);
  304|      0|        }
  305|  3.12k|}
bitset_container_and_nocard:
  747|  1.40k|                                         bitset_container_t *dst) {            \
  748|  1.40k|    int support = croaring_hardware_support();                                 \
  749|  1.40k|    if ( support & ROARING_SUPPORTS_AVX512 ) {                                 \
  ------------------
  |  Branch (749:10): [True: 0, False: 1.40k]
  ------------------
  750|      0|      return _avx512_bitset_container_##opname##_nocard(src_1, src_2, dst);    \
  751|      0|    }                                                                          \
  752|  1.40k|    else if ( support & ROARING_SUPPORTS_AVX2 ) {                              \
  ------------------
  |  Branch (752:15): [True: 1.40k, False: 0]
  ------------------
  753|  1.40k|      return _avx2_bitset_container_##opname##_nocard(src_1, src_2, dst);      \
  754|  1.40k|    } else {                                                                   \
  755|      0|      return _scalar_bitset_container_##opname##_nocard(src_1, src_2, dst);    \
  756|      0|    }                                                                          \
  757|  1.40k|  }                                                                            \
bitset_container_and_justcard:
  759|  1.40k|                                           const bitset_container_t *src_2) {  \
  760|  1.40k|     int support = croaring_hardware_support();                                \
  761|  1.40k|    if ( support & ROARING_SUPPORTS_AVX512 ) {                                 \
  ------------------
  |  Branch (761:10): [True: 0, False: 1.40k]
  ------------------
  762|      0|      return _avx512_bitset_container_##opname##_justcard(src_1, src_2);       \
  763|      0|    }                                                                          \
  764|  1.40k|    else if ( support & ROARING_SUPPORTS_AVX2 ) {                              \
  ------------------
  |  Branch (764:15): [True: 1.40k, False: 0]
  ------------------
  765|  1.40k|      return _avx2_bitset_container_##opname##_justcard(src_1, src_2);         \
  766|  1.40k|    } else {                                                                   \
  767|      0|      return _scalar_bitset_container_##opname##_justcard(src_1, src_2);       \
  768|      0|    }                                                                          \
  769|  1.40k|  }
bitset_container_xor:
  734|  1.35k|                                bitset_container_t *dst) {                     \
  735|  1.35k|    int support = croaring_hardware_support();                                 \
  736|  1.35k|    if ( support & ROARING_SUPPORTS_AVX512 ) {                                 \
  ------------------
  |  Branch (736:10): [True: 0, False: 1.35k]
  ------------------
  737|      0|      return _avx512_bitset_container_##opname(src_1, src_2, dst);             \
  738|      0|    }                                                                          \
  739|  1.35k|    else if ( support & ROARING_SUPPORTS_AVX2 ) {                              \
  ------------------
  |  Branch (739:15): [True: 1.35k, False: 0]
  ------------------
  740|  1.35k|      return _avx2_bitset_container_##opname(src_1, src_2, dst);               \
  741|  1.35k|    } else {                                                                   \
  742|      0|      return _scalar_bitset_container_##opname(src_1, src_2, dst);             \
  743|      0|    }                                                                          \
  744|  1.35k|  }                                                                            \
bitset_container_to_uint32_array:
  959|  1.40k|){
  960|  1.40k|#if CROARING_IS_X64
  961|  1.40k|   int support = croaring_hardware_support();
  962|  1.40k|#if CROARING_COMPILER_SUPPORTS_AVX512
  963|       |   // Unlike the AVX2 kernel, the AVX-512 one needs no cardinality heuristic:
  964|       |   // it skips empty words and only stores the blocks that carry a value, so it
  965|       |   // beat the scalar loop at every cardinality measured from 16 to 65536 (on
  966|       |   // an Emerald Rapids Xeon, 1.3x at 512 values, 6x at 4096, 7.5x at 8192).
  967|  1.40k|   if( support & ROARING_SUPPORTS_AVX512 )
  ------------------
  |  Branch (967:8): [True: 0, False: 1.40k]
  ------------------
  968|      0|		return (int) bitset_extract_setbits_avx512(bc->words,
  969|      0|                BITSET_CONTAINER_SIZE_IN_WORDS, out, bc->cardinality, base);
  970|  1.40k|   else
  971|  1.40k|#endif
  972|  1.40k|   if(( support & ROARING_SUPPORTS_AVX2 ) &&  (bc->cardinality >= 8192))  // heuristic
  ------------------
  |  Branch (972:7): [True: 1.40k, False: 0]
  |  Branch (972:47): [True: 1.01k, False: 394]
  ------------------
  973|  1.01k|		return (int) bitset_extract_setbits_avx2(bc->words,
  974|  1.01k|                BITSET_CONTAINER_SIZE_IN_WORDS, out, bc->cardinality, base);
  975|    394|	else
  976|    394|		return (int) bitset_extract_setbits(bc->words,
  977|    394|                BITSET_CONTAINER_SIZE_IN_WORDS, out, base);
  978|       |#else
  979|       |	return (int) bitset_extract_setbits(bc->words,
  980|       |                BITSET_CONTAINER_SIZE_IN_WORDS, out, base);
  981|       |#endif
  982|  1.40k|}
bitset_container_write:
 1078|  66.2k|                                  char *buf) {
 1079|       |#if CROARING_IS_BIG_ENDIAN
 1080|       |	for (int32_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i) {
 1081|       |		uint64_t w_le = croaring_htole64(container->words[i]);
 1082|       |		memcpy(buf + i * sizeof(uint64_t), &w_le, sizeof(uint64_t));
 1083|       |	}
 1084|       |#else
 1085|  66.2k|	memcpy(buf, container->words, BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t));
 1086|  66.2k|#endif
 1087|  66.2k|	return bitset_container_size_in_bytes(container);
 1088|  66.2k|}
bitset_container_read:
 1092|  66.2k|		const char *buf)  {
 1093|  66.2k|	container->cardinality = cardinality;
 1094|       |#if CROARING_IS_BIG_ENDIAN
 1095|       |	for (int32_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i) {
 1096|       |		uint64_t w_le;
 1097|       |		memcpy(&w_le, buf + i * sizeof(uint64_t), sizeof(uint64_t));
 1098|       |		container->words[i] = croaring_letoh64(w_le);
 1099|       |	}
 1100|       |#else
 1101|  66.2k|	memcpy(container->words, buf, BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t));
 1102|  66.2k|#endif
 1103|  66.2k|	return bitset_container_size_in_bytes(container);
 1104|  66.2k|}
bitset_container_iterate:
 1107|  1.44k|bool bitset_container_iterate(const bitset_container_t *cont, uint32_t base, roaring_iterator iterator, void *ptr) {
 1108|  1.47M|  for (int32_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i ) {
  ------------------
  |  Branch (1108:23): [True: 1.47M, False: 1.44k]
  ------------------
 1109|  1.47M|    uint64_t w = cont->words[i];
 1110|  59.4M|    while (w != 0) {
  ------------------
  |  Branch (1110:12): [True: 57.9M, False: 1.47M]
  ------------------
 1111|  57.9M|      uint64_t t = w & (~w + 1);
 1112|  57.9M|      int r = roaring_trailing_zeroes(w);
 1113|  57.9M|      if(!iterator(r + base, ptr)) return false;
  ------------------
  |  Branch (1113:10): [True: 0, False: 57.9M]
  ------------------
 1114|  57.9M|      w ^= t;
 1115|  57.9M|    }
 1116|  1.47M|    base += 64;
 1117|  1.47M|  }
 1118|  1.44k|  return true;
 1119|  1.44k|}
bitset_container_equals:
 1174|  66.2k|bool bitset_container_equals(const bitset_container_t *container1, const bitset_container_t *container2) {
 1175|  66.2k|  if((container1->cardinality != BITSET_UNKNOWN_CARDINALITY) && (container2->cardinality != BITSET_UNKNOWN_CARDINALITY)) {
  ------------------
  |  Branch (1175:6): [True: 66.2k, False: 0]
  |  Branch (1175:65): [True: 66.2k, False: 0]
  ------------------
 1176|  66.2k|    if(container1->cardinality != container2->cardinality) {
  ------------------
  |  Branch (1176:8): [True: 0, False: 66.2k]
  ------------------
 1177|      0|      return false;
 1178|      0|    }
 1179|  66.2k|    if (container1->cardinality == INT32_C(0x10000)) {
  ------------------
  |  Branch (1179:9): [True: 62.4k, False: 3.80k]
  ------------------
 1180|  62.4k|      return true;
 1181|  62.4k|    }
 1182|  66.2k|  }
 1183|  3.80k|#if CROARING_IS_X64
 1184|  3.80k|  int support = croaring_hardware_support();
 1185|  3.80k|#if CROARING_COMPILER_SUPPORTS_AVX512
 1186|  3.80k|  if( support & ROARING_SUPPORTS_AVX512 ) {
  ------------------
  |  Branch (1186:7): [True: 0, False: 3.80k]
  ------------------
 1187|      0|    return _avx512_bitset_container_equals(container1, container2);
 1188|      0|  }
 1189|  3.80k|  else
 1190|  3.80k|#endif
 1191|  3.80k|  if( support & ROARING_SUPPORTS_AVX2 ) {
  ------------------
  |  Branch (1191:7): [True: 3.80k, False: 0]
  ------------------
 1192|  3.80k|    return _avx2_bitset_container_equals(container1, container2);
 1193|  3.80k|  }
 1194|      0|#endif
 1195|      0|  return memcmp(container1->words,
 1196|      0|                container2->words,
 1197|      0|                BITSET_CONTAINER_SIZE_IN_WORDS*sizeof(uint64_t)) == 0;
 1198|  3.80k|}
bitset_container_minimum:
 1251|  1.16k|uint16_t bitset_container_minimum(const bitset_container_t *container) {
 1252|  8.59k|  for (int32_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i ) {
  ------------------
  |  Branch (1252:23): [True: 8.59k, False: 0]
  ------------------
 1253|  8.59k|    uint64_t w = container->words[i];
 1254|  8.59k|    if (w != 0) {
  ------------------
  |  Branch (1254:9): [True: 1.16k, False: 7.42k]
  ------------------
 1255|  1.16k|      int r = roaring_trailing_zeroes(w);
 1256|  1.16k|      return r + i * 64;
 1257|  1.16k|    }
 1258|  8.59k|  }
 1259|      0|  return UINT16_MAX;
 1260|  1.16k|}
bitset_container_maximum:
 1264|  4.14k|uint16_t bitset_container_maximum(const bitset_container_t *container) {
 1265|   876k|  for (int32_t i = BITSET_CONTAINER_SIZE_IN_WORDS - 1; i > 0; --i ) {
  ------------------
  |  Branch (1265:56): [True: 876k, False: 0]
  ------------------
 1266|   876k|    uint64_t w = container->words[i];
 1267|   876k|    if (w != 0) {
  ------------------
  |  Branch (1267:9): [True: 4.14k, False: 872k]
  ------------------
 1268|  4.14k|      int r = roaring_leading_zeroes(w);
 1269|  4.14k|      return i * 64 + 63  - r;
 1270|  4.14k|    }
 1271|   876k|  }
 1272|      0|  return 0;
 1273|  4.14k|}
bitset_container_index_equalorlarger:
 1337|  1.78k|int bitset_container_index_equalorlarger(const bitset_container_t *container, uint16_t x) {
 1338|  1.78k|  uint32_t x32 = x;
 1339|  1.78k|  uint32_t k = x32 / 64;
 1340|  1.78k|  uint64_t word = container->words[k];
 1341|  1.78k|  const int diff = x32 - k * 64; // in [0,64)
 1342|  1.78k|  word = (word >> diff) << diff; // a mask is faster, but we don't care
 1343|  6.36k|  while(word == 0) {
  ------------------
  |  Branch (1343:9): [True: 4.57k, False: 1.78k]
  ------------------
 1344|  4.57k|    k++;
 1345|  4.57k|    if(k == BITSET_CONTAINER_SIZE_IN_WORDS) return -1;
  ------------------
  |  Branch (1345:8): [True: 0, False: 4.57k]
  ------------------
 1346|  4.57k|    word = container->words[k];
 1347|  4.57k|  }
 1348|  1.78k|  return k * 64 + roaring_trailing_zeroes(word);
 1349|  1.78k|}
bitset.c:bitset_container_allocate:
   62|   137k|static bitset_container_t *bitset_container_allocate(void) {
   63|   137k|    bitset_container_t *bitset =
   64|   137k|        (bitset_container_t *)roaring_malloc(sizeof(bitset_container_t));
   65|       |
   66|   137k|    if (!bitset) {
  ------------------
  |  Branch (66:9): [True: 0, False: 137k]
  ------------------
   67|      0|        return NULL;
   68|      0|    }
   69|       |
   70|   137k|    size_t align_size = 32;
   71|   137k|#if CROARING_IS_X64
   72|   137k|    int support = croaring_hardware_support();
   73|   137k|    if (support & ROARING_SUPPORTS_AVX512) {
  ------------------
  |  Branch (73:9): [True: 0, False: 137k]
  ------------------
   74|       |        // sizeof(__m512i) == 64
   75|      0|        align_size = 64;
   76|   137k|    } else {
   77|       |        // sizeof(__m256i) == 32
   78|   137k|        align_size = 32;
   79|   137k|    }
   80|   137k|#endif
   81|   137k|    bitset->words = (uint64_t *)roaring_aligned_malloc(
   82|   137k|        align_size, sizeof(uint64_t) * BITSET_CONTAINER_SIZE_IN_WORDS);
   83|   137k|    if (!bitset->words) {
  ------------------
  |  Branch (83:9): [True: 0, False: 137k]
  ------------------
   84|      0|        roaring_free(bitset);
   85|      0|        return NULL;
   86|      0|    }
   87|   137k|    return bitset;
   88|   137k|}
bitset.c:_avx2_bitset_container_and_nocard:
  523|  1.40k|      bitset_container_t *dst) {                                               \
  524|  1.40k|    const uint8_t *__restrict__ words_1 = (const uint8_t *)src_1->words;       \
  525|  1.40k|    const uint8_t *__restrict__ words_2 = (const uint8_t *)src_2->words;       \
  526|  1.40k|    /* not using the blocking optimization for some reason*/                   \
  527|  1.40k|    uint8_t *out = (uint8_t *)dst->words;                                      \
  528|  1.40k|    const int innerloop = 8;                                                   \
  529|  1.40k|    for (size_t i = 0;                                                         \
  530|  46.4k|         i < BITSET_CONTAINER_SIZE_IN_WORDS / (CROARING_WORDS_IN_AVX2_REG);             \
  ------------------
  |  |  269|  46.4k|#define CROARING_WORDS_IN_AVX2_REG sizeof(__m256i) / sizeof(uint64_t)
  ------------------
  |  Branch (530:10): [True: 45.0k, False: 1.40k]
  ------------------
  531|  45.0k|         i += innerloop) {                                                     \
  532|  45.0k|      __m256i A1, A2, AO;                                                      \
  533|  45.0k|      A1 = _mm256_loadu_si256((const __m256i *)(words_1));                     \
  534|  45.0k|      A2 = _mm256_loadu_si256((const __m256i *)(words_2));                     \
  535|  45.0k|      AO = avx_intrinsic(A2, A1);                                              \
  536|  45.0k|      _mm256_storeu_si256((__m256i *)out, AO);                                 \
  537|  45.0k|      A1 = _mm256_loadu_si256((const __m256i *)(words_1 + 32));                \
  538|  45.0k|      A2 = _mm256_loadu_si256((const __m256i *)(words_2 + 32));                \
  539|  45.0k|      AO = avx_intrinsic(A2, A1);                                              \
  540|  45.0k|      _mm256_storeu_si256((__m256i *)(out + 32), AO);                          \
  541|  45.0k|      A1 = _mm256_loadu_si256((const __m256i *)(words_1 + 64));                \
  542|  45.0k|      A2 = _mm256_loadu_si256((const __m256i *)(words_2 + 64));                \
  543|  45.0k|      AO = avx_intrinsic(A2, A1);                                              \
  544|  45.0k|      _mm256_storeu_si256((__m256i *)(out + 64), AO);                          \
  545|  45.0k|      A1 = _mm256_loadu_si256((const __m256i *)(words_1 + 96));                \
  546|  45.0k|      A2 = _mm256_loadu_si256((const __m256i *)(words_2 + 96));                \
  547|  45.0k|      AO = avx_intrinsic(A2, A1);                                              \
  548|  45.0k|      _mm256_storeu_si256((__m256i *)(out + 96), AO);                          \
  549|  45.0k|      A1 = _mm256_loadu_si256((const __m256i *)(words_1 + 128));               \
  550|  45.0k|      A2 = _mm256_loadu_si256((const __m256i *)(words_2 + 128));               \
  551|  45.0k|      AO = avx_intrinsic(A2, A1);                                              \
  552|  45.0k|      _mm256_storeu_si256((__m256i *)(out + 128), AO);                         \
  553|  45.0k|      A1 = _mm256_loadu_si256((const __m256i *)(words_1 + 160));               \
  554|  45.0k|      A2 = _mm256_loadu_si256((const __m256i *)(words_2 + 160));               \
  555|  45.0k|      AO = avx_intrinsic(A2, A1);                                              \
  556|  45.0k|      _mm256_storeu_si256((__m256i *)(out + 160), AO);                         \
  557|  45.0k|      A1 = _mm256_loadu_si256((const __m256i *)(words_1 + 192));               \
  558|  45.0k|      A2 = _mm256_loadu_si256((const __m256i *)(words_2 + 192));               \
  559|  45.0k|      AO = avx_intrinsic(A2, A1);                                              \
  560|  45.0k|      _mm256_storeu_si256((__m256i *)(out + 192), AO);                         \
  561|  45.0k|      A1 = _mm256_loadu_si256((const __m256i *)(words_1 + 224));               \
  562|  45.0k|      A2 = _mm256_loadu_si256((const __m256i *)(words_2 + 224));               \
  563|  45.0k|      AO = avx_intrinsic(A2, A1);                                              \
  564|  45.0k|      _mm256_storeu_si256((__m256i *)(out + 224), AO);                         \
  565|  45.0k|      out += 256;                                                              \
  566|  45.0k|      words_1 += 256;                                                          \
  567|  45.0k|      words_2 += 256;                                                          \
  568|  45.0k|    }                                                                          \
  569|  1.40k|    dst->cardinality = BITSET_UNKNOWN_CARDINALITY;                             \
  570|  1.40k|    return dst->cardinality;                                                   \
  571|  1.40k|  }
bitset.c:_avx2_bitset_container_and_justcard:
  592|  1.40k|      const bitset_container_t *src_1, const bitset_container_t *src_2) {      \
  593|  1.40k|    const __m256i *__restrict__ data1 = (const __m256i *)src_1->words;         \
  594|  1.40k|    const __m256i *__restrict__ data2 = (const __m256i *)src_2->words;         \
  595|  1.40k|    return (int)avx2_harley_seal_popcount256_##opname(                         \
  596|  1.40k|        data2, data1, BITSET_CONTAINER_SIZE_IN_WORDS / (CROARING_WORDS_IN_AVX2_REG));   \
  ------------------
  |  |  269|  1.40k|#define CROARING_WORDS_IN_AVX2_REG sizeof(__m256i) / sizeof(uint64_t)
  ------------------
  597|  1.40k|  }
bitset.c:_avx2_bitset_container_xor:
  578|  1.35k|                                      bitset_container_t *dst) {               \
  579|  1.35k|    const __m256i *__restrict__ words_1 = (const __m256i *)src_1->words;       \
  580|  1.35k|    const __m256i *__restrict__ words_2 = (const __m256i *)src_2->words;       \
  581|  1.35k|    __m256i *out = (__m256i *)dst->words;                                      \
  582|  1.35k|    dst->cardinality = (int32_t)avx2_harley_seal_popcount256andstore_##opname( \
  583|  1.35k|        words_2, words_1, out,                                                 \
  584|  1.35k|        BITSET_CONTAINER_SIZE_IN_WORDS / (CROARING_WORDS_IN_AVX2_REG));                 \
  ------------------
  |  |  269|  1.35k|#define CROARING_WORDS_IN_AVX2_REG sizeof(__m256i) / sizeof(uint64_t)
  ------------------
  585|  1.35k|    return dst->cardinality;                                                   \
  586|  1.35k|  }                                                                            \
bitset.c:_avx2_bitset_container_equals:
 1157|  3.80k|static inline bool _avx2_bitset_container_equals(const bitset_container_t *container1, const bitset_container_t *container2) {
 1158|  3.80k|    const __m256i *ptr1 = (const __m256i*)container1->words;
 1159|  3.80k|    const __m256i *ptr2 = (const __m256i*)container2->words;
 1160|   977k|    for (size_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS*sizeof(uint64_t)/32; i++) {
  ------------------
  |  Branch (1160:24): [True: 974k, False: 3.80k]
  ------------------
 1161|   974k|      __m256i r1 = _mm256_loadu_si256(ptr1+i);
 1162|   974k|      __m256i r2 = _mm256_loadu_si256(ptr2+i);
 1163|   974k|      int mask = _mm256_movemask_epi8(_mm256_cmpeq_epi8(r1, r2));
 1164|   974k|      if ((uint32_t)mask != UINT32_MAX) {
  ------------------
  |  Branch (1164:11): [True: 0, False: 974k]
  ------------------
 1165|      0|          return false;
 1166|      0|      }
 1167|   974k|  }
 1168|  3.80k|	return true;
 1169|  3.80k|}

container_free:
   58|   581k|void container_free(container_t *c, uint8_t type) {
   59|   581k|    switch (type) {
   60|   268k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|   268k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (60:9): [True: 268k, False: 313k]
  ------------------
   61|   268k|            bitset_container_free(CAST_bitset(c));
  ------------------
  |  |   52|   268k|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|   268k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
   62|   268k|            break;
   63|   134k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|   134k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (63:9): [True: 134k, False: 446k]
  ------------------
   64|   134k|            array_container_free(CAST_array(c));
  ------------------
  |  |   54|   134k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|   134k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
   65|   134k|            break;
   66|   178k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|   178k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (66:9): [True: 178k, False: 403k]
  ------------------
   67|   178k|            run_container_free(CAST_run(c));
  ------------------
  |  |   77|   178k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|   178k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
   68|   178k|            break;
   69|      0|        case SHARED_CONTAINER_TYPE:
  ------------------
  |  |   51|      0|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (69:9): [True: 0, False: 581k]
  ------------------
   70|      0|            shared_container_free(CAST_shared(c));
  ------------------
  |  |   79|      0|#define CAST_shared(c) CAST(shared_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
   71|      0|            break;
   72|      0|        default:
  ------------------
  |  Branch (72:9): [True: 0, False: 581k]
  ------------------
   73|      0|            assert(false);
   74|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
   75|   581k|    }
   76|   581k|}
get_copy_of_container:
  181|    192|                                   bool copy_on_write) {
  182|    192|    if (copy_on_write) {
  ------------------
  |  Branch (182:9): [True: 0, False: 192]
  ------------------
  183|      0|        shared_container_t *shared_container;
  184|      0|        if (*typecode == SHARED_CONTAINER_TYPE) {
  ------------------
  |  |   51|      0|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (184:13): [True: 0, False: 0]
  ------------------
  185|      0|            shared_container = CAST_shared(c);
  ------------------
  |  |   79|      0|#define CAST_shared(c) CAST(shared_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  186|      0|            croaring_refcount_inc(&shared_container->counter);
  187|      0|            return shared_container;
  188|      0|        }
  189|      0|        assert(*typecode != SHARED_CONTAINER_TYPE);
  190|       |
  191|      0|        if ((shared_container = (shared_container_t *)roaring_malloc(
  ------------------
  |  Branch (191:13): [True: 0, False: 0]
  ------------------
  192|      0|                 sizeof(shared_container_t))) == NULL) {
  193|      0|            return NULL;
  194|      0|        }
  195|       |
  196|      0|        shared_container->container = c;
  197|      0|        shared_container->typecode = *typecode;
  198|       |        // At this point, we are creating new shared container
  199|       |        // so there should be no other references, and setting
  200|       |        // the counter to 2 - even non-atomically - is safe as
  201|       |        // long as the value is set before the return statement.
  202|      0|        shared_container->counter = 2;
  203|      0|        *typecode = SHARED_CONTAINER_TYPE;
  ------------------
  |  |   51|      0|#define SHARED_CONTAINER_TYPE 4
  ------------------
  204|       |
  205|      0|        return shared_container;
  206|      0|    }  // copy_on_write
  207|       |    // otherwise, no copy on write...
  208|    192|    const container_t *actual_container = container_unwrap_shared(c, typecode);
  209|       |    assert(*typecode != SHARED_CONTAINER_TYPE);
  210|    192|    return container_clone(actual_container, *typecode);
  211|    192|}
container_clone:
  217|   315k|container_t *container_clone(const container_t *c, uint8_t typecode) {
  218|       |    // We do not want to allow cloning of shared containers.
  219|       |    // c = container_unwrap_shared(c, &typecode);
  220|   315k|    switch (typecode) {
  221|   133k|        case BITSET_CONTAINER_TYPE:
  ------------------
  |  |   48|   133k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (221:9): [True: 133k, False: 181k]
  ------------------
  222|   133k|            return bitset_container_clone(const_CAST_bitset(c));
  ------------------
  |  |   53|   133k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|   133k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  223|  23.5k|        case ARRAY_CONTAINER_TYPE:
  ------------------
  |  |   49|  23.5k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (223:9): [True: 23.5k, False: 291k]
  ------------------
  224|  23.5k|            return array_container_clone(const_CAST_array(c));
  ------------------
  |  |   55|  23.5k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  23.5k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  225|   158k|        case RUN_CONTAINER_TYPE:
  ------------------
  |  |   50|   158k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (225:9): [True: 158k, False: 156k]
  ------------------
  226|   158k|            return run_container_clone(const_CAST_run(c));
  ------------------
  |  |   78|   158k|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|   158k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  227|      0|        case SHARED_CONTAINER_TYPE:
  ------------------
  |  |   51|      0|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (227:9): [True: 0, False: 315k]
  ------------------
  228|       |            // Shared containers are not cloneable. Are you mixing COW and
  229|       |            // non-COW bitmaps?
  230|      0|            return NULL;
  231|      0|        default:
  ------------------
  |  Branch (231:9): [True: 0, False: 315k]
  ------------------
  232|      0|            assert(false);
  233|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  234|      0|            return NULL;
  235|   315k|    }
  236|   315k|}
container_init_iterator:
  306|  21.2k|                                                     uint16_t *value) {
  307|  21.2k|    switch (typecode) {
  308|  3.63k|        case BITSET_CONTAINER_TYPE: {
  ------------------
  |  |   48|  3.63k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (308:9): [True: 3.63k, False: 17.6k]
  ------------------
  309|  3.63k|            const bitset_container_t *bc = const_CAST_bitset(c);
  ------------------
  |  |   53|  3.63k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  3.63k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  310|  3.63k|            uint32_t wordindex = 0;
  311|  3.63k|            uint64_t word;
  312|  24.6k|            while ((word = bc->words[wordindex]) == 0) {
  ------------------
  |  Branch (312:20): [True: 20.9k, False: 3.63k]
  ------------------
  313|  20.9k|                wordindex++;
  314|  20.9k|            }
  315|       |            // word is non-zero
  316|  3.63k|            int32_t index = wordindex * 64 + roaring_trailing_zeroes(word);
  317|  3.63k|            *value = index;
  318|  3.63k|            return ROARING_INIT_ROARING_CONTAINER_ITERATOR_T{
  ------------------
  |  |   13|  3.63k|#define ROARING_INIT_ROARING_CONTAINER_ITERATOR_T (roaring_container_iterator_t)
  ------------------
  319|  3.63k|                .index = index,
  320|  3.63k|            };
  321|      0|        }
  322|  17.2k|        case ARRAY_CONTAINER_TYPE: {
  ------------------
  |  |   49|  17.2k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (322:9): [True: 17.2k, False: 4.06k]
  ------------------
  323|  17.2k|            const array_container_t *ac = const_CAST_array(c);
  ------------------
  |  |   55|  17.2k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  17.2k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  324|  17.2k|            *value = ac->array[0];
  325|  17.2k|            return ROARING_INIT_ROARING_CONTAINER_ITERATOR_T{
  ------------------
  |  |   13|  17.2k|#define ROARING_INIT_ROARING_CONTAINER_ITERATOR_T (roaring_container_iterator_t)
  ------------------
  326|  17.2k|                .index = 0,
  327|  17.2k|            };
  328|      0|        }
  329|    435|        case RUN_CONTAINER_TYPE: {
  ------------------
  |  |   50|    435|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (329:9): [True: 435, False: 20.8k]
  ------------------
  330|    435|            const run_container_t *rc = const_CAST_run(c);
  ------------------
  |  |   78|    435|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|    435|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  331|    435|            *value = rc->runs[0].value;
  332|    435|            return ROARING_INIT_ROARING_CONTAINER_ITERATOR_T{
  ------------------
  |  |   13|    435|#define ROARING_INIT_ROARING_CONTAINER_ITERATOR_T (roaring_container_iterator_t)
  ------------------
  333|    435|                .index = 0,
  334|    435|            };
  335|      0|        }
  336|      0|        default:
  ------------------
  |  Branch (336:9): [True: 0, False: 21.2k]
  ------------------
  337|      0|            assert(false);
  338|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  339|      0|            return ROARING_INIT_ROARING_CONTAINER_ITERATOR_T{0};
  ------------------
  |  |   13|      0|#define ROARING_INIT_ROARING_CONTAINER_ITERATOR_T (roaring_container_iterator_t)
  ------------------
  340|  21.2k|    }
  341|  21.2k|}
container_iterator_lower_bound:
  389|  7.09k|                                    uint16_t *value_out, uint16_t val) {
  390|  7.09k|    if (val > container_maximum(c, typecode)) {
  ------------------
  |  Branch (390:9): [True: 0, False: 7.09k]
  ------------------
  391|      0|        return false;
  392|      0|    }
  393|  7.09k|    switch (typecode) {
  394|  1.78k|        case BITSET_CONTAINER_TYPE: {
  ------------------
  |  |   48|  1.78k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  |  Branch (394:9): [True: 1.78k, False: 5.31k]
  ------------------
  395|  1.78k|            const bitset_container_t *bc = const_CAST_bitset(c);
  ------------------
  |  |   53|  1.78k|#define const_CAST_bitset(c) CAST(const bitset_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  1.78k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  396|  1.78k|            it->index = bitset_container_index_equalorlarger(bc, val);
  397|  1.78k|            *value_out = it->index;
  398|  1.78k|            return true;
  399|      0|        }
  400|  5.31k|        case ARRAY_CONTAINER_TYPE: {
  ------------------
  |  |   49|  5.31k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (400:9): [True: 5.31k, False: 1.78k]
  ------------------
  401|  5.31k|            const array_container_t *ac = const_CAST_array(c);
  ------------------
  |  |   55|  5.31k|#define const_CAST_array(c) CAST(const array_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|  5.31k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  402|  5.31k|            it->index = array_container_index_equalorlarger(ac, val);
  403|  5.31k|            *value_out = ac->array[it->index];
  404|  5.31k|            return true;
  405|      0|        }
  406|      0|        case RUN_CONTAINER_TYPE: {
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (406:9): [True: 0, False: 7.09k]
  ------------------
  407|      0|            const run_container_t *rc = const_CAST_run(c);
  ------------------
  |  |   78|      0|#define const_CAST_run(c) CAST(const run_container_t *, c)
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  408|      0|            it->index = run_container_index_equalorlarger(rc, val);
  409|      0|            if (rc->runs[it->index].value <= val) {
  ------------------
  |  Branch (409:17): [True: 0, False: 0]
  ------------------
  410|      0|                *value_out = val;
  411|      0|            } else {
  412|      0|                *value_out = rc->runs[it->index].value;
  413|      0|            }
  414|      0|            return true;
  415|      0|        }
  416|      0|        default:
  ------------------
  |  Branch (416:9): [True: 0, False: 7.09k]
  ------------------
  417|      0|            assert(false);
  418|      0|            roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  419|      0|            return false;
  420|  7.09k|    }
  421|  7.09k|}

bitset_container_from_array:
   23|  2.25k|bitset_container_t *bitset_container_from_array(const array_container_t *ac) {
   24|  2.25k|    bitset_container_t *ans = bitset_container_create();
   25|  2.25k|    int limit = array_container_cardinality(ac);
   26|  2.71M|    for (int i = 0; i < limit; ++i) bitset_container_set(ans, ac->array[i]);
  ------------------
  |  Branch (26:21): [True: 2.71M, False: 2.25k]
  ------------------
   27|  2.25k|    return ans;
   28|  2.25k|}
bitset_container_from_run:
   31|    441|bitset_container_t *bitset_container_from_run(const run_container_t *arr) {
   32|    441|    int card = run_container_cardinality(arr);
   33|    441|    bitset_container_t *answer = bitset_container_create();
   34|  19.6k|    for (int rlepos = 0; rlepos < arr->n_runs; ++rlepos) {
  ------------------
  |  Branch (34:26): [True: 19.2k, False: 441]
  ------------------
   35|  19.2k|        rle16_t vl = arr->runs[rlepos];
   36|  19.2k|        bitset_set_lenrange(answer->words, vl.value, vl.length);
   37|  19.2k|    }
   38|    441|    answer->cardinality = card;
   39|    441|    return answer;
   40|    441|}
array_container_from_run:
   42|  1.04k|array_container_t *array_container_from_run(const run_container_t *arr) {
   43|  1.04k|    array_container_t *answer =
   44|  1.04k|        array_container_create_given_capacity(run_container_cardinality(arr));
   45|  1.04k|    answer->cardinality = 0;
   46|  69.2k|    for (int rlepos = 0; rlepos < arr->n_runs; ++rlepos) {
  ------------------
  |  Branch (46:26): [True: 68.2k, False: 1.04k]
  ------------------
   47|  68.2k|        int run_start = arr->runs[rlepos].value;
   48|  68.2k|        int run_end = run_start + arr->runs[rlepos].length;
   49|       |
   50|   394k|        for (int run_value = run_start; run_value <= run_end; ++run_value) {
  ------------------
  |  Branch (50:41): [True: 326k, False: 68.2k]
  ------------------
   51|   326k|            answer->array[answer->cardinality++] = (uint16_t)run_value;
   52|   326k|        }
   53|  68.2k|    }
   54|  1.04k|    return answer;
   55|  1.04k|}
array_container_from_bitset:
   57|  2.76k|array_container_t *array_container_from_bitset(const bitset_container_t *bits) {
   58|  2.76k|    array_container_t *result =
   59|  2.76k|        array_container_create_given_capacity(bits->cardinality);
   60|  2.76k|    result->cardinality = bits->cardinality;
   61|  2.76k|#if CROARING_IS_X64
   62|  2.76k|#if CROARING_COMPILER_SUPPORTS_AVX512
   63|       |    // Every caller first checks that the cardinality fits an array container
   64|       |    // (<= DEFAULT_MAX_SIZE), so the input here is sparse: under 6.25% density,
   65|       |    // a couple of set bits per word.
   66|       |    // Below ~1024 values the vector decoder does not make back its per-word
   67|       |    // cost and the scalar loop is as fast or faster; from 1024 up it wins
   68|       |    // (1.2x at 1024, 1.4x at 4096, measured on an Emerald Rapids Xeon).
   69|  2.76k|    if ((bits->cardinality >= 1024) &&
  ------------------
  |  Branch (69:9): [True: 684, False: 2.08k]
  ------------------
   70|    684|        (croaring_hardware_support() & ROARING_SUPPORTS_AVX512)) {
  ------------------
  |  Branch (70:9): [True: 0, False: 684]
  ------------------
   71|      0|        bitset_extract_setbits_avx512_uint16(
   72|      0|            bits->words, BITSET_CONTAINER_SIZE_IN_WORDS, result->array,
   73|      0|            bits->cardinality, 0);
   74|      0|    } else
   75|  2.76k|#endif
   76|  2.76k|    {
   77|       |        //  sse version ends up being slower here
   78|       |        // (bitset_extract_setbits_sse_uint16)
   79|       |        // because of the sparsity of the data
   80|  2.76k|        bitset_extract_setbits_uint16(
   81|  2.76k|            bits->words, BITSET_CONTAINER_SIZE_IN_WORDS, result->array, 0);
   82|  2.76k|    }
   83|       |#else
   84|       |    // If the system is not x64, then we have no accelerated function.
   85|       |    bitset_extract_setbits_uint16(bits->words, BITSET_CONTAINER_SIZE_IN_WORDS,
   86|       |                                  result->array, 0);
   87|       |#endif
   88|       |
   89|  2.76k|    return result;
   90|  2.76k|}
convert_to_bitset_or_array_container:
  129|  66.0k|                                                  uint8_t *resulttype) {
  130|  66.0k|    if (card <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (130:9): [True: 1.17k, False: 64.8k]
  ------------------
  131|  1.17k|        array_container_t *answer = array_container_create_given_capacity(card);
  132|  1.17k|        answer->cardinality = 0;
  133|  56.2k|        for (int rlepos = 0; rlepos < rc->n_runs; ++rlepos) {
  ------------------
  |  Branch (133:30): [True: 55.0k, False: 1.17k]
  ------------------
  134|  55.0k|            uint16_t run_start = rc->runs[rlepos].value;
  135|  55.0k|            uint16_t run_end = run_start + rc->runs[rlepos].length;
  136|   638k|            for (uint16_t run_value = run_start; run_value < run_end;
  ------------------
  |  Branch (136:50): [True: 583k, False: 55.0k]
  ------------------
  137|   583k|                 ++run_value) {
  138|   583k|                answer->array[answer->cardinality++] = run_value;
  139|   583k|            }
  140|  55.0k|            answer->array[answer->cardinality++] = run_end;
  141|  55.0k|        }
  142|  1.17k|        assert(card == answer->cardinality);
  143|  1.17k|        *resulttype = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  1.17k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  144|       |        // run_container_free(r);
  145|  1.17k|        return answer;
  146|  1.17k|    }
  147|  64.8k|    bitset_container_t *answer = bitset_container_create();
  148|   161k|    for (int rlepos = 0; rlepos < rc->n_runs; ++rlepos) {
  ------------------
  |  Branch (148:26): [True: 96.9k, False: 64.8k]
  ------------------
  149|  96.9k|        uint16_t run_start = rc->runs[rlepos].value;
  150|  96.9k|        bitset_set_lenrange(answer->words, run_start, rc->runs[rlepos].length);
  151|  96.9k|    }
  152|  64.8k|    answer->cardinality = card;
  153|  64.8k|    *resulttype = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|  64.8k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  154|       |    // run_container_free(r);
  155|  64.8k|    return answer;
  156|  66.0k|}
convert_run_to_efficient_container:
  164|   125k|                                                uint8_t *typecode_after) {
  165|   125k|    int32_t size_as_run_container =
  166|   125k|        run_container_serialized_size_in_bytes(c->n_runs);
  167|       |
  168|   125k|    int32_t size_as_bitset_container =
  169|   125k|        bitset_container_serialized_size_in_bytes();
  170|   125k|    int32_t card = run_container_cardinality(c);
  171|   125k|    int32_t size_as_array_container =
  172|   125k|        array_container_serialized_size_in_bytes(card);
  173|       |
  174|   125k|    int32_t min_size_non_run =
  175|   125k|        size_as_bitset_container < size_as_array_container
  ------------------
  |  Branch (175:9): [True: 55.6k, False: 69.7k]
  ------------------
  176|   125k|            ? size_as_bitset_container
  177|   125k|            : size_as_array_container;
  178|   125k|    if (size_as_run_container <= min_size_non_run) {  // no conversion
  ------------------
  |  Branch (178:9): [True: 63.6k, False: 61.7k]
  ------------------
  179|  63.6k|        *typecode_after = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|  63.6k|#define RUN_CONTAINER_TYPE 3
  ------------------
  180|  63.6k|        return c;
  181|  63.6k|    }
  182|  61.7k|    if (card <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (182:9): [True: 61.7k, False: 0]
  ------------------
  183|       |        // to array
  184|  61.7k|        array_container_t *answer = array_container_create_given_capacity(card);
  185|  61.7k|        answer->cardinality = 0;
  186|   199k|        for (int rlepos = 0; rlepos < c->n_runs; ++rlepos) {
  ------------------
  |  Branch (186:30): [True: 137k, False: 61.7k]
  ------------------
  187|   137k|            int run_start = c->runs[rlepos].value;
  188|   137k|            int run_end = run_start + c->runs[rlepos].length;
  189|       |
  190|   367k|            for (int run_value = run_start; run_value <= run_end; ++run_value) {
  ------------------
  |  Branch (190:45): [True: 230k, False: 137k]
  ------------------
  191|   230k|                answer->array[answer->cardinality++] = (uint16_t)run_value;
  192|   230k|            }
  193|   137k|        }
  194|  61.7k|        *typecode_after = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  61.7k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  195|  61.7k|        return answer;
  196|  61.7k|    }
  197|       |
  198|       |    // else to bitset
  199|      0|    bitset_container_t *answer = bitset_container_create();
  200|       |
  201|      0|    for (int rlepos = 0; rlepos < c->n_runs; ++rlepos) {
  ------------------
  |  Branch (201:26): [True: 0, False: 0]
  ------------------
  202|      0|        int start = c->runs[rlepos].value;
  203|      0|        int end = start + c->runs[rlepos].length;
  204|      0|        bitset_set_range(answer->words, start, end + 1);
  205|      0|    }
  206|      0|    answer->cardinality = card;
  207|      0|    *typecode_after = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  208|      0|    return answer;
  209|  61.7k|}
convert_run_to_efficient_container_and_free:
  213|   113k|    run_container_t *c, uint8_t *typecode_after) {
  214|   113k|    container_t *answer = convert_run_to_efficient_container(c, typecode_after);
  215|   113k|    if (answer != c) run_container_free(c);
  ------------------
  |  Branch (215:9): [True: 54.8k, False: 58.5k]
  ------------------
  216|   113k|    return answer;
  217|   113k|}
convert_run_optimize:
  227|  14.3k|                                  uint8_t *typecode_after) {
  228|  14.3k|    if (typecode_original == RUN_CONTAINER_TYPE) {
  ------------------
  |  |   50|  14.3k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (228:9): [True: 0, False: 14.3k]
  ------------------
  229|      0|        container_t *newc =
  230|      0|            convert_run_to_efficient_container(CAST_run(c), typecode_after);
  ------------------
  |  |   77|      0|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  231|      0|        if (newc != c) {
  ------------------
  |  Branch (231:13): [True: 0, False: 0]
  ------------------
  232|      0|            container_free(c, typecode_original);
  233|      0|        }
  234|      0|        return newc;
  235|  14.3k|    } else if (typecode_original == ARRAY_CONTAINER_TYPE) {
  ------------------
  |  |   49|  14.3k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (235:16): [True: 14.3k, False: 0]
  ------------------
  236|       |        // it might need to be converted to a run container.
  237|  14.3k|        array_container_t *c_qua_array = CAST_array(c);
  ------------------
  |  |   54|  14.3k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  14.3k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  238|  14.3k|        int32_t n_runs = array_container_number_of_runs(c_qua_array);
  239|  14.3k|        int32_t size_as_run_container =
  240|  14.3k|            run_container_serialized_size_in_bytes(n_runs);
  241|  14.3k|        int32_t card = array_container_cardinality(c_qua_array);
  242|  14.3k|        int32_t size_as_array_container =
  243|  14.3k|            array_container_serialized_size_in_bytes(card);
  244|       |
  245|  14.3k|        if (size_as_run_container >= size_as_array_container) {
  ------------------
  |  Branch (245:13): [True: 10.6k, False: 3.76k]
  ------------------
  246|  10.6k|            *typecode_after = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  10.6k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  247|  10.6k|            return c;
  248|  10.6k|        }
  249|       |        // else convert array to run container
  250|  3.76k|        run_container_t *answer = run_container_create_given_capacity(n_runs);
  251|  3.76k|        int prev = -2;
  252|  3.76k|        int run_start = -1;
  253|       |
  254|  3.76k|        assert(card > 0);
  255|   576k|        for (int i = 0; i < card; ++i) {
  ------------------
  |  Branch (255:25): [True: 573k, False: 3.76k]
  ------------------
  256|   573k|            uint16_t cur_val = c_qua_array->array[i];
  257|   573k|            if (cur_val != prev + 1) {
  ------------------
  |  Branch (257:17): [True: 230k, False: 343k]
  ------------------
  258|       |                // new run starts; flush old one, if any
  259|   230k|                if (run_start != -1) add_run(answer, run_start, prev);
  ------------------
  |  Branch (259:21): [True: 226k, False: 3.76k]
  ------------------
  260|   230k|                run_start = cur_val;
  261|   230k|            }
  262|   573k|            prev = c_qua_array->array[i];
  263|   573k|        }
  264|  3.76k|        assert(run_start >= 0);
  265|       |        // now prev is the last seen value
  266|  3.76k|        add_run(answer, run_start, prev);
  267|  3.76k|        *typecode_after = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|  3.76k|#define RUN_CONTAINER_TYPE 3
  ------------------
  268|  3.76k|        array_container_free(c_qua_array);
  269|  3.76k|        return answer;
  270|  14.3k|    } else if (typecode_original ==
  ------------------
  |  Branch (270:16): [True: 0, False: 0]
  ------------------
  271|      0|               BITSET_CONTAINER_TYPE) {  // run conversions on bitset
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  272|       |        // does bitset need conversion to run?
  273|      0|        bitset_container_t *c_qua_bitset = CAST_bitset(c);
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  274|      0|        int32_t n_runs = bitset_container_number_of_runs(c_qua_bitset);
  275|      0|        int32_t size_as_run_container =
  276|      0|            run_container_serialized_size_in_bytes(n_runs);
  277|      0|        int32_t size_as_bitset_container =
  278|      0|            bitset_container_serialized_size_in_bytes();
  279|       |
  280|      0|        if (size_as_bitset_container <= size_as_run_container) {
  ------------------
  |  Branch (280:13): [True: 0, False: 0]
  ------------------
  281|       |            // no conversion needed.
  282|      0|            *typecode_after = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|      0|#define BITSET_CONTAINER_TYPE 1
  ------------------
  283|      0|            return c;
  284|      0|        }
  285|       |        // bitset to runcontainer (ported from Java  RunContainer(
  286|       |        // BitmapContainer bc, int nbrRuns))
  287|      0|        assert(n_runs > 0);  // no empty bitmaps
  288|      0|        run_container_t *answer = run_container_create_given_capacity(n_runs);
  289|       |
  290|      0|        int long_ctr = 0;
  291|      0|        uint64_t cur_word = c_qua_bitset->words[0];
  292|      0|        while (true) {
  ------------------
  |  Branch (292:16): [True: 0, Folded]
  ------------------
  293|      0|            while (cur_word == UINT64_C(0) &&
  ------------------
  |  Branch (293:20): [True: 0, False: 0]
  ------------------
  294|      0|                   long_ctr < BITSET_CONTAINER_SIZE_IN_WORDS - 1)
  ------------------
  |  Branch (294:20): [True: 0, False: 0]
  ------------------
  295|      0|                cur_word = c_qua_bitset->words[++long_ctr];
  296|       |
  297|      0|            if (cur_word == UINT64_C(0)) {
  ------------------
  |  Branch (297:17): [True: 0, False: 0]
  ------------------
  298|      0|                bitset_container_free(c_qua_bitset);
  299|      0|                *typecode_after = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
  300|      0|                return answer;
  301|      0|            }
  302|       |
  303|      0|            int local_run_start = roaring_trailing_zeroes(cur_word);
  304|      0|            int run_start = local_run_start + 64 * long_ctr;
  305|      0|            uint64_t cur_word_with_1s = cur_word | (cur_word - 1);
  306|       |
  307|      0|            int run_end = 0;
  308|      0|            while (cur_word_with_1s == UINT64_C(0xFFFFFFFFFFFFFFFF) &&
  ------------------
  |  Branch (308:20): [True: 0, False: 0]
  ------------------
  309|      0|                   long_ctr < BITSET_CONTAINER_SIZE_IN_WORDS - 1)
  ------------------
  |  Branch (309:20): [True: 0, False: 0]
  ------------------
  310|      0|                cur_word_with_1s = c_qua_bitset->words[++long_ctr];
  311|       |
  312|      0|            if (cur_word_with_1s == UINT64_C(0xFFFFFFFFFFFFFFFF)) {
  ------------------
  |  Branch (312:17): [True: 0, False: 0]
  ------------------
  313|      0|                run_end = 64 + long_ctr * 64;  // exclusive, I guess
  314|      0|                add_run(answer, run_start, run_end - 1);
  315|      0|                bitset_container_free(c_qua_bitset);
  316|      0|                *typecode_after = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
  317|      0|                return answer;
  318|      0|            }
  319|      0|            int local_run_end = roaring_trailing_zeroes(~cur_word_with_1s);
  320|      0|            run_end = local_run_end + long_ctr * 64;
  321|      0|            add_run(answer, run_start, run_end - 1);
  322|      0|            cur_word = cur_word_with_1s & (cur_word_with_1s + 1);
  323|      0|        }
  324|      0|        return answer;
  325|      0|    } else {
  326|      0|        assert(false);
  327|      0|        roaring_unreachable;
  ------------------
  |  |  246|      0|#define roaring_unreachable __builtin_unreachable()
  ------------------
  328|      0|        return NULL;
  329|      0|    }
  330|  14.3k|}
convert.c:add_run:
   93|   230k|static void add_run(run_container_t *rc, int s, int e) {
   94|   230k|    rc->runs[rc->n_runs].value = s;
   95|   230k|    rc->runs[rc->n_runs].length = e - s;
   96|   230k|    rc->n_runs++;
   97|   230k|}

array_bitset_container_andnot:
   26|    568|                                   array_container_t *dst) {
   27|       |    // follows Java implementation as of June 2016
   28|    568|    if (dst->capacity < src_1->cardinality) {
  ------------------
  |  Branch (28:9): [True: 568, False: 0]
  ------------------
   29|    568|        array_container_grow(dst, src_1->cardinality, false);
   30|    568|    }
   31|    568|    int32_t newcard = 0;
   32|    568|    const int32_t origcard = src_1->cardinality;
   33|    568|    const uint16_t *array = src_1->array;
   34|    568|    const uint64_t *words = src_2->words;
   35|    568|    uint16_t *out = dst->array;
   36|  94.2k|    for (int i = 0; i < origcard; ++i) {
  ------------------
  |  Branch (36:21): [True: 93.6k, False: 568]
  ------------------
   37|  93.6k|        uint16_t key = array[i];
   38|  93.6k|        out[newcard] = key;
   39|  93.6k|        newcard += 1 - ((words[key >> 6] >> (key & 63)) & 1);
   40|  93.6k|    }
   41|    568|    dst->cardinality = newcard;
   42|    568|}
bitset_array_container_iandnot:
   86|  1.38k|                                    container_t **dst) {
   87|  1.38k|    *dst = src_1;
   88|  1.38k|    src_1->cardinality =
   89|  1.38k|        (int32_t)bitset_clear_list(src_1->words, (uint64_t)src_1->cardinality,
   90|  1.38k|                                   src_2->array, (uint64_t)src_2->cardinality);
   91|       |
   92|  1.38k|    if (src_1->cardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (92:9): [True: 229, False: 1.16k]
  ------------------
   93|    229|        *dst = array_container_from_bitset(src_1);
   94|    229|        bitset_container_free(src_1);
   95|    229|        return false;  // not bitset
   96|    229|    } else
   97|  1.16k|        return true;
   98|  1.38k|}
run_bitset_container_andnot:
  109|    593|                                 container_t **dst) {
  110|       |    // follows the Java implementation as of June 2016
  111|    593|    int card = run_container_cardinality(src_1);
  112|    593|    if (card <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (112:9): [True: 593, False: 0]
  ------------------
  113|       |        // must be an array
  114|    593|        array_container_t *answer = array_container_create_given_capacity(card);
  115|    593|        answer->cardinality = 0;
  116|  46.5k|        for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) {
  ------------------
  |  Branch (116:34): [True: 45.9k, False: 593]
  ------------------
  117|  45.9k|            rle16_t rle = src_1->runs[rlepos];
  118|   168k|            for (int run_value = rle.value; run_value <= rle.value + rle.length;
  ------------------
  |  Branch (118:45): [True: 122k, False: 45.9k]
  ------------------
  119|   122k|                 ++run_value) {
  120|   122k|                if (!bitset_container_get(src_2, (uint16_t)run_value)) {
  ------------------
  |  Branch (120:21): [True: 34.9k, False: 87.4k]
  ------------------
  121|  34.9k|                    answer->array[answer->cardinality++] = (uint16_t)run_value;
  122|  34.9k|                }
  123|   122k|            }
  124|  45.9k|        }
  125|    593|        *dst = answer;
  126|    593|        return false;
  127|    593|    } else {  // we guess it will be a bitset, though have to check guess when
  128|       |              // done
  129|      0|        bitset_container_t *answer = bitset_container_clone(src_2);
  130|       |
  131|      0|        uint32_t last_pos = 0;
  132|      0|        for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) {
  ------------------
  |  Branch (132:34): [True: 0, False: 0]
  ------------------
  133|      0|            rle16_t rle = src_1->runs[rlepos];
  134|       |
  135|      0|            uint32_t start = rle.value;
  136|      0|            uint32_t end = start + rle.length + 1;
  137|      0|            bitset_reset_range(answer->words, last_pos, start);
  138|      0|            bitset_flip_range(answer->words, start, end);
  139|      0|            last_pos = end;
  140|      0|        }
  141|      0|        bitset_reset_range(answer->words, last_pos, (uint32_t)(1 << 16));
  142|       |
  143|      0|        answer->cardinality = bitset_container_compute_cardinality(answer);
  144|       |
  145|      0|        if (answer->cardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (145:13): [True: 0, False: 0]
  ------------------
  146|      0|            *dst = array_container_from_bitset(answer);
  147|      0|            bitset_container_free(answer);
  148|      0|            return false;  // not bitset
  149|      0|        }
  150|      0|        *dst = answer;
  151|       |        return true;  // bitset
  152|      0|    }
  153|    593|}
run_array_container_andnot:
  282|  1.76k|                               container_t **dst) {
  283|       |    // follows the Java impl as of June 2016
  284|       |
  285|  1.76k|    int card = run_container_cardinality(src_1);
  286|  1.76k|    const int arbitrary_threshold = 32;
  287|       |
  288|  1.76k|    if (card <= arbitrary_threshold) {
  ------------------
  |  Branch (288:9): [True: 340, False: 1.42k]
  ------------------
  289|    340|        if (src_2->cardinality == 0) {
  ------------------
  |  Branch (289:13): [True: 0, False: 340]
  ------------------
  290|      0|            *dst = run_container_clone(src_1);
  291|      0|            return RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
  292|      0|        }
  293|       |        // Java's "lazyandNot.toEfficientContainer" thing
  294|    340|        run_container_t *answer = run_container_create_given_capacity(
  295|    340|            card + array_container_cardinality(src_2));
  296|       |
  297|    340|        int rlepos = 0;
  298|    340|        int xrlepos = 0;  // "x" is src_2
  299|    340|        rle16_t rle = src_1->runs[rlepos];
  300|    340|        int32_t start = rle.value;
  301|    340|        int32_t end = start + rle.length + 1;
  302|    340|        int32_t xstart = src_2->array[xrlepos];
  303|       |
  304|  9.45k|        while ((rlepos < src_1->n_runs) && (xrlepos < src_2->cardinality)) {
  ------------------
  |  Branch (304:16): [True: 9.16k, False: 283]
  |  Branch (304:44): [True: 9.11k, False: 57]
  ------------------
  305|  9.11k|            if (end <= xstart) {
  ------------------
  |  Branch (305:17): [True: 559, False: 8.55k]
  ------------------
  306|       |                // output the first run
  307|    559|                answer->runs[answer->n_runs++] =
  308|    559|                    CROARING_MAKE_RLE16(start, end - start - 1);
  ------------------
  |  |   60|    559|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  309|    559|                rlepos++;
  310|    559|                if (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (310:21): [True: 518, False: 41]
  ------------------
  311|    518|                    start = src_1->runs[rlepos].value;
  312|    518|                    end = start + src_1->runs[rlepos].length + 1;
  313|    518|                }
  314|  8.55k|            } else if (xstart + 1 <= start) {
  ------------------
  |  Branch (314:24): [True: 4.98k, False: 3.57k]
  ------------------
  315|       |                // exit the second run
  316|  4.98k|                xrlepos++;
  317|  4.98k|                if (xrlepos < src_2->cardinality) {
  ------------------
  |  Branch (317:21): [True: 4.92k, False: 57]
  ------------------
  318|  4.92k|                    xstart = src_2->array[xrlepos];
  319|  4.92k|                }
  320|  4.98k|            } else {
  321|  3.57k|                if (start < xstart) {
  ------------------
  |  Branch (321:21): [True: 310, False: 3.26k]
  ------------------
  322|    310|                    answer->runs[answer->n_runs++] =
  323|    310|                        CROARING_MAKE_RLE16(start, xstart - start - 1);
  ------------------
  |  |   60|    310|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  324|    310|                }
  325|  3.57k|                if (xstart + 1 < end) {
  ------------------
  |  Branch (325:21): [True: 2.09k, False: 1.47k]
  ------------------
  326|  2.09k|                    start = xstart + 1;
  327|  2.09k|                } else {
  328|  1.47k|                    rlepos++;
  329|  1.47k|                    if (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (329:25): [True: 1.23k, False: 242]
  ------------------
  330|  1.23k|                        start = src_1->runs[rlepos].value;
  331|  1.23k|                        end = start + src_1->runs[rlepos].length + 1;
  332|  1.23k|                    }
  333|  1.47k|                }
  334|  3.57k|            }
  335|  9.11k|        }
  336|    340|        if (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (336:13): [True: 57, False: 283]
  ------------------
  337|     57|            answer->runs[answer->n_runs++] =
  338|     57|                CROARING_MAKE_RLE16(start, end - start - 1);
  ------------------
  |  |   60|     57|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  339|     57|            rlepos++;
  340|     57|            if (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (340:17): [True: 23, False: 34]
  ------------------
  341|     23|                memcpy(answer->runs + answer->n_runs, src_1->runs + rlepos,
  342|     23|                       (src_1->n_runs - rlepos) * sizeof(rle16_t));
  343|     23|                answer->n_runs += (src_1->n_runs - rlepos);
  344|     23|            }
  345|     57|        }
  346|    340|        uint8_t return_type;
  347|    340|        *dst = convert_run_to_efficient_container(answer, &return_type);
  348|    340|        if (answer != *dst) run_container_free(answer);
  ------------------
  |  Branch (348:13): [True: 203, False: 137]
  ------------------
  349|    340|        return return_type;
  350|    340|    }
  351|       |    // else it's a bitmap or array
  352|       |
  353|  1.42k|    if (card <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (353:9): [True: 1.17k, False: 252]
  ------------------
  354|  1.17k|        array_container_t *ac = array_container_create_given_capacity(card);
  355|       |        // nb Java code used a generic iterator-based merge to compute
  356|       |        // difference
  357|  1.17k|        ac->cardinality = run_array_array_subtract(src_1, src_2, ac);
  358|  1.17k|        *dst = ac;
  359|  1.17k|        return ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  1.17k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  360|  1.17k|    }
  361|    252|    bitset_container_t *ans = bitset_container_from_run(src_1);
  362|    252|    bool result_is_bitset = bitset_array_container_iandnot(ans, src_2, dst);
  363|    252|    return (result_is_bitset ? BITSET_CONTAINER_TYPE : ARRAY_CONTAINER_TYPE);
  ------------------
  |  |   48|    234|#define BITSET_CONTAINER_TYPE 1
  ------------------
                  return (result_is_bitset ? BITSET_CONTAINER_TYPE : ARRAY_CONTAINER_TYPE);
  ------------------
  |  |   49|     18|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (363:13): [True: 234, False: 18]
  ------------------
  364|  1.42k|}
run_array_container_iandnot:
  375|    668|                                container_t **dst) {
  376|       |    // dummy implementation same as June 2016 Java
  377|    668|    int ans = run_array_container_andnot(src_1, src_2, dst);
  378|    668|    run_container_free(src_1);
  379|    668|    return ans;
  380|    668|}
array_run_container_andnot:
  386|    693|                                array_container_t *dst) {
  387|       |    // basically following Java impl as of June 2016
  388|    693|    if (src_1->cardinality > dst->capacity) {
  ------------------
  |  Branch (388:9): [True: 648, False: 45]
  ------------------
  389|    648|        array_container_grow(dst, src_1->cardinality, false);
  390|    648|    }
  391|       |
  392|    693|    if (src_2->n_runs == 0) {
  ------------------
  |  Branch (392:9): [True: 0, False: 693]
  ------------------
  393|      0|        memmove(dst->array, src_1->array,
  394|      0|                sizeof(uint16_t) * src_1->cardinality);
  395|      0|        dst->cardinality = src_1->cardinality;
  396|      0|        return;
  397|      0|    }
  398|    693|    int32_t run_start = src_2->runs[0].value;
  399|    693|    int32_t run_end = run_start + src_2->runs[0].length;
  400|    693|    int which_run = 0;
  401|       |
  402|    693|    uint16_t val = 0;
  403|    693|    int dest_card = 0;
  404|   135k|    for (int i = 0; i < src_1->cardinality; ++i) {
  ------------------
  |  Branch (404:21): [True: 134k, False: 693]
  ------------------
  405|   134k|        val = src_1->array[i];
  406|   134k|        if (val < run_start)
  ------------------
  |  Branch (406:13): [True: 34.9k, False: 99.5k]
  ------------------
  407|  34.9k|            dst->array[dest_card++] = val;
  408|  99.5k|        else if (val <= run_end) {
  ------------------
  |  Branch (408:18): [True: 71.0k, False: 28.5k]
  ------------------
  409|  71.0k|            ;  // omitted item
  410|  71.0k|        } else {
  411|  40.1k|            do {
  412|  40.1k|                if (which_run + 1 < src_2->n_runs) {
  ------------------
  |  Branch (412:21): [True: 40.0k, False: 152]
  ------------------
  413|  40.0k|                    ++which_run;
  414|  40.0k|                    run_start = src_2->runs[which_run].value;
  415|  40.0k|                    run_end = run_start + src_2->runs[which_run].length;
  416|       |
  417|  40.0k|                } else
  418|    152|                    run_start = run_end = (1 << 16) + 1;
  419|  40.1k|            } while (val > run_end);
  ------------------
  |  Branch (419:22): [True: 11.6k, False: 28.5k]
  ------------------
  420|  28.5k|            --i;
  421|  28.5k|        }
  422|   134k|    }
  423|    693|    dst->cardinality = dest_card;
  424|    693|}
array_run_container_iandnot:
  431|     45|                                 const run_container_t *src_2) {
  432|     45|    array_run_container_andnot(src_1, src_2, src_1);
  433|     45|}
run_run_container_andnot:
  440|  1.17k|                             const run_container_t *src_2, container_t **dst) {
  441|  1.17k|    run_container_t *ans = run_container_create();
  442|  1.17k|    run_container_andnot(src_1, src_2, ans);
  443|  1.17k|    uint8_t typecode_after;
  444|  1.17k|    *dst = convert_run_to_efficient_container_and_free(ans, &typecode_after);
  445|  1.17k|    return typecode_after;
  446|  1.17k|}
run_run_container_iandnot:
  456|    471|                              const run_container_t *src_2, container_t **dst) {
  457|       |    // following Java impl as of June 2016 (dummy)
  458|    471|    int ans = run_run_container_andnot(src_1, src_2, dst);
  459|    471|    run_container_free(src_1);
  460|    471|    return ans;
  461|    471|}
array_array_container_andnot:
  469|  3.45k|                                  array_container_t *dst) {
  470|  3.45k|    array_container_andnot(src_1, src_2, dst);
  471|  3.45k|}
array_array_container_iandnot:
  476|  4.47k|                                   const array_container_t *src_2) {
  477|  4.47k|    array_container_andnot(src_1, src_2, src_1);
  478|  4.47k|}
mixed_andnot.c:run_array_array_subtract:
  238|  1.17k|                                    array_container_t *a_out) {
  239|  1.17k|    int out_card = 0;
  240|  1.17k|    int32_t in_array_pos =
  241|  1.17k|        -1;  // since advanceUntil always assumes we start the search AFTER this
  242|       |
  243|  80.6k|    for (int rlepos = 0; rlepos < rc->n_runs; rlepos++) {
  ------------------
  |  Branch (243:26): [True: 79.4k, False: 1.17k]
  ------------------
  244|  79.4k|        int32_t start = rc->runs[rlepos].value;
  245|  79.4k|        int32_t end = start + rc->runs[rlepos].length + 1;
  246|       |
  247|  79.4k|        in_array_pos = advanceUntil(a_in->array, in_array_pos,
  248|  79.4k|                                    a_in->cardinality, (uint16_t)start);
  249|       |
  250|  79.4k|        if (in_array_pos >= a_in->cardinality) {  // run has no items subtracted
  ------------------
  |  Branch (250:13): [True: 4.16k, False: 75.3k]
  ------------------
  251|  95.0k|            for (int32_t i = start; i < end; ++i)
  ------------------
  |  Branch (251:37): [True: 90.9k, False: 4.16k]
  ------------------
  252|  90.9k|                a_out->array[out_card++] = (uint16_t)i;
  253|  75.3k|        } else {
  254|  75.3k|            uint16_t next_nonincluded = a_in->array[in_array_pos];
  255|  75.3k|            if (next_nonincluded >= end) {
  ------------------
  |  Branch (255:17): [True: 25.9k, False: 49.3k]
  ------------------
  256|       |                // another case when run goes unaltered
  257|  72.0k|                for (int32_t i = start; i < end; ++i)
  ------------------
  |  Branch (257:41): [True: 46.0k, False: 25.9k]
  ------------------
  258|  46.0k|                    a_out->array[out_card++] = (uint16_t)i;
  259|  25.9k|                in_array_pos--;  // ensure we see this item again if necessary
  260|  49.3k|            } else {
  261|   262k|                for (int32_t i = start; i < end; ++i)
  ------------------
  |  Branch (261:41): [True: 213k, False: 49.3k]
  ------------------
  262|   213k|                    if (i != next_nonincluded)
  ------------------
  |  Branch (262:25): [True: 101k, False: 112k]
  ------------------
  263|   101k|                        a_out->array[out_card++] = (uint16_t)i;
  264|   112k|                    else  // 0 should ensure  we don't match
  265|   112k|                        next_nonincluded =
  266|   112k|                            (in_array_pos + 1 >= a_in->cardinality)
  ------------------
  |  Branch (266:29): [True: 918, False: 111k]
  ------------------
  267|   112k|                                ? 0
  268|   112k|                                : a_in->array[++in_array_pos];
  269|  49.3k|                in_array_pos--;  // see again
  270|  49.3k|            }
  271|  75.3k|        }
  272|  79.4k|    }
  273|  1.17k|    return out_card;
  274|  1.17k|}

array_container_equal_bitset:
   10|    385|                                  const bitset_container_t* container2) {
   11|    385|    if (container2->cardinality != BITSET_UNKNOWN_CARDINALITY) {
  ------------------
  |  Branch (11:9): [True: 385, False: 0]
  ------------------
   12|    385|        if (container2->cardinality != container1->cardinality) {
  ------------------
  |  Branch (12:13): [True: 385, False: 0]
  ------------------
   13|    385|            return false;
   14|    385|        }
   15|    385|    }
   16|      0|    int32_t pos = 0;
   17|      0|    for (int32_t i = 0; i < BITSET_CONTAINER_SIZE_IN_WORDS; ++i) {
  ------------------
  |  Branch (17:25): [True: 0, False: 0]
  ------------------
   18|      0|        uint64_t w = container2->words[i];
   19|      0|        while (w != 0) {
  ------------------
  |  Branch (19:16): [True: 0, False: 0]
  ------------------
   20|      0|            uint64_t t = w & (~w + 1);
   21|      0|            uint16_t r = i * 64 + roaring_trailing_zeroes(w);
   22|      0|            if (pos >= container1->cardinality) {
  ------------------
  |  Branch (22:17): [True: 0, False: 0]
  ------------------
   23|      0|                return false;
   24|      0|            }
   25|      0|            if (container1->array[pos] != r) {
  ------------------
  |  Branch (25:17): [True: 0, False: 0]
  ------------------
   26|      0|                return false;
   27|      0|            }
   28|      0|            ++pos;
   29|      0|            w ^= t;
   30|      0|        }
   31|      0|    }
   32|      0|    return (pos == container1->cardinality);
   33|      0|}
run_container_equals_array:
   36|    878|                                const array_container_t* container2) {
   37|    878|    if (run_container_cardinality(container1) != container2->cardinality)
  ------------------
  |  Branch (37:9): [True: 838, False: 40]
  ------------------
   38|    838|        return false;
   39|     40|    int32_t pos = 0;
   40|     40|    for (int i = 0; i < container1->n_runs; ++i) {
  ------------------
  |  Branch (40:21): [True: 40, False: 0]
  ------------------
   41|     40|        const uint32_t run_start = container1->runs[i].value;
   42|     40|        const uint32_t le = container1->runs[i].length;
   43|       |
   44|     40|        if (container2->array[pos] != run_start) {
  ------------------
  |  Branch (44:13): [True: 40, False: 0]
  ------------------
   45|     40|            return false;
   46|     40|        }
   47|       |
   48|      0|        if (container2->array[pos + le] != run_start + le) {
  ------------------
  |  Branch (48:13): [True: 0, False: 0]
  ------------------
   49|      0|            return false;
   50|      0|        }
   51|       |
   52|      0|        pos += le + 1;
   53|      0|    }
   54|      0|    return true;
   55|     40|}

array_bitset_container_intersection:
   21|    609|                                         array_container_t *dst) {
   22|    609|    if (dst->capacity < src_1->cardinality) {
  ------------------
  |  Branch (22:9): [True: 609, False: 0]
  ------------------
   23|    609|        array_container_grow(dst, src_1->cardinality, false);
   24|    609|    }
   25|    609|    int32_t newcard = 0;  // dst could be src_1
   26|    609|    const int32_t origcard = src_1->cardinality;
   27|    609|    const uint16_t *array = src_1->array;
   28|    609|    const uint64_t *words = src_2->words;
   29|    609|    uint16_t *out = dst->array;
   30|   261k|    for (int i = 0; i < origcard; ++i) {
  ------------------
  |  Branch (30:21): [True: 261k, False: 609]
  ------------------
   31|   261k|        uint16_t key = array[i];
   32|       |        // this branchless approach is much faster...
   33|   261k|        out[newcard] = key;
   34|   261k|        newcard += (words[key >> 6] >> (key & 63)) & 1;
   35|       |        /**
   36|       |         * we could do it this way instead...
   37|       |         * if (bitset_container_contains(src_2, key)) {
   38|       |         * dst->array[newcard++] = key;
   39|       |         * }
   40|       |         * but if the result is unpredictible, the processor generates
   41|       |         * many mispredicted branches.
   42|       |         * Difference can be huge (from 3 cycles when predictible all the way
   43|       |         * to 16 cycles when unpredictible.
   44|       |         * See
   45|       |         * https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/extra/bitset/c/arraybitsetintersection.c
   46|       |         */
   47|   261k|    }
   48|    609|    dst->cardinality = newcard;
   49|    609|}
array_bitset_container_intersection_cardinality:
   53|  2.27k|    const array_container_t *src_1, const bitset_container_t *src_2) {
   54|  2.27k|    int32_t newcard = 0;
   55|  2.27k|    const int32_t origcard = src_1->cardinality;
   56|   376k|    for (int i = 0; i < origcard; ++i) {
  ------------------
  |  Branch (56:21): [True: 374k, False: 2.27k]
  ------------------
   57|   374k|        uint16_t key = src_1->array[i];
   58|   374k|        newcard += bitset_container_contains(src_2, key);
   59|   374k|    }
   60|  2.27k|    return newcard;
   61|  2.27k|}
array_bitset_container_intersect:
   64|    568|                                      const bitset_container_t *src_2) {
   65|    568|    const int32_t origcard = src_1->cardinality;
   66|  2.86k|    for (int i = 0; i < origcard; ++i) {
  ------------------
  |  Branch (66:21): [True: 2.85k, False: 12]
  ------------------
   67|  2.85k|        uint16_t key = src_1->array[i];
   68|  2.85k|        if (bitset_container_contains(src_2, key)) return true;
  ------------------
  |  Branch (68:13): [True: 556, False: 2.30k]
  ------------------
   69|  2.85k|    }
   70|     12|    return false;
   71|    568|}
array_run_container_intersection:
   78|  2.81k|                                      array_container_t *dst) {
   79|  2.81k|    if (run_container_is_full(src_2)) {
  ------------------
  |  Branch (79:9): [True: 16, False: 2.80k]
  ------------------
   80|     16|        if (dst != src_1) array_container_copy(src_1, dst);
  ------------------
  |  Branch (80:13): [True: 16, False: 0]
  ------------------
   81|     16|        return;
   82|     16|    }
   83|  2.80k|    if (dst->capacity < src_1->cardinality) {
  ------------------
  |  Branch (83:9): [True: 2.80k, False: 0]
  ------------------
   84|  2.80k|        array_container_grow(dst, src_1->cardinality, false);
   85|  2.80k|    }
   86|  2.80k|    if (src_2->n_runs == 0) {
  ------------------
  |  Branch (86:9): [True: 0, False: 2.80k]
  ------------------
   87|      0|        return;
   88|      0|    }
   89|  2.80k|    int32_t rlepos = 0;
   90|  2.80k|    int32_t arraypos = 0;
   91|  2.80k|    rle16_t rle = src_2->runs[rlepos];
   92|  2.80k|    int32_t newcard = 0;
   93|   363k|    while (arraypos < src_1->cardinality) {
  ------------------
  |  Branch (93:12): [True: 360k, False: 2.31k]
  ------------------
   94|   360k|        const uint16_t arrayval = src_1->array[arraypos];
   95|   486k|        while (rle.value + rle.length <
  ------------------
  |  Branch (95:16): [True: 125k, False: 360k]
  ------------------
   96|   486k|               arrayval) {  // this will frequently be false
   97|   125k|            ++rlepos;
   98|   125k|            if (rlepos == src_2->n_runs) {
  ------------------
  |  Branch (98:17): [True: 482, False: 125k]
  ------------------
   99|    482|                dst->cardinality = newcard;
  100|    482|                return;  // we are done
  101|    482|            }
  102|   125k|            rle = src_2->runs[rlepos];
  103|   125k|        }
  104|   360k|        if (rle.value > arrayval) {
  ------------------
  |  Branch (104:13): [True: 24.6k, False: 335k]
  ------------------
  105|  24.6k|            arraypos = advanceUntil(src_1->array, arraypos, src_1->cardinality,
  106|  24.6k|                                    rle.value);
  107|   335k|        } else {
  108|   335k|            dst->array[newcard] = arrayval;
  109|   335k|            newcard++;
  110|   335k|            arraypos++;
  111|   335k|        }
  112|   360k|    }
  113|  2.31k|    dst->cardinality = newcard;
  114|  2.31k|}
run_bitset_container_intersection:
  122|    593|                                       container_t **dst) {
  123|    593|    if (run_container_is_full(src_1)) {
  ------------------
  |  Branch (123:9): [True: 0, False: 593]
  ------------------
  124|      0|        if (*dst != src_2) *dst = bitset_container_clone(src_2);
  ------------------
  |  Branch (124:13): [True: 0, False: 0]
  ------------------
  125|      0|        return true;
  126|      0|    }
  127|    593|    int32_t card = run_container_cardinality(src_1);
  128|    593|    if (card <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (128:9): [True: 593, False: 0]
  ------------------
  129|       |        // result can only be an array (assuming that we never make a
  130|       |        // RunContainer)
  131|    593|        if (card > src_2->cardinality) {
  ------------------
  |  Branch (131:13): [True: 0, False: 593]
  ------------------
  132|      0|            card = src_2->cardinality;
  133|      0|        }
  134|    593|        array_container_t *answer = array_container_create_given_capacity(card);
  135|    593|        *dst = answer;
  136|    593|        if (*dst == NULL) {
  ------------------
  |  Branch (136:13): [True: 0, False: 593]
  ------------------
  137|      0|            return false;
  138|      0|        }
  139|    593|        const rle16_t *runs = src_1->runs;
  140|    593|        const int32_t n_runs = src_1->n_runs;
  141|    593|        const uint64_t *words = src_2->words;
  142|    593|        uint16_t *out = answer->array;
  143|    593|        int32_t newcard = 0;
  144|  46.5k|        for (int32_t rlepos = 0; rlepos < n_runs; ++rlepos) {
  ------------------
  |  Branch (144:34): [True: 45.9k, False: 593]
  ------------------
  145|  45.9k|            rle16_t rle = runs[rlepos];
  146|  45.9k|            uint32_t endofrun = (uint32_t)rle.value + rle.length;
  147|   168k|            for (uint32_t runValue = rle.value; runValue <= endofrun;
  ------------------
  |  Branch (147:49): [True: 122k, False: 45.9k]
  ------------------
  148|   122k|                 ++runValue) {
  149|   122k|                out[newcard] = (uint16_t)runValue;
  150|   122k|                newcard += (words[runValue >> 6] >> (runValue & 63)) & 1;
  151|   122k|            }
  152|  45.9k|        }
  153|    593|        answer->cardinality = newcard;
  154|    593|        return false;
  155|    593|    }
  156|      0|    if (*dst == src_2) {  // we attempt in-place
  ------------------
  |  Branch (156:9): [True: 0, False: 0]
  ------------------
  157|      0|        bitset_container_t *answer = CAST_bitset(*dst);
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  158|      0|        uint32_t start = 0;
  159|      0|        for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) {
  ------------------
  |  Branch (159:34): [True: 0, False: 0]
  ------------------
  160|      0|            const rle16_t rle = src_1->runs[rlepos];
  161|      0|            uint32_t end = rle.value;
  162|      0|            bitset_reset_range(src_2->words, start, end);
  163|       |
  164|      0|            start = end + rle.length + 1;
  165|      0|        }
  166|      0|        bitset_reset_range(src_2->words, start, UINT32_C(1) << 16);
  167|      0|        answer->cardinality = bitset_container_compute_cardinality(answer);
  168|      0|        if (src_2->cardinality > DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (168:13): [True: 0, False: 0]
  ------------------
  169|      0|            return true;
  170|      0|        } else {
  171|      0|            array_container_t *newanswer = array_container_from_bitset(src_2);
  172|      0|            if (newanswer == NULL) {
  ------------------
  |  Branch (172:17): [True: 0, False: 0]
  ------------------
  173|      0|                *dst = NULL;
  174|      0|                return false;
  175|      0|            }
  176|      0|            *dst = newanswer;
  177|      0|            return false;
  178|      0|        }
  179|      0|    } else {  // no inplace
  180|       |        // we expect the answer to be a bitmap (if we are lucky)
  181|      0|        bitset_container_t *answer = bitset_container_clone(src_2);
  182|       |
  183|      0|        *dst = answer;
  184|      0|        if (answer == NULL) {
  ------------------
  |  Branch (184:13): [True: 0, False: 0]
  ------------------
  185|      0|            return true;
  186|      0|        }
  187|      0|        uint32_t start = 0;
  188|      0|        for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) {
  ------------------
  |  Branch (188:34): [True: 0, False: 0]
  ------------------
  189|      0|            const rle16_t rle = src_1->runs[rlepos];
  190|      0|            uint32_t end = rle.value;
  191|      0|            bitset_reset_range(answer->words, start, end);
  192|      0|            start = end + rle.length + 1;
  193|      0|        }
  194|      0|        bitset_reset_range(answer->words, start, UINT32_C(1) << 16);
  195|      0|        answer->cardinality = bitset_container_compute_cardinality(answer);
  196|       |
  197|      0|        if (answer->cardinality > DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (197:13): [True: 0, False: 0]
  ------------------
  198|      0|            return true;
  199|      0|        } else {
  200|      0|            array_container_t *newanswer = array_container_from_bitset(answer);
  201|      0|            bitset_container_free(CAST_bitset(*dst));
  ------------------
  |  |   52|      0|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  202|      0|            if (newanswer == NULL) {
  ------------------
  |  Branch (202:17): [True: 0, False: 0]
  ------------------
  203|      0|                *dst = NULL;
  204|      0|                return false;
  205|      0|            }
  206|      0|            *dst = newanswer;
  207|       |            return false;
  208|      0|        }
  209|      0|    }
  210|      0|}
array_run_container_intersection_cardinality:
  214|  7.05k|                                                 const run_container_t *src_2) {
  215|  7.05k|    if (run_container_is_full(src_2)) {
  ------------------
  |  Branch (215:9): [True: 64, False: 6.98k]
  ------------------
  216|     64|        return src_1->cardinality;
  217|     64|    }
  218|  6.98k|    if (src_2->n_runs == 0) {
  ------------------
  |  Branch (218:9): [True: 0, False: 6.98k]
  ------------------
  219|      0|        return 0;
  220|      0|    }
  221|  6.98k|    int32_t rlepos = 0;
  222|  6.98k|    int32_t arraypos = 0;
  223|  6.98k|    rle16_t rle = src_2->runs[rlepos];
  224|  6.98k|    int32_t newcard = 0;
  225|   637k|    while (arraypos < src_1->cardinality) {
  ------------------
  |  Branch (225:12): [True: 631k, False: 5.42k]
  ------------------
  226|   631k|        const uint16_t arrayval = src_1->array[arraypos];
  227|   954k|        while (rle.value + rle.length <
  ------------------
  |  Branch (227:16): [True: 324k, False: 630k]
  ------------------
  228|   954k|               arrayval) {  // this will frequently be false
  229|   324k|            ++rlepos;
  230|   324k|            if (rlepos == src_2->n_runs) {
  ------------------
  |  Branch (230:17): [True: 1.56k, False: 322k]
  ------------------
  231|  1.56k|                return newcard;  // we are done
  232|  1.56k|            }
  233|   322k|            rle = src_2->runs[rlepos];
  234|   322k|        }
  235|   630k|        if (rle.value > arrayval) {
  ------------------
  |  Branch (235:13): [True: 87.0k, False: 542k]
  ------------------
  236|  87.0k|            arraypos = advanceUntil(src_1->array, arraypos, src_1->cardinality,
  237|  87.0k|                                    rle.value);
  238|   542k|        } else {
  239|   542k|            newcard++;
  240|   542k|            arraypos++;
  241|   542k|        }
  242|   630k|    }
  243|  5.42k|    return newcard;
  244|  6.98k|}
run_bitset_container_intersection_cardinality:
  249|  2.37k|    const run_container_t *src_1, const bitset_container_t *src_2) {
  250|  2.37k|    if (run_container_is_full(src_1)) {
  ------------------
  |  Branch (250:9): [True: 0, False: 2.37k]
  ------------------
  251|      0|        return bitset_container_cardinality(src_2);
  252|      0|    }
  253|  2.37k|    int answer = 0;
  254|   186k|    for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) {
  ------------------
  |  Branch (254:30): [True: 183k, False: 2.37k]
  ------------------
  255|   183k|        rle16_t rle = src_1->runs[rlepos];
  256|   183k|        answer +=
  257|   183k|            bitset_lenrange_cardinality(src_2->words, rle.value, rle.length);
  258|   183k|    }
  259|  2.37k|    return answer;
  260|  2.37k|}
array_run_container_intersect:
  263|  1.76k|                                   const run_container_t *src_2) {
  264|  1.76k|    if (run_container_is_full(src_2)) {
  ------------------
  |  Branch (264:9): [True: 16, False: 1.74k]
  ------------------
  265|     16|        return !array_container_empty(src_1);
  266|     16|    }
  267|  1.74k|    if (src_2->n_runs == 0) {
  ------------------
  |  Branch (267:9): [True: 0, False: 1.74k]
  ------------------
  268|      0|        return false;
  269|      0|    }
  270|  1.74k|    int32_t rlepos = 0;
  271|  1.74k|    int32_t arraypos = 0;
  272|  1.74k|    rle16_t rle = src_2->runs[rlepos];
  273|  3.17k|    while (arraypos < src_1->cardinality) {
  ------------------
  |  Branch (273:12): [True: 3.13k, False: 42]
  ------------------
  274|  3.13k|        const uint16_t arrayval = src_1->array[arraypos];
  275|  7.60k|        while (rle.value + rle.length <
  ------------------
  |  Branch (275:16): [True: 4.50k, False: 3.10k]
  ------------------
  276|  7.60k|               arrayval) {  // this will frequently be false
  277|  4.50k|            ++rlepos;
  278|  4.50k|            if (rlepos == src_2->n_runs) {
  ------------------
  |  Branch (278:17): [True: 27, False: 4.47k]
  ------------------
  279|     27|                return false;  // we are done
  280|     27|            }
  281|  4.47k|            rle = src_2->runs[rlepos];
  282|  4.47k|        }
  283|  3.10k|        if (rle.value > arrayval) {
  ------------------
  |  Branch (283:13): [True: 1.42k, False: 1.67k]
  ------------------
  284|  1.42k|            arraypos = advanceUntil(src_1->array, arraypos, src_1->cardinality,
  285|  1.42k|                                    rle.value);
  286|  1.67k|        } else {
  287|  1.67k|            return true;
  288|  1.67k|        }
  289|  3.10k|    }
  290|     42|    return false;
  291|  1.74k|}
run_bitset_container_intersect:
  296|    593|                                    const bitset_container_t *src_2) {
  297|    593|    if (run_container_is_full(src_1)) {
  ------------------
  |  Branch (297:9): [True: 0, False: 593]
  ------------------
  298|      0|        return !bitset_container_empty(src_2);
  299|      0|    }
  300|  3.75k|    for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) {
  ------------------
  |  Branch (300:30): [True: 3.74k, False: 12]
  ------------------
  301|  3.74k|        rle16_t rle = src_1->runs[rlepos];
  302|  3.74k|        if (!bitset_lenrange_empty(src_2->words, rle.value, rle.length))
  ------------------
  |  Branch (302:13): [True: 581, False: 3.16k]
  ------------------
  303|    581|            return true;
  304|  3.74k|    }
  305|     12|    return false;
  306|    593|}
bitset_bitset_container_intersection_inplace:
  358|  1.40k|    container_t **dst) {
  359|  1.40k|    const int newCardinality = bitset_container_and_justcard(src_1, src_2);
  360|  1.40k|    if (newCardinality > DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (360:9): [True: 1.40k, False: 0]
  ------------------
  361|  1.40k|        *dst = src_1;
  362|  1.40k|        bitset_container_and_nocard(src_1, src_2, src_1);
  363|  1.40k|        CAST_bitset(*dst)->cardinality = newCardinality;
  ------------------
  |  |   52|  1.40k|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  1.40k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  364|  1.40k|        return true;  // it is a bitset
  365|  1.40k|    }
  366|      0|    *dst = array_container_create_given_capacity(newCardinality);
  367|      0|    if (*dst != NULL) {
  ------------------
  |  Branch (367:9): [True: 0, False: 0]
  ------------------
  368|      0|        CAST_array(*dst)->cardinality = newCardinality;
  ------------------
  |  |   54|      0|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  369|      0|        extract_intersection_to_array(src_1, src_2, CAST_array(*dst)->array,
  ------------------
  |  |   54|      0|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  370|      0|                                      newCardinality);
  371|      0|    }
  372|       |    return false;  // not a bitset
  373|  1.40k|}

array_container_negation:
   33|     23|                              bitset_container_t *dst) {
   34|     23|    uint64_t card = UINT64_C(1 << 16);
   35|     23|    bitset_container_set_all(dst);
   36|       |
   37|     23|    if (src->cardinality == 0) {
  ------------------
  |  Branch (37:9): [True: 0, False: 23]
  ------------------
   38|      0|        return;
   39|      0|    }
   40|       |
   41|     23|    dst->cardinality = (int32_t)bitset_clear_list(dst->words, card, src->array,
   42|     23|                                                  (uint64_t)src->cardinality);
   43|     23|}
bitset_container_negation_inplace:
   67|     46|                                       container_t **dst) {
   68|     46|    return bitset_container_negation_range_inplace(src, 0, (1 << 16), dst);
   69|     46|}
run_container_negation_inplace:
   88|  6.42k|int run_container_negation_inplace(run_container_t *src, container_t **dst) {
   89|  6.42k|    return run_container_negation_range_inplace(src, 0, (1 << 16), dst);
   90|  6.42k|}
array_container_negation_range:
  100|  4.37k|                                    container_t **dst) {
  101|       |    /* close port of the Java implementation */
  102|  4.37k|    if (range_start >= range_end) {
  ------------------
  |  Branch (102:9): [True: 0, False: 4.37k]
  ------------------
  103|      0|        *dst = array_container_clone(src);
  104|      0|        return false;
  105|      0|    }
  106|       |
  107|  4.37k|    int32_t start_index =
  108|  4.37k|        binarySearch(src->array, src->cardinality, (uint16_t)range_start);
  109|  4.37k|    if (start_index < 0) start_index = -start_index - 1;
  ------------------
  |  Branch (109:9): [True: 4.09k, False: 280]
  ------------------
  110|       |
  111|  4.37k|    int32_t last_index =
  112|  4.37k|        binarySearch(src->array, src->cardinality, (uint16_t)(range_end - 1));
  113|  4.37k|    if (last_index < 0) last_index = -last_index - 2;
  ------------------
  |  Branch (113:9): [True: 4.10k, False: 266]
  ------------------
  114|       |
  115|  4.37k|    const int32_t current_values_in_range = last_index - start_index + 1;
  116|  4.37k|    const int32_t span_to_be_flipped = range_end - range_start;
  117|  4.37k|    const int32_t new_values_in_range =
  118|  4.37k|        span_to_be_flipped - current_values_in_range;
  119|  4.37k|    const int32_t cardinality_change =
  120|  4.37k|        new_values_in_range - current_values_in_range;
  121|  4.37k|    const int32_t new_cardinality = src->cardinality + cardinality_change;
  122|       |
  123|  4.37k|    if (new_cardinality > DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (123:9): [True: 38, False: 4.33k]
  ------------------
  124|     38|        bitset_container_t *temp = bitset_container_from_array(src);
  125|     38|        bitset_flip_range(temp->words, (uint32_t)range_start,
  126|     38|                          (uint32_t)range_end);
  127|     38|        temp->cardinality = new_cardinality;
  128|     38|        *dst = temp;
  129|     38|        return true;
  130|     38|    }
  131|       |
  132|  4.33k|    array_container_t *arr =
  133|  4.33k|        array_container_create_given_capacity(new_cardinality);
  134|  4.33k|    *dst = (container_t *)arr;
  135|  4.33k|    if (new_cardinality == 0) {
  ------------------
  |  Branch (135:9): [True: 10, False: 4.32k]
  ------------------
  136|     10|        arr->cardinality = new_cardinality;
  137|     10|        return false;  // we are done.
  138|     10|    }
  139|       |    // copy stuff before the active area
  140|  4.32k|    memcpy(arr->array, src->array, start_index * sizeof(uint16_t));
  141|       |
  142|       |    // work on the range
  143|  4.32k|    int32_t out_pos = start_index, in_pos = start_index;
  144|  4.32k|    int32_t val_in_range = range_start;
  145|  55.3k|    for (; val_in_range < range_end && in_pos <= last_index; ++val_in_range) {
  ------------------
  |  Branch (145:12): [True: 55.1k, False: 250]
  |  Branch (145:40): [True: 51.0k, False: 4.07k]
  ------------------
  146|  51.0k|        if ((uint16_t)val_in_range != src->array[in_pos]) {
  ------------------
  |  Branch (146:13): [True: 23.7k, False: 27.3k]
  ------------------
  147|  23.7k|            arr->array[out_pos++] = (uint16_t)val_in_range;
  148|  27.3k|        } else {
  149|  27.3k|            ++in_pos;
  150|  27.3k|        }
  151|  51.0k|    }
  152|  69.8k|    for (; val_in_range < range_end; ++val_in_range)
  ------------------
  |  Branch (152:12): [True: 65.5k, False: 4.32k]
  ------------------
  153|  65.5k|        arr->array[out_pos++] = (uint16_t)val_in_range;
  154|       |
  155|       |    // content after the active range
  156|  4.32k|    memcpy(arr->array + out_pos, src->array + (last_index + 1),
  157|  4.32k|           (src->cardinality - (last_index + 1)) * sizeof(uint16_t));
  158|  4.32k|    arr->cardinality = new_cardinality;
  159|       |    return false;
  160|  4.33k|}
array_container_negation_range_to_any:
  194|  4.70k|                                          container_t **dst) {
  195|       |    // The result has more than DEFAULT_MAX_SIZE values, so it would be a
  196|       |    // bitset, but it has at most cardinality + 1 runs: when these runs take
  197|       |    // less room than a bitset, we build them directly. In the range, the
  198|       |    // runs are the gaps between the values; outside, the values themselves.
  199|  4.70k|    if (range_end - range_start - src->cardinality > DEFAULT_MAX_SIZE &&
  ------------------
  |  Branch (199:9): [True: 346, False: 4.36k]
  ------------------
  200|    346|        run_container_serialized_size_in_bytes(src->cardinality + 1) <
  ------------------
  |  Branch (200:9): [True: 313, False: 33]
  ------------------
  201|    346|            BITSET_CONTAINER_SIZE_IN_WORDS * (int32_t)sizeof(uint64_t)) {
  202|    313|        run_container_t *ans =
  203|    313|            run_container_create_given_capacity(src->cardinality + 1);
  204|    313|        if (ans == NULL) {
  ------------------
  |  Branch (204:13): [True: 0, False: 313]
  ------------------
  205|      0|            *dst = NULL;
  206|      0|            return RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
  207|      0|        }
  208|    313|        const uint16_t *array = src->array;
  209|    313|        const int32_t card = src->cardinality;
  210|    313|        rle16_t *runs = ans->runs;
  211|    313|        int32_t n = 0, k = 0;
  212|  10.9k|        for (; k < card && array[k] < range_start; k++) {
  ------------------
  |  Branch (212:16): [True: 10.9k, False: 46]
  |  Branch (212:28): [True: 10.6k, False: 267]
  ------------------
  213|  10.6k|            n = append_run(runs, n, array[k], array[k]);
  214|  10.6k|        }
  215|    313|        uint32_t next = (uint32_t)range_start;  // first value not yet decided
  216|  30.5k|        for (; k < card && array[k] < range_end; k++) {
  ------------------
  |  Branch (216:16): [True: 30.2k, False: 284]
  |  Branch (216:28): [True: 30.2k, False: 29]
  ------------------
  217|  30.2k|            if (array[k] > next) n = append_run(runs, n, next, array[k] - 1u);
  ------------------
  |  Branch (217:17): [True: 8.80k, False: 21.4k]
  ------------------
  218|  30.2k|            next = array[k] + 1u;
  219|  30.2k|        }
  220|    313|        if (next < (uint32_t)range_end) {
  ------------------
  |  Branch (220:13): [True: 300, False: 13]
  ------------------
  221|    300|            n = append_run(runs, n, next, (uint32_t)range_end - 1);
  222|    300|        }
  223|  4.01k|        for (; k < card; k++) {
  ------------------
  |  Branch (223:16): [True: 3.70k, False: 313]
  ------------------
  224|  3.70k|            n = append_run(runs, n, array[k], array[k]);
  225|  3.70k|        }
  226|    313|        ans->n_runs = n;
  227|    313|        *dst = ans;
  228|    313|        return RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|    313|#define RUN_CONTAINER_TYPE 3
  ------------------
  229|    313|    }
  230|  4.39k|    if (range_start == 0 && range_end == (1 << 16)) {
  ------------------
  |  Branch (230:9): [True: 4.28k, False: 107]
  |  Branch (230:29): [True: 23, False: 4.26k]
  ------------------
  231|       |        // The negation of a whole array is always a bitset, built in one pass.
  232|     23|        bitset_container_t *ans = bitset_container_create();
  233|     23|        if (ans != NULL) array_container_negation(src, ans);
  ------------------
  |  Branch (233:13): [True: 23, False: 0]
  ------------------
  234|     23|        *dst = ans;
  235|     23|        return BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|     23|#define BITSET_CONTAINER_TYPE 1
  ------------------
  236|     23|    }
  237|  4.37k|    return array_container_negation_range(src, range_start, range_end, dst)
  ------------------
  |  Branch (237:12): [True: 38, False: 4.33k]
  ------------------
  238|  4.37k|               ? BITSET_CONTAINER_TYPE
  ------------------
  |  |   48|     38|#define BITSET_CONTAINER_TYPE 1
  ------------------
  239|  4.37k|               : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  4.33k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  240|  4.39k|}
bitset_container_negation_range_inplace:
  284|  1.26k|                                             container_t **dst) {
  285|  1.26k|    bitset_flip_range(src->words, (uint32_t)range_start, (uint32_t)range_end);
  286|  1.26k|    src->cardinality = bitset_container_compute_cardinality(src);
  287|  1.26k|    if (src->cardinality > DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (287:9): [True: 1.23k, False: 33]
  ------------------
  288|  1.23k|        *dst = src;
  289|  1.23k|        return true;
  290|  1.23k|    }
  291|     33|    *dst = array_container_from_bitset(src);
  292|     33|    bitset_container_free(src);
  293|       |    return false;
  294|  1.26k|}
run_container_negation_range:
  305|    148|                                 container_t **dst) {
  306|    148|    uint8_t return_typecode;
  307|       |
  308|       |    // follows the Java implementation
  309|    148|    if (range_end <= range_start) {
  ------------------
  |  Branch (309:9): [True: 0, False: 148]
  ------------------
  310|      0|        *dst = run_container_clone(src);
  311|      0|        return RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
  312|      0|    }
  313|       |
  314|    148|    run_container_t *ans = run_container_create_given_capacity(
  315|    148|        src->n_runs + 1);  // src->n_runs + 1);
  316|    148|    int k = 0;
  317|  2.23k|    for (; k < src->n_runs && src->runs[k].value < range_start; ++k) {
  ------------------
  |  Branch (317:12): [True: 2.20k, False: 35]
  |  Branch (317:31): [True: 2.09k, False: 113]
  ------------------
  318|  2.09k|        ans->runs[k] = src->runs[k];
  319|  2.09k|        ans->n_runs++;
  320|  2.09k|    }
  321|       |
  322|    148|    run_container_smart_append_exclusive(
  323|    148|        ans, (uint16_t)range_start, (uint16_t)(range_end - range_start - 1));
  324|       |
  325|  3.38k|    for (; k < src->n_runs; ++k) {
  ------------------
  |  Branch (325:12): [True: 3.24k, False: 148]
  ------------------
  326|  3.24k|        run_container_smart_append_exclusive(ans, src->runs[k].value,
  327|  3.24k|                                             src->runs[k].length);
  328|  3.24k|    }
  329|       |
  330|    148|    *dst = convert_run_to_efficient_container(ans, &return_typecode);
  331|    148|    if (return_typecode != RUN_CONTAINER_TYPE) run_container_free(ans);
  ------------------
  |  |   50|    148|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (331:9): [True: 4, False: 144]
  ------------------
  332|       |
  333|    148|    return return_typecode;
  334|    148|}
run_container_negation_range_inplace:
  346|  8.08k|                                         container_t **dst) {
  347|  8.08k|    uint8_t return_typecode;
  348|       |
  349|  8.08k|    if (range_end <= range_start) {
  ------------------
  |  Branch (349:9): [True: 0, False: 8.08k]
  ------------------
  350|      0|        *dst = src;
  351|      0|        return RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
  352|      0|    }
  353|       |
  354|       |    // TODO: efficient special case when range is 0 to 65535 inclusive
  355|       |
  356|  8.08k|    if (src->capacity == src->n_runs) {
  ------------------
  |  Branch (356:9): [True: 6.90k, False: 1.18k]
  ------------------
  357|       |        // no excess room.  More checking to see if result can fit
  358|  6.90k|        bool last_val_before_range = false;
  359|  6.90k|        bool first_val_in_range = false;
  360|  6.90k|        bool last_val_in_range = false;
  361|  6.90k|        bool first_val_past_range = false;
  362|       |
  363|  6.90k|        if (range_start > 0)
  ------------------
  |  Branch (363:13): [True: 163, False: 6.74k]
  ------------------
  364|    163|            last_val_before_range =
  365|    163|                run_container_contains(src, (uint16_t)(range_start - 1));
  366|  6.90k|        first_val_in_range = run_container_contains(src, (uint16_t)range_start);
  367|       |
  368|  6.90k|        if (last_val_before_range == first_val_in_range) {
  ------------------
  |  Branch (368:13): [True: 463, False: 6.44k]
  ------------------
  369|    463|            last_val_in_range =
  370|    463|                run_container_contains(src, (uint16_t)(range_end - 1));
  371|    463|            if (range_end != 0x10000)
  ------------------
  |  Branch (371:17): [True: 275, False: 188]
  ------------------
  372|    275|                first_val_past_range =
  373|    275|                    run_container_contains(src, (uint16_t)range_end);
  374|       |
  375|    463|            if (last_val_in_range ==
  ------------------
  |  Branch (375:17): [True: 148, False: 315]
  ------------------
  376|    463|                first_val_past_range) {  // no space for inplace
  377|    148|                int ans = run_container_negation_range(src, range_start,
  378|    148|                                                       range_end, dst);
  379|    148|                run_container_free(src);
  380|    148|                return ans;
  381|    148|            }
  382|    463|        }
  383|  6.90k|    }
  384|       |    // all other cases: result will fit
  385|       |
  386|  7.94k|    run_container_t *ans = src;
  387|  7.94k|    int my_nbr_runs = src->n_runs;
  388|       |
  389|  7.94k|    ans->n_runs = 0;
  390|  7.94k|    int k = 0;
  391|  10.0k|    for (; (k < my_nbr_runs) && (src->runs[k].value < range_start); ++k) {
  ------------------
  |  Branch (391:12): [True: 10.0k, False: 76]
  |  Branch (391:33): [True: 2.14k, False: 7.86k]
  ------------------
  392|       |        // ans->runs[k] = src->runs[k]; (would be self-copy)
  393|  2.14k|        ans->n_runs++;
  394|  2.14k|    }
  395|       |
  396|       |    // as with Java implementation, use locals to give self a buffer of depth 1
  397|  7.94k|    rle16_t buffered = CROARING_MAKE_RLE16(0, 0);
  ------------------
  |  |   60|  7.94k|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  398|  7.94k|    rle16_t next = buffered;
  399|  7.94k|    if (k < my_nbr_runs) buffered = src->runs[k];
  ------------------
  |  Branch (399:9): [True: 7.86k, False: 76]
  ------------------
  400|       |
  401|  7.94k|    run_container_smart_append_exclusive(
  402|  7.94k|        ans, (uint16_t)range_start, (uint16_t)(range_end - range_start - 1));
  403|       |
  404|  93.2k|    for (; k < my_nbr_runs; ++k) {
  ------------------
  |  Branch (404:12): [True: 85.2k, False: 7.94k]
  ------------------
  405|  85.2k|        if (k + 1 < my_nbr_runs) next = src->runs[k + 1];
  ------------------
  |  Branch (405:13): [True: 77.4k, False: 7.86k]
  ------------------
  406|       |
  407|  85.2k|        run_container_smart_append_exclusive(ans, buffered.value,
  408|  85.2k|                                             buffered.length);
  409|  85.2k|        buffered = next;
  410|  85.2k|    }
  411|       |
  412|  7.94k|    *dst = convert_run_to_efficient_container(ans, &return_typecode);
  413|  7.94k|    if (return_typecode != RUN_CONTAINER_TYPE) run_container_free(ans);
  ------------------
  |  |   50|  7.94k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (413:9): [True: 6.27k, False: 1.66k]
  ------------------
  414|       |
  415|  7.94k|    return return_typecode;
  416|  8.08k|}
mixed_negation.c:append_run:
  179|  23.4k|                                 uint32_t end) {
  180|  23.4k|    if (n > 0 &&
  ------------------
  |  Branch (180:9): [True: 23.1k, False: 313]
  ------------------
  181|  23.1k|        (uint32_t)runs[n - 1].value + runs[n - 1].length + 1 == start) {
  ------------------
  |  Branch (181:9): [True: 8.60k, False: 14.5k]
  ------------------
  182|  8.60k|        runs[n - 1].length = (uint16_t)(end - runs[n - 1].value);
  183|  8.60k|        return n;
  184|  8.60k|    }
  185|  14.8k|    runs[n].value = (uint16_t)start;
  186|  14.8k|    runs[n].length = (uint16_t)(end - start);
  187|  14.8k|    return n + 1;
  188|  23.4k|}

array_container_is_subset_bitset:
   11|  2.23k|                                      const bitset_container_t* container2) {
   12|  2.23k|    if (container2->cardinality != BITSET_UNKNOWN_CARDINALITY) {
  ------------------
  |  Branch (12:9): [True: 2.23k, False: 0]
  ------------------
   13|  2.23k|        if (container2->cardinality < container1->cardinality) {
  ------------------
  |  Branch (13:13): [True: 0, False: 2.23k]
  ------------------
   14|      0|            return false;
   15|      0|        }
   16|  2.23k|    }
   17|  2.23k|    for (int i = 0; i < container1->cardinality; ++i) {
  ------------------
  |  Branch (17:21): [True: 2.23k, False: 0]
  ------------------
   18|  2.23k|        if (!bitset_container_contains(container2, container1->array[i])) {
  ------------------
  |  Branch (18:13): [True: 2.23k, False: 0]
  ------------------
   19|  2.23k|            return false;
   20|  2.23k|        }
   21|  2.23k|    }
   22|      0|    return true;
   23|  2.23k|}
run_container_is_subset_array:
   26|    350|                                   const array_container_t* container2) {
   27|    350|    if (run_container_cardinality(container1) > container2->cardinality)
  ------------------
  |  Branch (27:9): [True: 139, False: 211]
  ------------------
   28|    139|        return false;
   29|    211|    int32_t start_pos = -1, stop_pos = -1;
   30|    211|    for (int i = 0; i < container1->n_runs; ++i) {
  ------------------
  |  Branch (30:21): [True: 211, False: 0]
  ------------------
   31|    211|        int32_t start = container1->runs[i].value;
   32|    211|        int32_t stop = start + container1->runs[i].length;
   33|    211|        start_pos = advanceUntil(container2->array, stop_pos,
   34|    211|                                 container2->cardinality, start);
   35|    211|        stop_pos = advanceUntil(container2->array, stop_pos,
   36|    211|                                container2->cardinality, stop);
   37|    211|        if (stop_pos == container2->cardinality) {
  ------------------
  |  Branch (37:13): [True: 3, False: 208]
  ------------------
   38|      3|            return false;
   39|    208|        } else if (stop_pos - start_pos != stop - start ||
  ------------------
  |  Branch (39:20): [True: 72, False: 136]
  ------------------
   40|    136|                   container2->array[start_pos] != start ||
  ------------------
  |  Branch (40:20): [True: 136, False: 0]
  ------------------
   41|    208|                   container2->array[stop_pos] != stop) {
  ------------------
  |  Branch (41:20): [True: 0, False: 0]
  ------------------
   42|    208|            return false;
   43|    208|        }
   44|    211|    }
   45|      0|    return true;
   46|    211|}
array_container_is_subset_run:
   49|  2.05k|                                   const run_container_t* container2) {
   50|  2.05k|    if (container1->cardinality > run_container_cardinality(container2))
  ------------------
  |  Branch (50:9): [True: 161, False: 1.89k]
  ------------------
   51|    161|        return false;
   52|  1.89k|    int i_array = 0, i_run = 0;
   53|  4.88k|    while (i_array < container1->cardinality && i_run < container2->n_runs) {
  ------------------
  |  Branch (53:12): [True: 4.88k, False: 0]
  |  Branch (53:49): [True: 4.87k, False: 14]
  ------------------
   54|  4.87k|        uint32_t start = container2->runs[i_run].value;
   55|  4.87k|        uint32_t stop = start + container2->runs[i_run].length;
   56|  4.87k|        if (container1->array[i_array] < start) {
  ------------------
  |  Branch (56:13): [True: 1.87k, False: 2.99k]
  ------------------
   57|  1.87k|            return false;
   58|  2.99k|        } else if (container1->array[i_array] > stop) {
  ------------------
  |  Branch (58:20): [True: 2.99k, False: 0]
  ------------------
   59|  2.99k|            i_run++;
   60|  2.99k|        } else {  // the value of the array is in the run
   61|      0|            i_array++;
   62|      0|        }
   63|  4.87k|    }
   64|     14|    if (i_array == container1->cardinality) {
  ------------------
  |  Branch (64:9): [True: 0, False: 14]
  ------------------
   65|      0|        return true;
   66|     14|    } else {
   67|       |        return false;
   68|     14|    }
   69|     14|}

array_bitset_container_union:
   24|  1.17k|                                  bitset_container_t *dst) {
   25|  1.17k|    if (src_2 != dst) bitset_container_copy(src_2, dst);
  ------------------
  |  Branch (25:9): [True: 1.17k, False: 0]
  ------------------
   26|  1.17k|    dst->cardinality = (int32_t)bitset_set_list_withcard(
   27|  1.17k|        dst->words, dst->cardinality, src_1->array, src_1->cardinality);
   28|  1.17k|}
run_bitset_container_union:
   43|  1.18k|                                bitset_container_t *dst) {
   44|  1.18k|    assert(!run_container_is_full(src_1));  // catch this case upstream
   45|  1.18k|    if (src_2 != dst) bitset_container_copy(src_2, dst);
  ------------------
  |  Branch (45:9): [True: 1.18k, False: 0]
  ------------------
   46|  93.1k|    for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) {
  ------------------
  |  Branch (46:30): [True: 91.9k, False: 1.18k]
  ------------------
   47|  91.9k|        rle16_t rle = src_1->runs[rlepos];
   48|  91.9k|        bitset_set_lenrange(dst->words, rle.value, rle.length);
   49|  91.9k|    }
   50|  1.18k|    dst->cardinality = bitset_container_compute_cardinality(dst);
   51|  1.18k|}
array_run_container_union:
   68|  2.30k|                               run_container_t *dst) {
   69|  2.30k|    if (run_container_is_full(src_2)) {
  ------------------
  |  Branch (69:9): [True: 67, False: 2.23k]
  ------------------
   70|     67|        run_container_copy(src_2, dst);
   71|     67|        return;
   72|     67|    }
   73|       |    // TODO: see whether the "2*" is spurious
   74|  2.23k|    run_container_grow(dst, 2 * (src_1->cardinality + src_2->n_runs), false);
   75|  2.23k|    int32_t rlepos = 0;
   76|  2.23k|    int32_t arraypos = 0;
   77|  2.23k|    rle16_t previousrle;
   78|  2.23k|    if (src_2->runs[rlepos].value <= src_1->array[arraypos]) {
  ------------------
  |  Branch (78:9): [True: 1.66k, False: 569]
  ------------------
   79|  1.66k|        previousrle = run_container_append_first(dst, src_2->runs[rlepos]);
   80|  1.66k|        rlepos++;
   81|  1.66k|    } else {
   82|    569|        previousrle =
   83|    569|            run_container_append_value_first(dst, src_1->array[arraypos]);
   84|    569|        arraypos++;
   85|    569|    }
   86|   377k|    while ((rlepos < src_2->n_runs) && (arraypos < src_1->cardinality)) {
  ------------------
  |  Branch (86:12): [True: 376k, False: 1.41k]
  |  Branch (86:40): [True: 375k, False: 824]
  ------------------
   87|   375k|        if (src_2->runs[rlepos].value <= src_1->array[arraypos]) {
  ------------------
  |  Branch (87:13): [True: 123k, False: 251k]
  ------------------
   88|   123k|            run_container_append(dst, src_2->runs[rlepos], &previousrle);
   89|   123k|            rlepos++;
   90|   251k|        } else {
   91|   251k|            run_container_append_value(dst, src_1->array[arraypos],
   92|   251k|                                       &previousrle);
   93|   251k|            arraypos++;
   94|   251k|        }
   95|   375k|    }
   96|  2.23k|    if (arraypos < src_1->cardinality) {
  ------------------
  |  Branch (96:9): [True: 1.41k, False: 824]
  ------------------
   97|   131k|        while (arraypos < src_1->cardinality) {
  ------------------
  |  Branch (97:16): [True: 129k, False: 1.41k]
  ------------------
   98|   129k|            run_container_append_value(dst, src_1->array[arraypos],
   99|   129k|                                       &previousrle);
  100|   129k|            arraypos++;
  101|   129k|        }
  102|  1.41k|    } else {
  103|  5.37k|        while (rlepos < src_2->n_runs) {
  ------------------
  |  Branch (103:16): [True: 4.54k, False: 824]
  ------------------
  104|  4.54k|            run_container_append(dst, src_2->runs[rlepos], &previousrle);
  105|  4.54k|            rlepos++;
  106|  4.54k|        }
  107|    824|    }
  108|  2.23k|}
array_run_container_inplace_union:
  111|    262|                                       run_container_t *src_2) {
  112|    262|    if (run_container_is_full(src_2)) {
  ------------------
  |  Branch (112:9): [True: 0, False: 262]
  ------------------
  113|      0|        return;
  114|      0|    }
  115|    262|    const int32_t maxoutput = src_1->cardinality + src_2->n_runs;
  116|    262|    const int32_t neededcapacity = maxoutput + src_2->n_runs;
  117|    262|    if (src_2->capacity < neededcapacity)
  ------------------
  |  Branch (117:9): [True: 262, False: 0]
  ------------------
  118|    262|        run_container_grow(src_2, neededcapacity, true);
  119|    262|    memmove(src_2->runs + maxoutput, src_2->runs,
  120|    262|            src_2->n_runs * sizeof(rle16_t));
  121|    262|    rle16_t *inputsrc2 = src_2->runs + maxoutput;
  122|    262|    int32_t rlepos = 0;
  123|    262|    int32_t arraypos = 0;
  124|    262|    int src2nruns = src_2->n_runs;
  125|    262|    src_2->n_runs = 0;
  126|       |
  127|    262|    rle16_t previousrle;
  128|       |
  129|    262|    if (inputsrc2[rlepos].value <= src_1->array[arraypos]) {
  ------------------
  |  Branch (129:9): [True: 218, False: 44]
  ------------------
  130|    218|        previousrle = run_container_append_first(src_2, inputsrc2[rlepos]);
  131|    218|        rlepos++;
  132|    218|    } else {
  133|     44|        previousrle =
  134|     44|            run_container_append_value_first(src_2, src_1->array[arraypos]);
  135|     44|        arraypos++;
  136|     44|    }
  137|       |
  138|  51.3k|    while ((rlepos < src2nruns) && (arraypos < src_1->cardinality)) {
  ------------------
  |  Branch (138:12): [True: 51.0k, False: 262]
  |  Branch (138:36): [True: 51.0k, False: 0]
  ------------------
  139|  51.0k|        if (inputsrc2[rlepos].value <= src_1->array[arraypos]) {
  ------------------
  |  Branch (139:13): [True: 13.1k, False: 37.8k]
  ------------------
  140|  13.1k|            run_container_append(src_2, inputsrc2[rlepos], &previousrle);
  141|  13.1k|            rlepos++;
  142|  37.8k|        } else {
  143|  37.8k|            run_container_append_value(src_2, src_1->array[arraypos],
  144|  37.8k|                                       &previousrle);
  145|  37.8k|            arraypos++;
  146|  37.8k|        }
  147|  51.0k|    }
  148|    262|    if (arraypos < src_1->cardinality) {
  ------------------
  |  Branch (148:9): [True: 262, False: 0]
  ------------------
  149|  2.21k|        while (arraypos < src_1->cardinality) {
  ------------------
  |  Branch (149:16): [True: 1.95k, False: 262]
  ------------------
  150|  1.95k|            run_container_append_value(src_2, src_1->array[arraypos],
  151|  1.95k|                                       &previousrle);
  152|  1.95k|            arraypos++;
  153|  1.95k|        }
  154|    262|    } else {
  155|      0|        while (rlepos < src2nruns) {
  ------------------
  |  Branch (155:16): [True: 0, False: 0]
  ------------------
  156|      0|            run_container_append(src_2, inputsrc2[rlepos], &previousrle);
  157|      0|            rlepos++;
  158|      0|        }
  159|      0|    }
  160|    262|}
array_array_container_union:
  164|  3.45k|                                 container_t **dst) {
  165|  3.45k|    int totalCardinality = src_1->cardinality + src_2->cardinality;
  166|  3.45k|    if (totalCardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (166:9): [True: 3.34k, False: 106]
  ------------------
  167|  3.34k|        *dst = array_container_create_given_capacity(totalCardinality);
  168|  3.34k|        if (*dst != NULL) {
  ------------------
  |  Branch (168:13): [True: 3.34k, False: 0]
  ------------------
  169|  3.34k|            array_container_union(src_1, src_2, CAST_array(*dst));
  ------------------
  |  |   54|  3.34k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  3.34k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  170|  3.34k|        } else {
  171|      0|            return true;  // otherwise failure won't be caught
  172|      0|        }
  173|  3.34k|        return false;  // not a bitset
  174|  3.34k|    }
  175|    106|    *dst = bitset_container_create();
  176|    106|    bool returnval = true;  // expect a bitset
  177|    106|    if (*dst != NULL) {
  ------------------
  |  Branch (177:9): [True: 106, False: 0]
  ------------------
  178|    106|        bitset_container_t *ourbitset = CAST_bitset(*dst);
  ------------------
  |  |   52|    106|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    106|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  179|    106|        bitset_set_list(ourbitset->words, src_1->array, src_1->cardinality);
  180|    106|        ourbitset->cardinality = (int32_t)bitset_set_list_withcard(
  181|    106|            ourbitset->words, src_1->cardinality, src_2->array,
  182|    106|            src_2->cardinality);
  183|    106|        if (ourbitset->cardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (183:13): [True: 65, False: 41]
  ------------------
  184|       |            // need to convert!
  185|     65|            *dst = array_container_from_bitset(ourbitset);
  186|     65|            bitset_container_free(ourbitset);
  187|       |            returnval = false;  // not going to be a bitset
  188|     65|        }
  189|    106|    }
  190|    106|    return returnval;
  191|  3.45k|}
array_array_container_inplace_union:
  195|  3.62k|                                         container_t **dst) {
  196|  3.62k|    int totalCardinality = src_1->cardinality + src_2->cardinality;
  197|  3.62k|    *dst = NULL;
  198|  3.62k|    if (totalCardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (198:9): [True: 3.54k, False: 80]
  ------------------
  199|  3.54k|        if (src_1->capacity < totalCardinality) {
  ------------------
  |  Branch (199:13): [True: 3.54k, False: 0]
  ------------------
  200|  3.54k|            *dst = array_container_create_given_capacity(
  201|  3.54k|                2 * totalCardinality);  // be purposefully generous
  202|  3.54k|            if (*dst != NULL) {
  ------------------
  |  Branch (202:17): [True: 3.54k, False: 0]
  ------------------
  203|  3.54k|                array_container_union(src_1, src_2, CAST_array(*dst));
  ------------------
  |  |   54|  3.54k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  3.54k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  204|  3.54k|            } else {
  205|      0|                return true;  // otherwise failure won't be caught
  206|      0|            }
  207|  3.54k|            return false;  // not a bitset
  208|  3.54k|        } else {
  209|       |            // fast_union_uint16 cannot work in place: its vectorized stores
  210|       |            // could overwrite values not yet read.
  211|       |            // https://github.com/RoaringBitmap/CRoaring/pull/452
  212|       |            // See report https://github.com/RoaringBitmap/CRoaring/issues/476
  213|       |            // So we copy src_1 aside first, which costs about as much as
  214|       |            // moving it to the end of its array for the scalar union.
  215|      0|            uint16_t buffer[DEFAULT_MAX_SIZE];
  216|      0|            memcpy(buffer, src_1->array, src_1->cardinality * sizeof(uint16_t));
  217|      0|            src_1->cardinality = (int32_t)fast_union_uint16(
  218|      0|                buffer, src_1->cardinality, src_2->array, src_2->cardinality,
  219|      0|                src_1->array);
  220|      0|            return false;  // not a bitset
  221|      0|        }
  222|  3.54k|    }
  223|     80|    *dst = bitset_container_create();
  224|     80|    bool returnval = true;  // expect a bitset
  225|     80|    if (*dst != NULL) {
  ------------------
  |  Branch (225:9): [True: 80, False: 0]
  ------------------
  226|     80|        bitset_container_t *ourbitset = CAST_bitset(*dst);
  ------------------
  |  |   52|     80|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|     80|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  227|     80|        bitset_set_list(ourbitset->words, src_1->array, src_1->cardinality);
  228|     80|        ourbitset->cardinality = (int32_t)bitset_set_list_withcard(
  229|     80|            ourbitset->words, src_1->cardinality, src_2->array,
  230|     80|            src_2->cardinality);
  231|     80|        if (ourbitset->cardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (231:13): [True: 80, False: 0]
  ------------------
  232|       |            // need to convert!
  233|     80|            if (src_1->capacity < ourbitset->cardinality) {
  ------------------
  |  Branch (233:17): [True: 80, False: 0]
  ------------------
  234|     80|                array_container_grow(src_1, ourbitset->cardinality, false);
  235|     80|            }
  236|       |
  237|     80|            bitset_extract_setbits_uint16(ourbitset->words,
  238|     80|                                          BITSET_CONTAINER_SIZE_IN_WORDS,
  239|     80|                                          src_1->array, 0);
  240|     80|            src_1->cardinality = ourbitset->cardinality;
  241|     80|            *dst = src_1;
  242|     80|            bitset_container_free(ourbitset);
  243|       |            returnval = false;  // not going to be a bitset
  244|     80|        }
  245|     80|    }
  246|     80|    return returnval;
  247|  3.62k|}

array_bitset_container_xor:
   25|    641|                                container_t **dst) {
   26|    641|    bitset_container_t *result = bitset_container_create();
   27|    641|    bitset_container_copy(src_2, result);
   28|    641|    result->cardinality = (int32_t)bitset_flip_list_withcard(
   29|    641|        result->words, result->cardinality, src_1->array, src_1->cardinality);
   30|       |
   31|       |    // do required type conversions.
   32|    641|    if (result->cardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (32:9): [True: 136, False: 505]
  ------------------
   33|    136|        *dst = array_container_from_bitset(result);
   34|    136|        bitset_container_free(result);
   35|    136|        return false;  // not bitset
   36|    136|    }
   37|    505|    *dst = result;
   38|       |    return true;  // bitset
   39|    641|}
run_bitset_container_xor:
   63|    675|                              container_t **dst) {
   64|    675|    bitset_container_t *result = bitset_container_create();
   65|       |
   66|    675|    bitset_container_copy(src_2, result);
   67|  50.0k|    for (int32_t rlepos = 0; rlepos < src_1->n_runs; ++rlepos) {
  ------------------
  |  Branch (67:30): [True: 49.3k, False: 675]
  ------------------
   68|  49.3k|        rle16_t rle = src_1->runs[rlepos];
   69|  49.3k|        bitset_flip_range(result->words, rle.value,
   70|  49.3k|                          rle.value + rle.length + UINT32_C(1));
   71|  49.3k|    }
   72|    675|    result->cardinality = bitset_container_compute_cardinality(result);
   73|       |
   74|    675|    if (result->cardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (74:9): [True: 170, False: 505]
  ------------------
   75|    170|        *dst = array_container_from_bitset(result);
   76|    170|        bitset_container_free(result);
   77|    170|        return false;  // not bitset
   78|    170|    }
   79|    505|    *dst = result;
   80|       |    return true;  // bitset
   81|    675|}
array_run_container_xor:
  105|  2.06k|                            const run_container_t *src_2, container_t **dst) {
  106|       |    // semi following Java XOR implementation as of May 2016
  107|       |    // the C OR implementation works quite differently and can return a run
  108|       |    // container
  109|       |    // TODO could optimize for full run containers.
  110|       |
  111|       |    // use of lazy following Java impl.
  112|  2.06k|    const int arbitrary_threshold = 32;
  113|  2.06k|    if (src_1->cardinality < arbitrary_threshold) {
  ------------------
  |  Branch (113:9): [True: 827, False: 1.23k]
  ------------------
  114|    827|        run_container_t *ans = run_container_create();
  115|    827|        array_run_container_lazy_xor(src_1, src_2, ans);  // keeps runs.
  116|    827|        uint8_t typecode_after;
  117|    827|        *dst =
  118|    827|            convert_run_to_efficient_container_and_free(ans, &typecode_after);
  119|    827|        return typecode_after;
  120|    827|    }
  121|       |
  122|  1.23k|    int card = run_container_cardinality(src_2);
  123|  1.23k|    if (card <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (123:9): [True: 1.04k, False: 189]
  ------------------
  124|       |        // Java implementation works with the array, xoring the run elements via
  125|       |        // iterator
  126|  1.04k|        array_container_t *temp = array_container_from_run(src_2);
  127|  1.04k|        bool ret_is_bitset = array_array_container_xor(temp, src_1, dst);
  128|  1.04k|        array_container_free(temp);
  129|  1.04k|        return ret_is_bitset ? BITSET_CONTAINER_TYPE : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   48|      1|#define BITSET_CONTAINER_TYPE 1
  ------------------
                      return ret_is_bitset ? BITSET_CONTAINER_TYPE : ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  1.04k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (129:16): [True: 1, False: 1.04k]
  ------------------
  130|       |
  131|  1.04k|    } else {  // guess that it will end up as a bitset
  132|    189|        bitset_container_t *result = bitset_container_from_run(src_2);
  133|    189|        bool is_bitset = bitset_array_container_ixor(result, src_1, dst);
  134|       |        // any necessary type conversion has been done by the ixor
  135|    189|        int retval = (is_bitset ? BITSET_CONTAINER_TYPE : ARRAY_CONTAINER_TYPE);
  ------------------
  |  |   48|    173|#define BITSET_CONTAINER_TYPE 1
  ------------------
                      int retval = (is_bitset ? BITSET_CONTAINER_TYPE : ARRAY_CONTAINER_TYPE);
  ------------------
  |  |   49|     16|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  |  Branch (135:23): [True: 173, False: 16]
  ------------------
  136|    189|        return retval;
  137|    189|    }
  138|  1.23k|}
array_run_container_lazy_xor:
  147|    827|                                  run_container_t *dst) {
  148|    827|    run_container_grow(dst, src_1->cardinality + src_2->n_runs, false);
  149|    827|    int32_t rlepos = 0;
  150|    827|    int32_t arraypos = 0;
  151|    827|    dst->n_runs = 0;
  152|       |
  153|  26.2k|    while ((rlepos < src_2->n_runs) && (arraypos < src_1->cardinality)) {
  ------------------
  |  Branch (153:12): [True: 25.7k, False: 494]
  |  Branch (153:40): [True: 25.4k, False: 333]
  ------------------
  154|  25.4k|        if (src_2->runs[rlepos].value <= src_1->array[arraypos]) {
  ------------------
  |  Branch (154:13): [True: 15.3k, False: 10.0k]
  ------------------
  155|  15.3k|            run_container_smart_append_exclusive(dst, src_2->runs[rlepos].value,
  156|  15.3k|                                                 src_2->runs[rlepos].length);
  157|  15.3k|            rlepos++;
  158|  15.3k|        } else {
  159|  10.0k|            run_container_smart_append_exclusive(dst, src_1->array[arraypos],
  160|  10.0k|                                                 0);
  161|  10.0k|            arraypos++;
  162|  10.0k|        }
  163|  25.4k|    }
  164|  2.79k|    while (arraypos < src_1->cardinality) {
  ------------------
  |  Branch (164:12): [True: 1.96k, False: 827]
  ------------------
  165|  1.96k|        run_container_smart_append_exclusive(dst, src_1->array[arraypos], 0);
  166|  1.96k|        arraypos++;
  167|  1.96k|    }
  168|  6.60k|    while (rlepos < src_2->n_runs) {
  ------------------
  |  Branch (168:12): [True: 5.77k, False: 827]
  ------------------
  169|  5.77k|        run_container_smart_append_exclusive(dst, src_2->runs[rlepos].value,
  170|  5.77k|                                             src_2->runs[rlepos].length);
  171|  5.77k|        rlepos++;
  172|  5.77k|    }
  173|    827|}
run_run_container_xor:
  180|  53.7k|                          const run_container_t *src_2, container_t **dst) {
  181|  53.7k|    run_container_t *ans = run_container_create();
  182|  53.7k|    run_container_xor(src_1, src_2, ans);
  183|  53.7k|    uint8_t typecode_after;
  184|  53.7k|    *dst = convert_run_to_efficient_container_and_free(ans, &typecode_after);
  185|  53.7k|    return typecode_after;
  186|  53.7k|}
array_array_container_xor:
  198|  9.87k|                               container_t **dst) {
  199|  9.87k|    int totalCardinality =
  200|  9.87k|        src_1->cardinality + src_2->cardinality;  // upper bound
  201|  9.87k|    if (totalCardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (201:9): [True: 9.28k, False: 589]
  ------------------
  202|  9.28k|        *dst = array_container_create_given_capacity(totalCardinality);
  203|  9.28k|        array_container_xor(src_1, src_2, CAST_array(*dst));
  ------------------
  |  |   54|  9.28k|#define CAST_array(c) CAST(array_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  9.28k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  204|  9.28k|        return false;  // not a bitset
  205|  9.28k|    }
  206|    589|    *dst = bitset_container_from_array(src_1);
  207|    589|    bool returnval = true;  // expect a bitset
  208|    589|    bitset_container_t *ourbitset = CAST_bitset(*dst);
  ------------------
  |  |   52|    589|#define CAST_bitset(c) CAST(bitset_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|    589|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
  209|    589|    ourbitset->cardinality = (uint32_t)bitset_flip_list_withcard(
  210|    589|        ourbitset->words, src_1->cardinality, src_2->array, src_2->cardinality);
  211|    589|    if (ourbitset->cardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (211:9): [True: 577, False: 12]
  ------------------
  212|       |        // need to convert!
  213|    577|        *dst = array_container_from_bitset(ourbitset);
  214|    577|        bitset_container_free(ourbitset);
  215|    577|        returnval = false;  // not going to be a bitset
  216|    577|    }
  217|       |
  218|    589|    return returnval;
  219|  9.87k|}
bitset_array_container_ixor:
  284|    189|                                 container_t **dst) {
  285|    189|    *dst = src_1;
  286|    189|    src_1->cardinality = (uint32_t)bitset_flip_list_withcard(
  287|    189|        src_1->words, src_1->cardinality, src_2->array, src_2->cardinality);
  288|       |
  289|    189|    if (src_1->cardinality <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (289:9): [True: 16, False: 173]
  ------------------
  290|     16|        *dst = array_container_from_bitset(src_1);
  291|     16|        bitset_container_free(src_1);
  292|     16|        return false;  // not bitset
  293|     16|    } else
  294|    173|        return true;
  295|    189|}
bitset_bitset_container_ixor:
  304|  1.35k|                                  container_t **dst) {
  305|  1.35k|    int card = bitset_container_xor(src_1, src_2, src_1);
  306|  1.35k|    if (card <= DEFAULT_MAX_SIZE) {
  ------------------
  |  Branch (306:9): [True: 1.35k, False: 0]
  ------------------
  307|  1.35k|        *dst = array_container_from_bitset(src_1);
  308|  1.35k|        bitset_container_free(src_1);
  309|  1.35k|        return false;  // not bitset
  310|  1.35k|    } else {
  311|      0|        *dst = src_1;
  312|       |        return true;
  313|      0|    }
  314|  1.35k|}
array_bitset_container_ixor:
  318|     73|                                 container_t **dst) {
  319|       |    bool ans = array_bitset_container_xor(src_1, src_2, dst);
  320|     73|    array_container_free(src_1);
  321|     73|    return ans;
  322|     73|}
run_bitset_container_ixor:
  333|     10|                               container_t **dst) {
  334|       |    bool ans = run_bitset_container_xor(src_1, src_2, dst);
  335|     10|    run_container_free(src_1);
  336|     10|    return ans;
  337|     10|}
bitset_run_container_ixor:
  341|     72|                               container_t **dst) {
  342|       |    bool ans = run_bitset_container_xor(src_2, src_1, dst);
  343|     72|    bitset_container_free(src_1);
  344|     72|    return ans;
  345|     72|}
array_run_container_ixor:
  352|    237|                             const run_container_t *src_2, container_t **dst) {
  353|    237|    int ans = array_run_container_xor(src_1, src_2, dst);
  354|    237|    array_container_free(src_1);
  355|    237|    return ans;
  356|    237|}
run_array_container_ixor:
  360|     65|                             container_t **dst) {
  361|     65|    int ans = array_run_container_xor(src_2, src_1, dst);
  362|     65|    run_container_free(src_1);
  363|     65|    return ans;
  364|     65|}
array_array_container_ixor:
  368|  5.36k|                                container_t **dst) {
  369|       |    bool ans = array_array_container_xor(src_1, src_2, dst);
  370|  5.36k|    array_container_free(src_1);
  371|  5.36k|    return ans;
  372|  5.36k|}
run_run_container_ixor:
  375|  53.0k|                           container_t **dst) {
  376|  53.0k|    int ans = run_run_container_xor(src_1, src_2, dst);
  377|  53.0k|    run_container_free(src_1);
  378|  53.0k|    return ans;
  379|  53.0k|}

run_container_add:
   39|   384k|bool run_container_add(run_container_t *run, uint16_t pos) {
   40|   384k|    int32_t index = interleavedBinarySearch(run->runs, run->n_runs, pos);
   41|   384k|    if (index >= 0) return false;  // already there
  ------------------
  |  Branch (41:9): [True: 185k, False: 198k]
  ------------------
   42|   198k|    index = -index - 2;            // points to preceding value, possibly -1
   43|   198k|    if (index >= 0) {              // possible match
  ------------------
  |  Branch (43:9): [True: 198k, False: 391]
  ------------------
   44|   198k|        int32_t offset = pos - run->runs[index].value;
   45|   198k|        int32_t le = run->runs[index].length;
   46|   198k|        if (offset <= le) return false;  // already there
  ------------------
  |  Branch (46:13): [True: 112k, False: 85.4k]
  ------------------
   47|  85.4k|        if (offset == le + 1) {
  ------------------
  |  Branch (47:13): [True: 13.0k, False: 72.3k]
  ------------------
   48|       |            // we may need to fuse
   49|  13.0k|            if (index + 1 < run->n_runs) {
  ------------------
  |  Branch (49:17): [True: 12.7k, False: 315]
  ------------------
   50|  12.7k|                if (run->runs[index + 1].value == pos + 1) {
  ------------------
  |  Branch (50:21): [True: 6.07k, False: 6.65k]
  ------------------
   51|       |                    // indeed fusion is needed
   52|  6.07k|                    run->runs[index].length = run->runs[index + 1].value +
   53|  6.07k|                                              run->runs[index + 1].length -
   54|  6.07k|                                              run->runs[index].value;
   55|  6.07k|                    recoverRoomAtIndex(run, (uint16_t)(index + 1));
   56|  6.07k|                    return true;
   57|  6.07k|                }
   58|  12.7k|            }
   59|  6.96k|            run->runs[index].length++;
   60|  6.96k|            return true;
   61|  13.0k|        }
   62|  72.3k|        if (index + 1 < run->n_runs) {
  ------------------
  |  Branch (62:13): [True: 70.6k, False: 1.72k]
  ------------------
   63|       |            // we may need to fuse
   64|  70.6k|            if (run->runs[index + 1].value == pos + 1) {
  ------------------
  |  Branch (64:17): [True: 31.1k, False: 39.5k]
  ------------------
   65|       |                // indeed fusion is needed
   66|  31.1k|                run->runs[index + 1].value = pos;
   67|  31.1k|                run->runs[index + 1].length = run->runs[index + 1].length + 1;
   68|  31.1k|                return true;
   69|  31.1k|            }
   70|  70.6k|        }
   71|  72.3k|    }
   72|  41.6k|    if (index == -1) {
  ------------------
  |  Branch (72:9): [True: 391, False: 41.2k]
  ------------------
   73|       |        // we may need to extend the first run
   74|    391|        if (0 < run->n_runs) {
  ------------------
  |  Branch (74:13): [True: 391, False: 0]
  ------------------
   75|    391|            if (run->runs[0].value == pos + 1) {
  ------------------
  |  Branch (75:17): [True: 253, False: 138]
  ------------------
   76|    253|                run->runs[0].length++;
   77|    253|                run->runs[0].value--;
   78|    253|                return true;
   79|    253|            }
   80|    391|        }
   81|    391|    }
   82|  41.3k|    makeRoomAtIndex(run, (uint16_t)(index + 1));
   83|  41.3k|    run->runs[index + 1].value = pos;
   84|  41.3k|    run->runs[index + 1].length = 0;
   85|       |    return true;
   86|  41.6k|}
run_container_create_given_capacity:
   89|   360k|run_container_t *run_container_create_given_capacity(int32_t size) {
   90|   360k|    run_container_t *run;
   91|       |    /* Allocate the run container itself. */
   92|   360k|    if ((run = (run_container_t *)roaring_malloc(sizeof(run_container_t))) ==
  ------------------
  |  Branch (92:9): [True: 0, False: 360k]
  ------------------
   93|   360k|        NULL) {
   94|      0|        return NULL;
   95|      0|    }
   96|   360k|    if (size <= 0) {  // we don't want to rely on malloc(0)
  ------------------
  |  Branch (96:9): [True: 113k, False: 246k]
  ------------------
   97|   113k|        run->runs = NULL;
   98|   246k|    } else if ((run->runs = (rle16_t *)roaring_malloc(sizeof(rle16_t) *
  ------------------
  |  Branch (98:16): [True: 0, False: 246k]
  ------------------
   99|   246k|                                                      size)) == NULL) {
  100|      0|        roaring_free(run);
  101|      0|        return NULL;
  102|      0|    }
  103|   360k|    run->capacity = size;
  104|   360k|    run->n_runs = 0;
  105|   360k|    return run;
  106|   360k|}
run_container_shrink_to_fit:
  108|  2.41k|int run_container_shrink_to_fit(run_container_t *src) {
  109|  2.41k|    if (src->n_runs == src->capacity) return 0;  // nothing to do
  ------------------
  |  Branch (109:9): [True: 2.41k, False: 0]
  ------------------
  110|      0|    int savings = src->capacity - src->n_runs;
  111|      0|    src->capacity = src->n_runs;
  112|      0|    rle16_t *oldruns = src->runs;
  113|      0|    src->runs =
  114|      0|        (rle16_t *)roaring_realloc(oldruns, src->capacity * sizeof(rle16_t));
  115|      0|    if (src->runs == NULL) roaring_free(oldruns);  // should never happen?
  ------------------
  |  Branch (115:9): [True: 0, False: 0]
  ------------------
  116|      0|    return savings;
  117|  2.41k|}
run_container_create:
  119|   113k|run_container_t *run_container_create(void) {
  120|   113k|    return run_container_create_given_capacity(RUN_DEFAULT_INIT_SIZE);
  121|   113k|}
run_container_clone:
  124|   158k|run_container_t *run_container_clone(const run_container_t *src) {
  125|   158k|    run_container_t *run = run_container_create_given_capacity(src->capacity);
  126|   158k|    if (run == NULL) return NULL;
  ------------------
  |  Branch (126:9): [True: 0, False: 158k]
  ------------------
  127|   158k|    run->capacity = src->capacity;
  128|   158k|    run->n_runs = src->n_runs;
  129|   158k|    memcpy(run->runs, src->runs, src->n_runs * sizeof(rle16_t));
  130|   158k|    return run;
  131|   158k|}
run_container_free:
  193|   360k|void run_container_free(run_container_t *run) {
  194|   360k|    if (run == NULL) return;
  ------------------
  |  Branch (194:9): [True: 0, False: 360k]
  ------------------
  195|   360k|    roaring_free(run->runs);
  196|   360k|    roaring_free(run);
  197|   360k|}
run_container_grow:
  199|   118k|void run_container_grow(run_container_t *run, int32_t min, bool copy) {
  200|   118k|    int32_t newCapacity = (run->capacity == 0)   ? RUN_DEFAULT_INIT_SIZE
  ------------------
  |  Branch (200:27): [True: 113k, False: 4.97k]
  ------------------
  201|   118k|                          : run->capacity < 64   ? run->capacity * 2
  ------------------
  |  Branch (201:29): [True: 3.59k, False: 1.38k]
  ------------------
  202|  4.97k|                          : run->capacity < 1024 ? run->capacity * 3 / 2
  ------------------
  |  Branch (202:29): [True: 1.38k, False: 0]
  ------------------
  203|  1.38k|                                                 : run->capacity * 5 / 4;
  204|   118k|    if (newCapacity < min) newCapacity = min;
  ------------------
  |  Branch (204:9): [True: 115k, False: 3.17k]
  ------------------
  205|   118k|    run->capacity = newCapacity;
  206|   118k|    assert(run->capacity >= min);
  207|   118k|    if (copy) {
  ------------------
  |  Branch (207:9): [True: 4.97k, False: 113k]
  ------------------
  208|  4.97k|        rle16_t *oldruns = run->runs;
  209|  4.97k|        run->runs = (rle16_t *)roaring_realloc(oldruns,
  210|  4.97k|                                               run->capacity * sizeof(rle16_t));
  211|  4.97k|        if (run->runs == NULL) roaring_free(oldruns);
  ------------------
  |  Branch (211:13): [True: 0, False: 4.97k]
  ------------------
  212|   113k|    } else {
  213|   113k|        roaring_free(run->runs);
  214|   113k|        run->runs = (rle16_t *)roaring_malloc(run->capacity * sizeof(rle16_t));
  215|   113k|    }
  216|       |    // We may have run->runs == NULL.
  217|   118k|}
run_container_copy:
  220|  51.3k|void run_container_copy(const run_container_t *src, run_container_t *dst) {
  221|  51.3k|    const int32_t n_runs = src->n_runs;
  222|  51.3k|    if (src->n_runs > dst->capacity) {
  ------------------
  |  Branch (222:9): [True: 51.3k, False: 25]
  ------------------
  223|       |        run_container_grow(dst, n_runs, false);
  224|  51.3k|    }
  225|  51.3k|    dst->n_runs = n_runs;
  226|  51.3k|    memcpy(dst->runs, src->runs, sizeof(rle16_t) * n_runs);
  227|  51.3k|}
run_container_union:
  233|    710|                         const run_container_t *src_2, run_container_t *dst) {
  234|       |    // TODO: this could be a lot more efficient
  235|       |
  236|       |    // we start out with inexpensive checks
  237|    710|    const bool if1 = run_container_is_full(src_1);
  238|    710|    const bool if2 = run_container_is_full(src_2);
  239|    710|    if (if1 || if2) {
  ------------------
  |  Branch (239:9): [True: 0, False: 710]
  |  Branch (239:16): [True: 10, False: 700]
  ------------------
  240|     10|        if (if1) {
  ------------------
  |  Branch (240:13): [True: 0, False: 10]
  ------------------
  241|      0|            run_container_copy(src_1, dst);
  242|      0|            return;
  243|      0|        }
  244|     10|        if (if2) {
  ------------------
  |  Branch (244:13): [True: 10, False: 0]
  ------------------
  245|     10|            run_container_copy(src_2, dst);
  246|     10|            return;
  247|     10|        }
  248|     10|    }
  249|    700|    const int32_t neededcapacity = src_1->n_runs + src_2->n_runs;
  250|    700|    if (dst->capacity < neededcapacity)
  ------------------
  |  Branch (250:9): [True: 700, False: 0]
  ------------------
  251|    700|        run_container_grow(dst, neededcapacity, false);
  252|    700|    dst->n_runs = 0;
  253|    700|    int32_t rlepos = 0;
  254|    700|    int32_t xrlepos = 0;
  255|       |
  256|    700|    rle16_t previousrle;
  257|    700|    if (src_1->runs[rlepos].value <= src_2->runs[xrlepos].value) {
  ------------------
  |  Branch (257:9): [True: 651, False: 49]
  ------------------
  258|    651|        previousrle = run_container_append_first(dst, src_1->runs[rlepos]);
  259|    651|        rlepos++;
  260|    651|    } else {
  261|     49|        previousrle = run_container_append_first(dst, src_2->runs[xrlepos]);
  262|     49|        xrlepos++;
  263|     49|    }
  264|       |
  265|  83.7k|    while ((xrlepos < src_2->n_runs) && (rlepos < src_1->n_runs)) {
  ------------------
  |  Branch (265:12): [True: 83.5k, False: 287]
  |  Branch (265:41): [True: 83.0k, False: 413]
  ------------------
  266|  83.0k|        rle16_t newrl;
  267|  83.0k|        if (src_1->runs[rlepos].value <= src_2->runs[xrlepos].value) {
  ------------------
  |  Branch (267:13): [True: 46.5k, False: 36.5k]
  ------------------
  268|  46.5k|            newrl = src_1->runs[rlepos];
  269|  46.5k|            rlepos++;
  270|  46.5k|        } else {
  271|  36.5k|            newrl = src_2->runs[xrlepos];
  272|  36.5k|            xrlepos++;
  273|  36.5k|        }
  274|  83.0k|        run_container_append(dst, newrl, &previousrle);
  275|  83.0k|    }
  276|  1.69k|    while (xrlepos < src_2->n_runs) {
  ------------------
  |  Branch (276:12): [True: 999, False: 700]
  ------------------
  277|    999|        run_container_append(dst, src_2->runs[xrlepos], &previousrle);
  278|    999|        xrlepos++;
  279|    999|    }
  280|  11.0k|    while (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (280:12): [True: 10.3k, False: 700]
  ------------------
  281|  10.3k|        run_container_append(dst, src_1->runs[rlepos], &previousrle);
  282|  10.3k|        rlepos++;
  283|  10.3k|    }
  284|    700|}
run_container_union_inplace:
  290|  1.56k|                                 const run_container_t *src_2) {
  291|       |    // TODO: this could be a lot more efficient
  292|       |
  293|       |    // we start out with inexpensive checks
  294|  1.56k|    const bool if1 = run_container_is_full(src_1);
  295|  1.56k|    const bool if2 = run_container_is_full(src_2);
  296|  1.56k|    if (if1 || if2) {
  ------------------
  |  Branch (296:9): [True: 0, False: 1.56k]
  |  Branch (296:16): [True: 25, False: 1.53k]
  ------------------
  297|     25|        if (if1) {
  ------------------
  |  Branch (297:13): [True: 0, False: 25]
  ------------------
  298|      0|            return;
  299|      0|        }
  300|     25|        if (if2) {
  ------------------
  |  Branch (300:13): [True: 25, False: 0]
  ------------------
  301|     25|            run_container_copy(src_2, src_1);
  302|     25|            return;
  303|     25|        }
  304|     25|    }
  305|       |    // we move the data to the end of the current array
  306|  1.53k|    const int32_t maxoutput = src_1->n_runs + src_2->n_runs;
  307|  1.53k|    const int32_t neededcapacity = maxoutput + src_1->n_runs;
  308|  1.53k|    if (src_1->capacity < neededcapacity)
  ------------------
  |  Branch (308:9): [True: 1.53k, False: 0]
  ------------------
  309|  1.53k|        run_container_grow(src_1, neededcapacity, true);
  310|  1.53k|    memmove(src_1->runs + maxoutput, src_1->runs,
  311|  1.53k|            src_1->n_runs * sizeof(rle16_t));
  312|  1.53k|    rle16_t *inputsrc1 = src_1->runs + maxoutput;
  313|  1.53k|    const int32_t input1nruns = src_1->n_runs;
  314|  1.53k|    src_1->n_runs = 0;
  315|  1.53k|    int32_t rlepos = 0;
  316|  1.53k|    int32_t xrlepos = 0;
  317|       |
  318|  1.53k|    rle16_t previousrle;
  319|  1.53k|    if (inputsrc1[rlepos].value <= src_2->runs[xrlepos].value) {
  ------------------
  |  Branch (319:9): [True: 1.45k, False: 82]
  ------------------
  320|  1.45k|        previousrle = run_container_append_first(src_1, inputsrc1[rlepos]);
  321|  1.45k|        rlepos++;
  322|  1.45k|    } else {
  323|     82|        previousrle = run_container_append_first(src_1, src_2->runs[xrlepos]);
  324|     82|        xrlepos++;
  325|     82|    }
  326|   174k|    while ((xrlepos < src_2->n_runs) && (rlepos < input1nruns)) {
  ------------------
  |  Branch (326:12): [True: 174k, False: 125]
  |  Branch (326:41): [True: 172k, False: 1.41k]
  ------------------
  327|   172k|        rle16_t newrl;
  328|   172k|        if (inputsrc1[rlepos].value <= src_2->runs[xrlepos].value) {
  ------------------
  |  Branch (328:13): [True: 83.2k, False: 89.4k]
  ------------------
  329|  83.2k|            newrl = inputsrc1[rlepos];
  330|  83.2k|            rlepos++;
  331|  89.4k|        } else {
  332|  89.4k|            newrl = src_2->runs[xrlepos];
  333|  89.4k|            xrlepos++;
  334|  89.4k|        }
  335|   172k|        run_container_append(src_1, newrl, &previousrle);
  336|   172k|    }
  337|  4.10k|    while (xrlepos < src_2->n_runs) {
  ------------------
  |  Branch (337:12): [True: 2.56k, False: 1.53k]
  ------------------
  338|  2.56k|        run_container_append(src_1, src_2->runs[xrlepos], &previousrle);
  339|  2.56k|        xrlepos++;
  340|  2.56k|    }
  341|  8.08k|    while (rlepos < input1nruns) {
  ------------------
  |  Branch (341:12): [True: 6.54k, False: 1.53k]
  ------------------
  342|  6.54k|        run_container_append(src_1, inputsrc1[rlepos], &previousrle);
  343|  6.54k|        rlepos++;
  344|  6.54k|    }
  345|  1.53k|}
run_container_xor:
  352|  53.7k|                       const run_container_t *src_2, run_container_t *dst) {
  353|       |    // don't bother to convert xor with full range into negation
  354|       |    // since negation is implemented similarly
  355|       |
  356|  53.7k|    const int32_t neededcapacity = src_1->n_runs + src_2->n_runs;
  357|  53.7k|    if (dst->capacity < neededcapacity)
  ------------------
  |  Branch (357:9): [True: 53.7k, False: 0]
  ------------------
  358|  53.7k|        run_container_grow(dst, neededcapacity, false);
  359|       |
  360|  53.7k|    rle16_t *out = dst->runs;
  361|  53.7k|    int32_t n_out = 0;
  362|  53.7k|    int32_t pos1 = 0;
  363|  53.7k|    int32_t pos2 = 0;
  364|       |
  365|   224k|    while ((pos1 < src_1->n_runs) && (pos2 < src_2->n_runs)) {
  ------------------
  |  Branch (365:12): [True: 170k, False: 53.4k]
  |  Branch (365:38): [True: 170k, False: 305]
  ------------------
  366|   170k|        if (src_1->runs[pos1].value <= src_2->runs[pos2].value) {
  ------------------
  |  Branch (366:13): [True: 115k, False: 55.1k]
  ------------------
  367|   115k|            n_out = run_append_exclusive(out, n_out, src_1->runs[pos1].value,
  368|   115k|                                         src_1->runs[pos1].length);
  369|   115k|            pos1++;
  370|   115k|        } else {
  371|  55.1k|            n_out = run_append_exclusive(out, n_out, src_2->runs[pos2].value,
  372|  55.1k|                                         src_2->runs[pos2].length);
  373|  55.1k|            pos2++;
  374|  55.1k|        }
  375|   170k|    }
  376|  64.9k|    while (pos1 < src_1->n_runs) {
  ------------------
  |  Branch (376:12): [True: 11.2k, False: 53.7k]
  ------------------
  377|  11.2k|        n_out = run_append_exclusive(out, n_out, src_1->runs[pos1].value,
  378|  11.2k|                                     src_1->runs[pos1].length);
  379|  11.2k|        pos1++;
  380|  11.2k|    }
  381|       |
  382|   108k|    while (pos2 < src_2->n_runs) {
  ------------------
  |  Branch (382:12): [True: 55.1k, False: 53.7k]
  ------------------
  383|  55.1k|        n_out = run_append_exclusive(out, n_out, src_2->runs[pos2].value,
  384|  55.1k|                                     src_2->runs[pos2].length);
  385|  55.1k|        pos2++;
  386|  55.1k|    }
  387|  53.7k|    dst->n_runs = n_out;
  388|  53.7k|}
run_container_intersection:
  395|  54.6k|                                run_container_t *dst) {
  396|  54.6k|    const bool if1 = run_container_is_full(src_1);
  397|  54.6k|    const bool if2 = run_container_is_full(src_2);
  398|  54.6k|    if (if1 || if2) {
  ------------------
  |  Branch (398:9): [True: 51.2k, False: 3.38k]
  |  Branch (398:16): [True: 10, False: 3.37k]
  ------------------
  399|  51.2k|        if (if1) {
  ------------------
  |  Branch (399:13): [True: 51.2k, False: 10]
  ------------------
  400|  51.2k|            run_container_copy(src_2, dst);
  401|  51.2k|            return;
  402|  51.2k|        }
  403|     10|        if (if2) {
  ------------------
  |  Branch (403:13): [True: 10, False: 0]
  ------------------
  404|     10|            run_container_copy(src_1, dst);
  405|     10|            return;
  406|     10|        }
  407|     10|    }
  408|       |    // TODO: this could be a lot more efficient, could use SIMD optimizations
  409|  3.37k|    const int32_t neededcapacity = src_1->n_runs + src_2->n_runs;
  410|  3.37k|    if (dst->capacity < neededcapacity)
  ------------------
  |  Branch (410:9): [True: 3.37k, False: 0]
  ------------------
  411|  3.37k|        run_container_grow(dst, neededcapacity, false);
  412|  3.37k|    dst->n_runs = 0;
  413|  3.37k|    int32_t rlepos = 0;
  414|  3.37k|    int32_t xrlepos = 0;
  415|  3.37k|    int32_t start = src_1->runs[rlepos].value;
  416|  3.37k|    int32_t end = start + src_1->runs[rlepos].length + 1;
  417|  3.37k|    int32_t xstart = src_2->runs[xrlepos].value;
  418|  3.37k|    int32_t xend = xstart + src_2->runs[xrlepos].length + 1;
  419|   169k|    while ((rlepos < src_1->n_runs) && (xrlepos < src_2->n_runs)) {
  ------------------
  |  Branch (419:12): [True: 167k, False: 2.89k]
  |  Branch (419:40): [True: 166k, False: 477]
  ------------------
  420|   166k|        if (end <= xstart) {
  ------------------
  |  Branch (420:13): [True: 43.0k, False: 123k]
  ------------------
  421|  43.0k|            ++rlepos;
  422|  43.0k|            if (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (422:17): [True: 42.9k, False: 84]
  ------------------
  423|  42.9k|                start = src_1->runs[rlepos].value;
  424|  42.9k|                end = start + src_1->runs[rlepos].length + 1;
  425|  42.9k|            }
  426|   123k|        } else if (xend <= start) {
  ------------------
  |  Branch (426:20): [True: 10.8k, False: 112k]
  ------------------
  427|  10.8k|            ++xrlepos;
  428|  10.8k|            if (xrlepos < src_2->n_runs) {
  ------------------
  |  Branch (428:17): [True: 10.8k, False: 42]
  ------------------
  429|  10.8k|                xstart = src_2->runs[xrlepos].value;
  430|  10.8k|                xend = xstart + src_2->runs[xrlepos].length + 1;
  431|  10.8k|            }
  432|   112k|        } else {  // they overlap
  433|   112k|            const int32_t lateststart = start > xstart ? start : xstart;
  ------------------
  |  Branch (433:41): [True: 14.3k, False: 98.3k]
  ------------------
  434|   112k|            int32_t earliestend;
  435|   112k|            if (end == xend) {  // improbable
  ------------------
  |  Branch (435:17): [True: 85.3k, False: 27.3k]
  ------------------
  436|  85.3k|                earliestend = end;
  437|  85.3k|                rlepos++;
  438|  85.3k|                xrlepos++;
  439|  85.3k|                if (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (439:21): [True: 82.6k, False: 2.65k]
  ------------------
  440|  82.6k|                    start = src_1->runs[rlepos].value;
  441|  82.6k|                    end = start + src_1->runs[rlepos].length + 1;
  442|  82.6k|                }
  443|  85.3k|                if (xrlepos < src_2->n_runs) {
  ------------------
  |  Branch (443:21): [True: 82.4k, False: 2.88k]
  ------------------
  444|  82.4k|                    xstart = src_2->runs[xrlepos].value;
  445|  82.4k|                    xend = xstart + src_2->runs[xrlepos].length + 1;
  446|  82.4k|                }
  447|  85.3k|            } else if (end < xend) {
  ------------------
  |  Branch (447:24): [True: 14.6k, False: 12.7k]
  ------------------
  448|  14.6k|                earliestend = end;
  449|  14.6k|                rlepos++;
  450|  14.6k|                if (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (450:21): [True: 14.5k, False: 153]
  ------------------
  451|  14.5k|                    start = src_1->runs[rlepos].value;
  452|  14.5k|                    end = start + src_1->runs[rlepos].length + 1;
  453|  14.5k|                }
  454|       |
  455|  14.6k|            } else {  // end > xend
  456|  12.7k|                earliestend = xend;
  457|  12.7k|                xrlepos++;
  458|  12.7k|                if (xrlepos < src_2->n_runs) {
  ------------------
  |  Branch (458:21): [True: 12.5k, False: 144]
  ------------------
  459|  12.5k|                    xstart = src_2->runs[xrlepos].value;
  460|  12.5k|                    xend = xstart + src_2->runs[xrlepos].length + 1;
  461|  12.5k|                }
  462|  12.7k|            }
  463|   112k|            dst->runs[dst->n_runs].value = (uint16_t)lateststart;
  464|   112k|            dst->runs[dst->n_runs].length =
  465|   112k|                (uint16_t)(earliestend - lateststart - 1);
  466|   112k|            dst->n_runs++;
  467|   112k|        }
  468|   166k|    }
  469|  3.37k|}
run_container_intersection_cardinality:
  474|  2.84k|                                           const run_container_t *src_2) {
  475|  2.84k|    const bool if1 = run_container_is_full(src_1);
  476|  2.84k|    const bool if2 = run_container_is_full(src_2);
  477|  2.84k|    if (if1 || if2) {
  ------------------
  |  Branch (477:9): [True: 0, False: 2.84k]
  |  Branch (477:16): [True: 40, False: 2.80k]
  ------------------
  478|     40|        if (if1) {
  ------------------
  |  Branch (478:13): [True: 0, False: 40]
  ------------------
  479|      0|            return run_container_cardinality(src_2);
  480|      0|        }
  481|     40|        if (if2) {
  ------------------
  |  Branch (481:13): [True: 40, False: 0]
  ------------------
  482|     40|            return run_container_cardinality(src_1);
  483|     40|        }
  484|     40|    }
  485|  2.80k|    int answer = 0;
  486|  2.80k|    int32_t rlepos = 0;
  487|  2.80k|    int32_t xrlepos = 0;
  488|  2.80k|    int32_t start = src_1->runs[rlepos].value;
  489|  2.80k|    int32_t end = start + src_1->runs[rlepos].length + 1;
  490|  2.80k|    int32_t xstart = src_2->runs[xrlepos].value;
  491|  2.80k|    int32_t xend = xstart + src_2->runs[xrlepos].length + 1;
  492|   279k|    while ((rlepos < src_1->n_runs) && (xrlepos < src_2->n_runs)) {
  ------------------
  |  Branch (492:12): [True: 277k, False: 1.92k]
  |  Branch (492:40): [True: 276k, False: 876]
  ------------------
  493|   276k|        if (end <= xstart) {
  ------------------
  |  Branch (493:13): [True: 70.7k, False: 206k]
  ------------------
  494|  70.7k|            ++rlepos;
  495|  70.7k|            if (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (495:17): [True: 70.4k, False: 336]
  ------------------
  496|  70.4k|                start = src_1->runs[rlepos].value;
  497|  70.4k|                end = start + src_1->runs[rlepos].length + 1;
  498|  70.4k|            }
  499|   206k|        } else if (xend <= start) {
  ------------------
  |  Branch (499:20): [True: 43.5k, False: 162k]
  ------------------
  500|  43.5k|            ++xrlepos;
  501|  43.5k|            if (xrlepos < src_2->n_runs) {
  ------------------
  |  Branch (501:17): [True: 43.4k, False: 168]
  ------------------
  502|  43.4k|                xstart = src_2->runs[xrlepos].value;
  503|  43.4k|                xend = xstart + src_2->runs[xrlepos].length + 1;
  504|  43.4k|            }
  505|   162k|        } else {  // they overlap
  506|   162k|            const int32_t lateststart = start > xstart ? start : xstart;
  ------------------
  |  Branch (506:41): [True: 57.5k, False: 105k]
  ------------------
  507|   162k|            int32_t earliestend;
  508|   162k|            if (end == xend) {  // improbable
  ------------------
  |  Branch (508:17): [True: 86.1k, False: 76.4k]
  ------------------
  509|  86.1k|                earliestend = end;
  510|  86.1k|                rlepos++;
  511|  86.1k|                xrlepos++;
  512|  86.1k|                if (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (512:21): [True: 85.2k, False: 976]
  ------------------
  513|  85.2k|                    start = src_1->runs[rlepos].value;
  514|  85.2k|                    end = start + src_1->runs[rlepos].length + 1;
  515|  85.2k|                }
  516|  86.1k|                if (xrlepos < src_2->n_runs) {
  ------------------
  |  Branch (516:21): [True: 85.0k, False: 1.18k]
  ------------------
  517|  85.0k|                    xstart = src_2->runs[xrlepos].value;
  518|  85.0k|                    xend = xstart + src_2->runs[xrlepos].length + 1;
  519|  85.0k|                }
  520|  86.1k|            } else if (end < xend) {
  ------------------
  |  Branch (520:24): [True: 58.6k, False: 17.7k]
  ------------------
  521|  58.6k|                earliestend = end;
  522|  58.6k|                rlepos++;
  523|  58.6k|                if (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (523:21): [True: 58.0k, False: 612]
  ------------------
  524|  58.0k|                    start = src_1->runs[rlepos].value;
  525|  58.0k|                    end = start + src_1->runs[rlepos].length + 1;
  526|  58.0k|                }
  527|       |
  528|  58.6k|            } else {  // end > xend
  529|  17.7k|                earliestend = xend;
  530|  17.7k|                xrlepos++;
  531|  17.7k|                if (xrlepos < src_2->n_runs) {
  ------------------
  |  Branch (531:21): [True: 17.5k, False: 240]
  ------------------
  532|  17.5k|                    xstart = src_2->runs[xrlepos].value;
  533|  17.5k|                    xend = xstart + src_2->runs[xrlepos].length + 1;
  534|  17.5k|                }
  535|  17.7k|            }
  536|   162k|            answer += earliestend - lateststart;
  537|   162k|        }
  538|   276k|    }
  539|  2.80k|    return answer;
  540|  2.84k|}
run_container_intersect:
  544|    710|                             const run_container_t *src_2) {
  545|    710|    const bool if1 = run_container_is_full(src_1);
  546|    710|    const bool if2 = run_container_is_full(src_2);
  547|    710|    if (if1 || if2) {
  ------------------
  |  Branch (547:9): [True: 0, False: 710]
  |  Branch (547:16): [True: 10, False: 700]
  ------------------
  548|     10|        if (if1) {
  ------------------
  |  Branch (548:13): [True: 0, False: 10]
  ------------------
  549|      0|            return !run_container_empty(src_2);
  550|      0|        }
  551|     10|        if (if2) {
  ------------------
  |  Branch (551:13): [True: 10, False: 0]
  ------------------
  552|     10|            return !run_container_empty(src_1);
  553|     10|        }
  554|     10|    }
  555|    700|    int32_t rlepos = 0;
  556|    700|    int32_t xrlepos = 0;
  557|    700|    int32_t start = src_1->runs[rlepos].value;
  558|    700|    int32_t end = start + src_1->runs[rlepos].length + 1;
  559|    700|    int32_t xstart = src_2->runs[xrlepos].value;
  560|    700|    int32_t xend = xstart + src_2->runs[xrlepos].length + 1;
  561|  3.31k|    while ((rlepos < src_1->n_runs) && (xrlepos < src_2->n_runs)) {
  ------------------
  |  Branch (561:12): [True: 3.29k, False: 18]
  |  Branch (561:40): [True: 3.28k, False: 3]
  ------------------
  562|  3.28k|        if (end <= xstart) {
  ------------------
  |  Branch (562:13): [True: 2.13k, False: 1.15k]
  ------------------
  563|  2.13k|            ++rlepos;
  564|  2.13k|            if (rlepos < src_1->n_runs) {
  ------------------
  |  Branch (564:17): [True: 2.11k, False: 18]
  ------------------
  565|  2.11k|                start = src_1->runs[rlepos].value;
  566|  2.11k|                end = start + src_1->runs[rlepos].length + 1;
  567|  2.11k|            }
  568|  2.13k|        } else if (xend <= start) {
  ------------------
  |  Branch (568:20): [True: 473, False: 679]
  ------------------
  569|    473|            ++xrlepos;
  570|    473|            if (xrlepos < src_2->n_runs) {
  ------------------
  |  Branch (570:17): [True: 470, False: 3]
  ------------------
  571|    470|                xstart = src_2->runs[xrlepos].value;
  572|    470|                xend = xstart + src_2->runs[xrlepos].length + 1;
  573|    470|            }
  574|    679|        } else {  // they overlap
  575|    679|            return true;
  576|    679|        }
  577|  3.28k|    }
  578|     21|    return false;
  579|    700|}
run_container_andnot:
  585|  1.17k|                          const run_container_t *src_2, run_container_t *dst) {
  586|       |    // following Java implementation as of June 2016
  587|       |
  588|  1.17k|    if (dst->capacity < src_1->n_runs + src_2->n_runs)
  ------------------
  |  Branch (588:9): [True: 1.17k, False: 0]
  ------------------
  589|  1.17k|        run_container_grow(dst, src_1->n_runs + src_2->n_runs, false);
  590|       |
  591|  1.17k|    int32_t n_out = 0;
  592|       |
  593|  1.17k|    int rlepos1 = 0;
  594|  1.17k|    int rlepos2 = 0;
  595|  1.17k|    int32_t start = src_1->runs[rlepos1].value;
  596|  1.17k|    int32_t end = start + src_1->runs[rlepos1].length + 1;
  597|  1.17k|    int32_t start2 = src_2->runs[rlepos2].value;
  598|  1.17k|    int32_t end2 = start2 + src_2->runs[rlepos2].length + 1;
  599|       |
  600|   155k|    while ((rlepos1 < src_1->n_runs) && (rlepos2 < src_2->n_runs)) {
  ------------------
  |  Branch (600:12): [True: 154k, False: 720]
  |  Branch (600:41): [True: 154k, False: 451]
  ------------------
  601|   154k|        if (end <= start2) {
  ------------------
  |  Branch (601:13): [True: 23.5k, False: 130k]
  ------------------
  602|       |            // output the first run
  603|  23.5k|            dst->runs[n_out++] = CROARING_MAKE_RLE16(start, end - start - 1);
  ------------------
  |  |   60|  23.5k|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  604|  23.5k|            rlepos1++;
  605|  23.5k|            if (rlepos1 < src_1->n_runs) {
  ------------------
  |  Branch (605:17): [True: 23.4k, False: 84]
  ------------------
  606|  23.4k|                start = src_1->runs[rlepos1].value;
  607|  23.4k|                end = start + src_1->runs[rlepos1].length + 1;
  608|  23.4k|            }
  609|   130k|        } else if (end2 <= start) {
  ------------------
  |  Branch (609:20): [True: 63.2k, False: 67.4k]
  ------------------
  610|       |            // exit the second run
  611|  63.2k|            rlepos2++;
  612|  63.2k|            if (rlepos2 < src_2->n_runs) {
  ------------------
  |  Branch (612:17): [True: 62.7k, False: 451]
  ------------------
  613|  62.7k|                start2 = src_2->runs[rlepos2].value;
  614|  62.7k|                end2 = start2 + src_2->runs[rlepos2].length + 1;
  615|  62.7k|            }
  616|  67.4k|        } else {
  617|  67.4k|            if (start < start2) {
  ------------------
  |  Branch (617:17): [True: 17.2k, False: 50.2k]
  ------------------
  618|  17.2k|                dst->runs[n_out++] =
  619|  17.2k|                    CROARING_MAKE_RLE16(start, start2 - start - 1);
  ------------------
  |  |   60|  17.2k|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  620|  17.2k|            }
  621|  67.4k|            if (end2 < end) {
  ------------------
  |  Branch (621:17): [True: 16.8k, False: 50.6k]
  ------------------
  622|  16.8k|                start = end2;
  623|  50.6k|            } else {
  624|  50.6k|                rlepos1++;
  625|  50.6k|                if (rlepos1 < src_1->n_runs) {
  ------------------
  |  Branch (625:21): [True: 49.9k, False: 636]
  ------------------
  626|  49.9k|                    start = src_1->runs[rlepos1].value;
  627|  49.9k|                    end = start + src_1->runs[rlepos1].length + 1;
  628|  49.9k|                }
  629|  50.6k|            }
  630|  67.4k|        }
  631|   154k|    }
  632|  1.17k|    if (rlepos1 < src_1->n_runs) {
  ------------------
  |  Branch (632:9): [True: 451, False: 720]
  ------------------
  633|    451|        dst->runs[n_out++] = CROARING_MAKE_RLE16(start, end - start - 1);
  ------------------
  |  |   60|    451|    (rle16_t) { .value = (uint16_t)(val), .length = (uint16_t)(len) }
  ------------------
  634|    451|        rlepos1++;
  635|    451|        if (rlepos1 < src_1->n_runs) {
  ------------------
  |  Branch (635:13): [True: 222, False: 229]
  ------------------
  636|    222|            memcpy(dst->runs + n_out, src_1->runs + rlepos1,
  637|    222|                   sizeof(rle16_t) * (src_1->n_runs - rlepos1));
  638|    222|            n_out += src_1->n_runs - rlepos1;
  639|    222|        }
  640|    451|    }
  641|  1.17k|    dst->n_runs = n_out;
  642|  1.17k|}
run_container_read:
  749|     67|                           const char *buf) {
  750|     67|    (void)cardinality;
  751|     67|    uint16_t cast_16;
  752|     67|    memcpy(&cast_16, buf, sizeof(uint16_t));
  753|     67|    container->n_runs = croaring_letoh16(cast_16);
  ------------------
  |  |  530|     67|#define croaring_letoh16(x) croaring_htole16(x)
  |  |  ------------------
  |  |  |  |  524|     67|#define croaring_htole16(x) (x)
  |  |  ------------------
  ------------------
  754|     67|    if (container->n_runs > container->capacity)
  ------------------
  |  Branch (754:9): [True: 8, False: 59]
  ------------------
  755|      8|        run_container_grow(container, container->n_runs, false);
  756|     67|    if (container->n_runs > 0) {
  ------------------
  |  Branch (756:9): [True: 8, False: 59]
  ------------------
  757|       |#if CROARING_IS_BIG_ENDIAN
  758|       |        const char *in = buf + sizeof(uint16_t);
  759|       |        for (int32_t i = 0; i < container->n_runs; ++i) {
  760|       |            uint16_t v_le, l_le;
  761|       |            memcpy(&v_le, in, sizeof(uint16_t));
  762|       |            memcpy(&l_le, in + sizeof(uint16_t), sizeof(uint16_t));
  763|       |            container->runs[i].value = croaring_letoh16(v_le);
  764|       |            container->runs[i].length = croaring_letoh16(l_le);
  765|       |            in += sizeof(rle16_t);
  766|       |        }
  767|       |#else
  768|      8|        memcpy(container->runs, buf + sizeof(uint16_t),
  769|      8|               container->n_runs * sizeof(rle16_t));
  770|      8|#endif
  771|      8|    }
  772|     67|    return run_container_size_in_bytes(container);
  773|     67|}
run_container_iterate:
  777|  53.4k|                           roaring_iterator iterator, void *ptr) {
  778|   144k|    for (int i = 0; i < cont->n_runs; ++i) {
  ------------------
  |  Branch (778:21): [True: 90.6k, False: 53.4k]
  ------------------
  779|  90.6k|        uint32_t run_start = base + cont->runs[i].value;
  780|  90.6k|        uint16_t le = cont->runs[i].length;
  781|       |
  782|  3.42G|        for (int j = 0; j <= le; ++j)
  ------------------
  |  Branch (782:25): [True: 3.42G, False: 90.6k]
  ------------------
  783|  3.42G|            if (!iterator(run_start + j, ptr)) return false;
  ------------------
  |  Branch (783:17): [True: 0, False: 3.42G]
  ------------------
  784|  90.6k|    }
  785|  53.4k|    return true;
  786|  53.4k|}
run_container_is_subset:
  805|    254|                             const run_container_t *container2) {
  806|    254|    int i1 = 0, i2 = 0;
  807|    921|    while (i1 < container1->n_runs && i2 < container2->n_runs) {
  ------------------
  |  Branch (807:12): [True: 921, False: 0]
  |  Branch (807:39): [True: 900, False: 21]
  ------------------
  808|    900|        int start1 = container1->runs[i1].value;
  809|    900|        int stop1 = start1 + container1->runs[i1].length;
  810|    900|        int start2 = container2->runs[i2].value;
  811|    900|        int stop2 = start2 + container2->runs[i2].length;
  812|    900|        if (start1 < start2) {
  ------------------
  |  Branch (812:13): [True: 233, False: 667]
  ------------------
  813|    233|            return false;
  814|    667|        } else {  // start1 >= start2
  815|    667|            if (stop1 < stop2) {
  ------------------
  |  Branch (815:17): [True: 0, False: 667]
  ------------------
  816|      0|                i1++;
  817|    667|            } else if (stop1 == stop2) {
  ------------------
  |  Branch (817:24): [True: 0, False: 667]
  ------------------
  818|      0|                i1++;
  819|      0|                i2++;
  820|    667|            } else {  // stop1 > stop2
  821|    667|                i2++;
  822|    667|            }
  823|    667|        }
  824|    900|    }
  825|     21|    if (i1 == container1->n_runs) {
  ------------------
  |  Branch (825:9): [True: 0, False: 21]
  ------------------
  826|      0|        return true;
  827|     21|    } else {
  828|       |        return false;
  829|     21|    }
  830|     21|}
run_container_smart_append_exclusive:
  837|   129k|                                          const uint16_t length) {
  838|   129k|    src->n_runs = run_append_exclusive(src->runs, src->n_runs, start, length);
  839|   129k|}
run_container_select:
  844|  2.41k|                          uint32_t *element) {
  845|  11.5k|    for (int i = 0; i < container->n_runs; i++) {
  ------------------
  |  Branch (845:21): [True: 11.4k, False: 74]
  ------------------
  846|  11.4k|        uint16_t length = container->runs[i].length;
  847|  11.4k|        if (rank <= *start_rank + length) {
  ------------------
  |  Branch (847:13): [True: 2.34k, False: 9.11k]
  ------------------
  848|  2.34k|            uint16_t value = container->runs[i].value;
  849|  2.34k|            *element = value + rank - (*start_rank);
  850|  2.34k|            return true;
  851|  2.34k|        } else
  852|  9.11k|            *start_rank += length + 1;
  853|  11.4k|    }
  854|     74|    return false;
  855|  2.41k|}
run_container_rank:
  858|  2.41k|int run_container_rank(const run_container_t *container, uint16_t x) {
  859|  2.41k|    int sum = 0;
  860|  2.41k|    uint32_t x32 = x;
  861|  10.9k|    for (int i = 0; i < container->n_runs; i++) {
  ------------------
  |  Branch (861:21): [True: 10.9k, False: 68]
  ------------------
  862|  10.9k|        uint32_t startpoint = container->runs[i].value;
  863|  10.9k|        uint32_t length = container->runs[i].length;
  864|  10.9k|        uint32_t endpoint = length + startpoint;
  865|  10.9k|        if (x <= endpoint) {
  ------------------
  |  Branch (865:13): [True: 2.35k, False: 8.55k]
  ------------------
  866|  2.35k|            if (x < startpoint) break;
  ------------------
  |  Branch (866:17): [True: 259, False: 2.09k]
  ------------------
  867|  2.09k|            return sum + (x32 - startpoint) + 1;
  868|  8.55k|        } else {
  869|  8.55k|            sum += length + 1;
  870|  8.55k|        }
  871|  10.9k|    }
  872|    327|    return sum;
  873|  2.41k|}
_avx2_run_container_to_uint32_array:
  997|  54.1k|                                        uint32_t base) {
  998|  54.1k|    int outpos = 0;
  999|  54.1k|    uint32_t *out = (uint32_t *)vout;
 1000|       |
 1001|   183k|    for (int i = 0; i < cont->n_runs; ++i) {
  ------------------
  |  Branch (1001:21): [True: 129k, False: 54.1k]
  ------------------
 1002|   129k|        uint32_t run_start = base + cont->runs[i].value;
 1003|   129k|        uint16_t le = cont->runs[i].length;
 1004|   129k|        if (le < 8) {
  ------------------
  |  Branch (1004:13): [True: 72.5k, False: 57.3k]
  ------------------
 1005|   187k|            for (int j = 0; j <= le; ++j) {
  ------------------
  |  Branch (1005:29): [True: 115k, False: 72.5k]
  ------------------
 1006|   115k|                uint32_t val = run_start + j;
 1007|   115k|                memcpy(out + outpos, &val,
 1008|   115k|                       sizeof(uint32_t));  // should be compiled as a MOV on x64
 1009|   115k|                outpos++;
 1010|   115k|            }
 1011|  72.5k|        } else {
 1012|  57.3k|            int j = 0;
 1013|  57.3k|            __m256i run_start_v = _mm256_set1_epi32(run_start);
 1014|       |            // [8,8,8,8....]
 1015|  57.3k|            __m256i inc = _mm256_set1_epi32(8);
 1016|       |            // used for generate sequence:
 1017|       |            // [0, 1, 2, 3...], [8, 9, 10,...]
 1018|  57.3k|            __m256i delta = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
 1019|   429M|            for (j = 0; j + 8 <= le; j += 8) {
  ------------------
  |  Branch (1019:25): [True: 429M, False: 57.3k]
  ------------------
 1020|   429M|                __m256i val_v = _mm256_add_epi32(run_start_v, delta);
 1021|   429M|                _mm256_storeu_si256((__m256i *)(out + outpos), val_v);
 1022|   429M|                delta = _mm256_add_epi32(inc, delta);
 1023|   429M|                outpos += 8;
 1024|   429M|            }
 1025|   494k|            for (; j <= le; ++j) {
  ------------------
  |  Branch (1025:20): [True: 436k, False: 57.3k]
  ------------------
 1026|   436k|                uint32_t val = run_start + j;
 1027|   436k|                memcpy(out + outpos, &val,
 1028|   436k|                       sizeof(uint32_t));  // should be compiled as a MOV on x64
 1029|   436k|                outpos++;
 1030|   436k|            }
 1031|  57.3k|        }
 1032|   129k|    }
 1033|  54.1k|    return outpos;
 1034|  54.1k|}
run_container_cardinality:
 1054|   486k|int run_container_cardinality(const run_container_t *run) {
 1055|       |    // Empirically AVX-512 is not always faster than AVX2
 1056|       |#if CROARING_COMPILER_SUPPORTS_AVX512 && \
 1057|       |    CROARING_ENABLE_AVX512_RUN_CONTAINER_CARDINALITY
 1058|       |    if (croaring_hardware_support() & ROARING_SUPPORTS_AVX512) {
 1059|       |        return _avx512_run_container_cardinality(run);
 1060|       |    } else
 1061|       |#endif
 1062|   486k|        if (croaring_hardware_support() & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (1062:13): [True: 486k, False: 0]
  ------------------
 1063|   486k|        return _avx2_run_container_cardinality(run);
 1064|   486k|    } else {
 1065|      0|        return _scalar_run_container_cardinality(run);
 1066|      0|    }
 1067|   486k|}
run_container_to_uint32_array:
 1089|  54.1k|                                  uint32_t base) {
 1090|  54.1k|    if (croaring_hardware_support() & ROARING_SUPPORTS_AVX2) {
  ------------------
  |  Branch (1090:9): [True: 54.1k, False: 0]
  ------------------
 1091|  54.1k|        return _avx2_run_container_to_uint32_array(vout, cont, base);
 1092|  54.1k|    } else {
 1093|      0|        return _scalar_run_container_to_uint32_array(vout, cont, base);
 1094|      0|    }
 1095|  54.1k|}
run.c:_avx2_run_container_cardinality:
  967|   486k|static inline int _avx2_run_container_cardinality(const run_container_t *run) {
  968|   486k|    const int32_t n_runs = run->n_runs;
  969|   486k|    const rle16_t *runs = run->runs;
  970|       |
  971|       |    /* by initializing with n_runs, we omit counting the +1 for each pair. */
  972|   486k|    int sum = n_runs;
  973|   486k|    int32_t k = 0;
  974|   486k|    const int32_t step = sizeof(__m256i) / sizeof(rle16_t);
  975|   486k|    if (n_runs > step) {
  ------------------
  |  Branch (975:9): [True: 31.0k, False: 455k]
  ------------------
  976|  31.0k|        __m256i total = _mm256_setzero_si256();
  977|   335k|        for (; k + step <= n_runs; k += step) {
  ------------------
  |  Branch (977:16): [True: 304k, False: 31.0k]
  ------------------
  978|   304k|            __m256i ymm1 = _mm256_loadu_si256((const __m256i *)(runs + k));
  979|   304k|            __m256i justlengths = _mm256_srli_epi32(ymm1, 16);
  980|   304k|            total = _mm256_add_epi32(total, justlengths);
  981|   304k|        }
  982|       |        // a store might be faster than extract?
  983|  31.0k|        uint32_t buffer[sizeof(__m256i) / sizeof(rle16_t)];
  984|  31.0k|        _mm256_storeu_si256((__m256i *)buffer, total);
  985|  31.0k|        sum += (buffer[0] + buffer[1]) + (buffer[2] + buffer[3]) +
  986|  31.0k|               (buffer[4] + buffer[5]) + (buffer[6] + buffer[7]);
  987|  31.0k|    }
  988|  1.01M|    for (; k < n_runs; ++k) {
  ------------------
  |  Branch (988:12): [True: 531k, False: 486k]
  ------------------
  989|   531k|        sum += runs[k].length;
  990|   531k|    }
  991|       |
  992|   486k|    return sum;
  993|   486k|}

croaring_hardware_support:
  401|   881k|int croaring_hardware_support(void) {
  402|   881k|    static
  403|   881k|#if CROARING_ATOMIC_IMPL == CROARING_ATOMIC_IMPL_C
  404|   881k|        _Atomic
  405|   881k|#endif
  406|   881k|        int support = 0xFFFFFFF;
  407|   881k|    if (support == 0xFFFFFFF) {
  ------------------
  |  Branch (407:9): [True: 1, False: 881k]
  ------------------
  408|      1|        bool has_avx2 = (croaring_detect_supported_architectures() &
  409|      1|                         CROARING_AVX2) == CROARING_AVX2;
  410|      1|        bool has_avx512 = false;
  411|      1|#if CROARING_COMPILER_SUPPORTS_AVX512
  412|      1|        has_avx512 = (croaring_detect_supported_architectures() &
  413|      1|                      CROARING_AVX512_REQUIRED) == CROARING_AVX512_REQUIRED;
  414|      1|#endif  // CROARING_COMPILER_SUPPORTS_AVX512
  415|      1|        support = (has_avx2 ? ROARING_SUPPORTS_AVX2 : 0) |
  ------------------
  |  Branch (415:20): [True: 1, False: 0]
  ------------------
  416|      1|                  (has_avx512 ? ROARING_SUPPORTS_AVX512 : 0);
  ------------------
  |  Branch (416:20): [True: 0, False: 1]
  ------------------
  417|      1|    }
  418|   881k|    return support;
  419|   881k|}
isadetection.c:croaring_detect_supported_architectures:
  345|      2|static uint32_t croaring_detect_supported_architectures(void) {
  346|       |    // we use an atomic for thread safety
  347|      2|    static _Atomic uint32_t buffer = CROARING_UNINITIALIZED;
  348|      2|    if (buffer == CROARING_UNINITIALIZED) {
  ------------------
  |  Branch (348:9): [True: 1, False: 1]
  ------------------
  349|       |        // atomicity is sufficient
  350|      1|        buffer = dynamic_croaring_detect_supported_architectures();
  351|      1|    }
  352|      2|    return buffer;
  353|      2|}
isadetection.c:dynamic_croaring_detect_supported_architectures:
  196|      1|static inline uint32_t dynamic_croaring_detect_supported_architectures(void) {
  197|      1|    uint32_t eax, ebx, ecx, edx;
  198|      1|    uint32_t host_isa = 0x0;
  199|       |    // Can be found on Intel ISA Reference for CPUID
  200|      1|    static uint32_t cpuid_avx2_bit =
  201|      1|        1 << 5;  ///< @private Bit 5 of EBX for EAX=0x7
  202|      1|    static uint32_t cpuid_bmi1_bit =
  203|      1|        1 << 3;  ///< @private bit 3 of EBX for EAX=0x7
  204|      1|    static uint32_t cpuid_bmi2_bit =
  205|      1|        1 << 8;  ///< @private bit 8 of EBX for EAX=0x7
  206|      1|    static uint32_t cpuid_avx512f_bit =
  207|      1|        1 << 16;  ///< @private bit 16 of EBX for EAX=0x7
  208|      1|    static uint32_t cpuid_avx512dq_bit =
  209|      1|        1 << 17;  ///< @private bit 17 of EBX for EAX=0x7
  210|      1|    static uint32_t cpuid_avx512bw_bit =
  211|      1|        1 << 30;  ///< @private bit 30 of EBX for EAX=0x7
  212|      1|    static uint32_t cpuid_avx512vbmi2_bit =
  213|      1|        1 << 6;  ///< @private bit 6 of ECX for EAX=0x7
  214|      1|    static uint32_t cpuid_avx512bitalg_bit =
  215|      1|        1 << 12;  ///< @private bit 12 of ECX for EAX=0x7
  216|      1|    static uint32_t cpuid_avx512vpopcntdq_bit =
  217|      1|        1 << 14;  ///< @private bit 14 of ECX for EAX=0x7
  218|      1|    static uint64_t cpuid_avx256_saved = 1 << 2;  ///< @private bit 2 = AVX
  219|      1|    static uint64_t cpuid_avx512_saved =
  220|      1|        7 << 5;  ///< @private bits 5,6,7 = opmask, ZMM_hi256, hi16_ZMM
  221|      1|    static uint32_t cpuid_sse42_bit =
  222|      1|        1 << 20;  ///< @private bit 20 of ECX for EAX=0x1
  223|      1|    static uint32_t cpuid_osxsave =
  224|      1|        (1 << 26) | (1 << 27);  ///< @private bits 26+27 of ECX for EAX=0x1
  225|      1|    static uint32_t cpuid_pclmulqdq_bit =
  226|      1|        1 << 1;  ///< @private bit  1 of ECX for EAX=0x1
  227|       |
  228|       |    // EBX for EAX=0x1
  229|      1|    eax = 0x1;
  230|      1|    ecx = 0x0;
  231|      1|    cpuid(&eax, &ebx, &ecx, &edx);
  232|       |
  233|      1|    if (ecx & cpuid_sse42_bit) {
  ------------------
  |  Branch (233:9): [True: 1, False: 0]
  ------------------
  234|      1|        host_isa |= CROARING_SSE42;
  235|      1|    } else {
  236|      0|        return host_isa;  // everything after is redundant
  237|      0|    }
  238|       |
  239|      1|    if (ecx & cpuid_pclmulqdq_bit) {
  ------------------
  |  Branch (239:9): [True: 1, False: 0]
  ------------------
  240|      1|        host_isa |= CROARING_PCLMULQDQ;
  241|      1|    }
  242|       |
  243|      1|    if ((ecx & cpuid_osxsave) != cpuid_osxsave) {
  ------------------
  |  Branch (243:9): [True: 0, False: 1]
  ------------------
  244|      0|        return host_isa;
  245|      0|    }
  246|       |
  247|       |    // xgetbv for checking if the OS saves registers
  248|      1|    uint64_t xcr0 = xgetbv();
  249|       |
  250|      1|    if ((xcr0 & cpuid_avx256_saved) == 0) {
  ------------------
  |  Branch (250:9): [True: 0, False: 1]
  ------------------
  251|      0|        return host_isa;
  252|      0|    }
  253|       |
  254|       |    // ECX for EAX=0x7
  255|      1|    eax = 0x7;
  256|      1|    ecx = 0x0;
  257|      1|    cpuid(&eax, &ebx, &ecx, &edx);
  258|      1|    if (ebx & cpuid_avx2_bit) {
  ------------------
  |  Branch (258:9): [True: 1, False: 0]
  ------------------
  259|      1|        host_isa |= CROARING_AVX2;
  260|      1|    }
  261|      1|    if (ebx & cpuid_bmi1_bit) {
  ------------------
  |  Branch (261:9): [True: 1, False: 0]
  ------------------
  262|      1|        host_isa |= CROARING_BMI1;
  263|      1|    }
  264|       |
  265|      1|    if (ebx & cpuid_bmi2_bit) {
  ------------------
  |  Branch (265:9): [True: 1, False: 0]
  ------------------
  266|      1|        host_isa |= CROARING_BMI2;
  267|      1|    }
  268|       |
  269|      1|    if (!((xcr0 & cpuid_avx512_saved) == cpuid_avx512_saved)) {
  ------------------
  |  Branch (269:9): [True: 1, False: 0]
  ------------------
  270|      1|        return host_isa;
  271|      1|    }
  272|       |
  273|      0|    if (ebx & cpuid_avx512f_bit) {
  ------------------
  |  Branch (273:9): [True: 0, False: 0]
  ------------------
  274|      0|        host_isa |= CROARING_AVX512F;
  275|      0|    }
  276|       |
  277|      0|    if (ebx & cpuid_avx512bw_bit) {
  ------------------
  |  Branch (277:9): [True: 0, False: 0]
  ------------------
  278|      0|        host_isa |= CROARING_AVX512BW;
  279|      0|    }
  280|       |
  281|      0|    if (ebx & cpuid_avx512dq_bit) {
  ------------------
  |  Branch (281:9): [True: 0, False: 0]
  ------------------
  282|      0|        host_isa |= CROARING_AVX512DQ;
  283|      0|    }
  284|       |
  285|      0|    if (ecx & cpuid_avx512vbmi2_bit) {
  ------------------
  |  Branch (285:9): [True: 0, False: 0]
  ------------------
  286|      0|        host_isa |= CROARING_AVX512VBMI2;
  287|      0|    }
  288|       |
  289|      0|    if (ecx & cpuid_avx512bitalg_bit) {
  ------------------
  |  Branch (289:9): [True: 0, False: 0]
  ------------------
  290|      0|        host_isa |= CROARING_AVX512BITALG;
  291|      0|    }
  292|       |
  293|      0|    if (ecx & cpuid_avx512vpopcntdq_bit) {
  ------------------
  |  Branch (293:9): [True: 0, False: 0]
  ------------------
  294|      0|        host_isa |= CROARING_AVX512VPOPCNTDQ;
  295|      0|    }
  296|       |
  297|      0|    return host_isa;
  298|      1|}
isadetection.c:cpuid:
  157|      2|                         uint32_t *edx) {
  158|       |#if CROARING_REGULAR_VISUAL_STUDIO
  159|       |    int cpu_info[4];
  160|       |    __cpuidex(cpu_info, *eax, *ecx);
  161|       |    *eax = cpu_info[0];
  162|       |    *ebx = cpu_info[1];
  163|       |    *ecx = cpu_info[2];
  164|       |    *edx = cpu_info[3];
  165|       |#elif (defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID)) || \
  166|       |    defined(__FILC__)
  167|       |    uint32_t level = *eax;
  168|       |    __get_cpuid(level, eax, ebx, ecx, edx);
  169|       |#else
  170|      2|    uint32_t a = *eax, b, c = *ecx, d;
  171|      2|    __asm__("cpuid\n\t" : "+a"(a), "=b"(b), "+c"(c), "=d"(d));
  172|      2|    *eax = a;
  173|      2|    *ebx = b;
  174|      2|    *ecx = c;
  175|      2|    *edx = d;
  176|      2|#endif
  177|      2|}
isadetection.c:xgetbv:
  179|      1|static inline uint64_t xgetbv(void) {
  180|       |#if defined(_MSC_VER)
  181|       |    return _xgetbv(0);
  182|       |#elif defined(__FILC__)
  183|       |    return zxgetbv();
  184|       |#else
  185|      1|    uint32_t xcr0_lo, xcr0_hi;
  186|      1|    __asm__("xgetbv\n\t" : "=a"(xcr0_lo), "=d"(xcr0_hi) : "c"(0));
  187|      1|    return xcr0_lo | ((uint64_t)xcr0_hi << 32);
  188|      1|#endif
  189|      1|}

roaring_malloc:
   48|  1.33M|void* roaring_malloc(size_t n) { return global_memory_hook.malloc(n); }
roaring_realloc:
   50|   124k|void* roaring_realloc(void* p, size_t new_sz) {
   51|   124k|    return global_memory_hook.realloc(p, new_sz);
   52|   124k|}
roaring_free:
   58|  1.57M|void roaring_free(void* p) { global_memory_hook.free(p); }
roaring_aligned_malloc:
   60|   271k|void* roaring_aligned_malloc(size_t alignment, size_t size) {
   61|   271k|    return global_memory_hook.aligned_malloc(alignment, size);
   62|   271k|}
roaring_aligned_free:
   64|   271k|void roaring_aligned_free(void* p) { global_memory_hook.aligned_free(p); }
memory.c:roaring_bitmap_aligned_malloc:
   11|   271k|static void* roaring_bitmap_aligned_malloc(size_t alignment, size_t size) {
   12|   271k|    void* p;
   13|       |#ifdef _MSC_VER
   14|       |    p = _aligned_malloc(size, alignment);
   15|       |#elif defined(__MINGW32__) || defined(__MINGW64__)
   16|       |    p = __mingw_aligned_malloc(size, alignment);
   17|       |#else
   18|       |    // somehow, if this is used before including "x86intrin.h", it creates an
   19|       |    // implicit defined warning.
   20|   271k|    if (posix_memalign(&p, alignment, size) != 0) return NULL;
  ------------------
  |  Branch (20:9): [True: 0, False: 271k]
  ------------------
   21|   271k|#endif
   22|   271k|    return p;
   23|   271k|}
memory.c:roaring_bitmap_aligned_free:
   25|   271k|static void roaring_bitmap_aligned_free(void* memblock) {
   26|       |#ifdef _MSC_VER
   27|       |    _aligned_free(memblock);
   28|       |#elif defined(__MINGW32__) || defined(__MINGW64__)
   29|       |    __mingw_aligned_free(memblock);
   30|       |#else
   31|   271k|    free(memblock);
   32|   271k|#endif
   33|   271k|}

roaring_bitmap_create_with_capacity:
   86|  28.6k|roaring_bitmap_t *roaring_bitmap_create_with_capacity(uint32_t cap) {
   87|  28.6k|    roaring_bitmap_t *ans =
   88|  28.6k|        (roaring_bitmap_t *)roaring_malloc(sizeof(roaring_bitmap_t));
   89|  28.6k|    if (!ans) {
  ------------------
  |  Branch (89:9): [True: 0, False: 28.6k]
  ------------------
   90|      0|        return NULL;
   91|      0|    }
   92|  28.6k|    bool is_ok = ra_init_with_capacity(&ans->high_low_container, cap);
   93|  28.6k|    if (!is_ok) {
  ------------------
  |  Branch (93:9): [True: 0, False: 28.6k]
  ------------------
   94|      0|        roaring_free(ans);
   95|      0|        return NULL;
   96|      0|    }
   97|  28.6k|    return ans;
   98|  28.6k|}
roaring_bitmap_init_with_capacity:
  100|  35.9k|bool roaring_bitmap_init_with_capacity(roaring_bitmap_t *r, uint32_t cap) {
  101|  35.9k|    return ra_init_with_capacity(&r->high_low_container, cap);
  102|  35.9k|}
roaring_bitmap_add_many:
  135|  21.5k|                             const uint32_t *vals) {
  136|  21.5k|    uint32_t val;
  137|  21.5k|    const uint32_t *start = vals;
  138|  21.5k|    const uint32_t *end = vals + n_args;
  139|  21.5k|    const uint32_t *current_val = start;
  140|       |
  141|  21.5k|    if (n_args == 0) {
  ------------------
  |  Branch (141:9): [True: 0, False: 21.5k]
  ------------------
  142|      0|        return;
  143|      0|    }
  144|       |
  145|  21.5k|    uint8_t typecode;
  146|  21.5k|    int idx;
  147|  21.5k|    container_t *container;
  148|  21.5k|    val = *current_val;
  149|  21.5k|    container = containerptr_roaring_bitmap_add(r, val, &typecode, &idx);
  150|  21.5k|    roaring_bulk_context_t context = {container, idx, (uint16_t)(val >> 16),
  151|  21.5k|                                      typecode};
  152|       |
  153|  9.00M|    for (; current_val != end; current_val++) {
  ------------------
  |  Branch (153:12): [True: 8.98M, False: 21.5k]
  ------------------
  154|  8.98M|        memcpy(&val, current_val, sizeof(val));
  155|  8.98M|        add_bulk_impl(r, &context, val);
  156|  8.98M|    }
  157|  21.5k|}
roaring_bitmap_add_range_closed:
  252|  2.69k|                                     uint32_t max) {
  253|  2.69k|    if (min > max) {
  ------------------
  |  Branch (253:9): [True: 0, False: 2.69k]
  ------------------
  254|      0|        return;
  255|      0|    }
  256|       |
  257|  2.69k|    roaring_array_t *ra = &r->high_low_container;
  258|       |
  259|  2.69k|    uint32_t min_key = min >> 16;
  260|  2.69k|    uint32_t max_key = max >> 16;
  261|       |
  262|  2.69k|    int32_t num_required_containers = max_key - min_key + 1;
  263|  2.69k|    int32_t suffix_length =
  264|  2.69k|        count_greater(ra->keys, ra->size, (uint16_t)max_key);
  265|  2.69k|    int32_t prefix_length =
  266|  2.69k|        count_less(ra->keys, ra->size - suffix_length, (uint16_t)min_key);
  267|  2.69k|    int32_t common_length = ra->size - prefix_length - suffix_length;
  268|       |
  269|  2.69k|    if (num_required_containers > common_length) {
  ------------------
  |  Branch (269:9): [True: 1.23k, False: 1.46k]
  ------------------
  270|  1.23k|        ra_shift_tail(ra, suffix_length,
  271|  1.23k|                      num_required_containers - common_length);
  272|  1.23k|    }
  273|       |
  274|  2.69k|    int32_t src = prefix_length + common_length - 1;
  275|  2.69k|    int32_t dst = ra->size - suffix_length - 1;
  276|  71.3k|    for (uint32_t key = max_key; key != min_key - 1;
  ------------------
  |  Branch (276:34): [True: 68.6k, False: 2.69k]
  ------------------
  277|  68.6k|         key--) {  // beware of min_key==0
  278|  68.6k|        uint32_t container_min = (min_key == key) ? (min & 0xffff) : 0;
  ------------------
  |  Branch (278:34): [True: 2.69k, False: 65.9k]
  ------------------
  279|  68.6k|        uint32_t container_max = (max_key == key) ? (max & 0xffff) : 0xffff;
  ------------------
  |  Branch (279:34): [True: 2.69k, False: 65.9k]
  ------------------
  280|  68.6k|        container_t *new_container;
  281|  68.6k|        uint8_t new_type;
  282|       |
  283|  68.6k|        if (src >= 0 && ra->keys[src] == key) {
  ------------------
  |  Branch (283:13): [True: 68.6k, False: 0]
  |  Branch (283:25): [True: 3.08k, False: 65.5k]
  ------------------
  284|  3.08k|            ra_unshare_container_at_index(ra, (uint16_t)src);
  285|  3.08k|            new_container =
  286|  3.08k|                container_add_range(ra->containers[src], ra->typecodes[src],
  287|  3.08k|                                    container_min, container_max, &new_type);
  288|  3.08k|            if (new_container != ra->containers[src]) {
  ------------------
  |  Branch (288:17): [True: 2.03k, False: 1.05k]
  ------------------
  289|  2.03k|                container_free(ra->containers[src], ra->typecodes[src]);
  290|  2.03k|            }
  291|  3.08k|            src--;
  292|  65.5k|        } else {
  293|  65.5k|            new_container = container_from_range(&new_type, container_min,
  294|  65.5k|                                                 container_max + 1, 1);
  295|  65.5k|        }
  296|  68.6k|        ra_replace_key_and_container_at_index(ra, dst, (uint16_t)key,
  297|  68.6k|                                              new_container, new_type);
  298|  68.6k|        dst--;
  299|  68.6k|    }
  300|  2.69k|}
roaring_bitmap_remove_range_closed:
  303|  8.09k|                                        uint32_t max) {
  304|  8.09k|    if (min > max) {
  ------------------
  |  Branch (304:9): [True: 733, False: 7.36k]
  ------------------
  305|    733|        return;
  306|    733|    }
  307|       |
  308|  7.36k|    roaring_array_t *ra = &r->high_low_container;
  309|       |
  310|  7.36k|    uint32_t min_key = min >> 16;
  311|  7.36k|    uint32_t max_key = max >> 16;
  312|       |
  313|  7.36k|    int32_t src = count_less(ra->keys, ra->size, (uint16_t)min_key);
  314|  7.36k|    int32_t dst = src;
  315|  28.1k|    while (src < ra->size && ra->keys[src] <= max_key) {
  ------------------
  |  Branch (315:12): [True: 22.8k, False: 5.32k]
  |  Branch (315:30): [True: 20.7k, False: 2.04k]
  ------------------
  316|  20.7k|        uint32_t container_min =
  317|  20.7k|            (min_key == ra->keys[src]) ? (min & 0xffff) : 0;
  ------------------
  |  Branch (317:13): [True: 7.00k, False: 13.7k]
  ------------------
  318|  20.7k|        uint32_t container_max =
  319|  20.7k|            (max_key == ra->keys[src]) ? (max & 0xffff) : 0xffff;
  ------------------
  |  Branch (319:13): [True: 6.62k, False: 14.1k]
  ------------------
  320|  20.7k|        ra_unshare_container_at_index(ra, (uint16_t)src);
  321|  20.7k|        container_t *new_container;
  322|  20.7k|        uint8_t new_type;
  323|  20.7k|        new_container =
  324|  20.7k|            container_remove_range(ra->containers[src], ra->typecodes[src],
  325|  20.7k|                                   container_min, container_max, &new_type);
  326|  20.7k|        if (new_container != ra->containers[src]) {
  ------------------
  |  Branch (326:13): [True: 13.8k, False: 6.88k]
  ------------------
  327|  13.8k|            container_free(ra->containers[src], ra->typecodes[src]);
  328|  13.8k|        }
  329|  20.7k|        if (new_container) {
  ------------------
  |  Branch (329:13): [True: 7.19k, False: 13.5k]
  ------------------
  330|  7.19k|            ra_replace_key_and_container_at_index(ra, dst, ra->keys[src],
  331|  7.19k|                                                  new_container, new_type);
  332|  7.19k|            dst++;
  333|  7.19k|        }
  334|  20.7k|        src++;
  335|  20.7k|    }
  336|  7.36k|    if (src > dst) {
  ------------------
  |  Branch (336:9): [True: 643, False: 6.71k]
  ------------------
  337|    643|        ra_shift_tail(ra, ra->size - src, dst - src);
  338|    643|    }
  339|  7.36k|}
roaring_bitmap_copy:
  525|    123|roaring_bitmap_t *roaring_bitmap_copy(const roaring_bitmap_t *r) {
  526|    123|    roaring_bitmap_t *ans =
  527|    123|        (roaring_bitmap_t *)roaring_malloc(sizeof(roaring_bitmap_t));
  528|    123|    if (!ans) {
  ------------------
  |  Branch (528:9): [True: 0, False: 123]
  ------------------
  529|      0|        return NULL;
  530|      0|    }
  531|    123|    if (!ra_init_with_capacity(  // allocation of list of containers can fail
  ------------------
  |  Branch (531:9): [True: 0, False: 123]
  ------------------
  532|    123|            &ans->high_low_container, r->high_low_container.size)) {
  533|      0|        roaring_free(ans);
  534|      0|        return NULL;
  535|      0|    }
  536|    123|    if (!ra_overwrite(  // memory allocation of individual containers may fail
  ------------------
  |  Branch (536:9): [True: 0, False: 123]
  ------------------
  537|    123|            &r->high_low_container, &ans->high_low_container, is_cow(r))) {
  538|      0|        roaring_bitmap_free(ans);  // overwrite should leave in freeable state
  539|      0|        return NULL;
  540|      0|    }
  541|    123|    roaring_bitmap_set_copy_on_write(ans, is_cow(r));
  542|    123|    return ans;
  543|    123|}
roaring_bitmap_overwrite:
  546|  16.3k|                              const roaring_bitmap_t *src) {
  547|  16.3k|    roaring_bitmap_set_copy_on_write(dest, is_cow(src));
  548|  16.3k|    return ra_overwrite(&src->high_low_container, &dest->high_low_container,
  549|  16.3k|                        is_cow(src));
  550|  16.3k|}
roaring_bitmap_clear:
  562|  71.8k|void roaring_bitmap_clear(roaring_bitmap_t *r) {
  563|  71.8k|    ra_reset(&r->high_low_container);
  564|  71.8k|}
roaring_bitmap_add:
  566|  7.18k|void roaring_bitmap_add(roaring_bitmap_t *r, uint32_t val) {
  567|  7.18k|    roaring_array_t *ra = &r->high_low_container;
  568|       |
  569|  7.18k|    const uint16_t hb = val >> 16;
  570|  7.18k|    const int i = ra_get_index(ra, hb);
  571|  7.18k|    uint8_t typecode;
  572|  7.18k|    if (i >= 0) {
  ------------------
  |  Branch (572:9): [True: 5.59k, False: 1.59k]
  ------------------
  573|  5.59k|        ra_unshare_container_at_index(ra, (uint16_t)i);
  574|  5.59k|        container_t *container =
  575|  5.59k|            ra_get_container_at_index(ra, (uint16_t)i, &typecode);
  576|  5.59k|        uint8_t newtypecode = typecode;
  577|  5.59k|        container_t *container2 =
  578|  5.59k|            container_add(container, val & 0xFFFF, typecode, &newtypecode);
  579|  5.59k|        if (container2 != container) {
  ------------------
  |  Branch (579:13): [True: 0, False: 5.59k]
  ------------------
  580|      0|            container_free(container, typecode);
  581|      0|            ra_set_container_at_index(&r->high_low_container, i, container2,
  582|      0|                                      newtypecode);
  583|      0|        }
  584|  5.59k|    } else {
  585|  1.59k|        array_container_t *newac = array_container_create();
  586|  1.59k|        container_t *container =
  587|  1.59k|            container_add(newac, val & 0xFFFF, ARRAY_CONTAINER_TYPE, &typecode);
  ------------------
  |  |   49|  1.59k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  588|       |        // we could just assume that it stays an array container
  589|  1.59k|        ra_insert_new_key_value_at(&r->high_low_container, -i - 1, hb,
  590|  1.59k|                                   container, typecode);
  591|  1.59k|    }
  592|  7.18k|}
roaring_bitmap_add_checked:
  594|  7.18k|bool roaring_bitmap_add_checked(roaring_bitmap_t *r, uint32_t val) {
  595|  7.18k|    const uint16_t hb = val >> 16;
  596|  7.18k|    const int i = ra_get_index(&r->high_low_container, hb);
  597|  7.18k|    uint8_t typecode;
  598|  7.18k|    bool result = false;
  599|  7.18k|    if (i >= 0) {
  ------------------
  |  Branch (599:9): [True: 5.75k, False: 1.43k]
  ------------------
  600|  5.75k|        ra_unshare_container_at_index(&r->high_low_container, (uint16_t)i);
  601|  5.75k|        container_t *container = ra_get_container_at_index(
  602|  5.75k|            &r->high_low_container, (uint16_t)i, &typecode);
  603|       |
  604|  5.75k|        const int oldCardinality =
  605|  5.75k|            container_get_cardinality(container, typecode);
  606|       |
  607|  5.75k|        uint8_t newtypecode = typecode;
  608|  5.75k|        container_t *container2 =
  609|  5.75k|            container_add(container, val & 0xFFFF, typecode, &newtypecode);
  610|  5.75k|        if (container2 != container) {
  ------------------
  |  Branch (610:13): [True: 0, False: 5.75k]
  ------------------
  611|      0|            container_free(container, typecode);
  612|      0|            ra_set_container_at_index(&r->high_low_container, i, container2,
  613|      0|                                      newtypecode);
  614|      0|            result = true;
  615|  5.75k|        } else {
  616|  5.75k|            const int newCardinality =
  617|  5.75k|                container_get_cardinality(container, newtypecode);
  618|       |
  619|  5.75k|            result = oldCardinality != newCardinality;
  620|  5.75k|        }
  621|  5.75k|    } else {
  622|  1.43k|        array_container_t *newac = array_container_create();
  623|  1.43k|        container_t *container =
  624|  1.43k|            container_add(newac, val & 0xFFFF, ARRAY_CONTAINER_TYPE, &typecode);
  ------------------
  |  |   49|  1.43k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  625|       |        // we could just assume that it stays an array container
  626|  1.43k|        ra_insert_new_key_value_at(&r->high_low_container, -i - 1, hb,
  627|  1.43k|                                   container, typecode);
  628|  1.43k|        result = true;
  629|  1.43k|    }
  630|       |
  631|  7.18k|    return result;
  632|  7.18k|}
roaring_bitmap_remove:
  634|  7.18k|void roaring_bitmap_remove(roaring_bitmap_t *r, uint32_t val) {
  635|  7.18k|    const uint16_t hb = val >> 16;
  636|  7.18k|    const int i = ra_get_index(&r->high_low_container, hb);
  637|  7.18k|    uint8_t typecode;
  638|  7.18k|    if (i >= 0) {
  ------------------
  |  Branch (638:9): [True: 6.58k, False: 605]
  ------------------
  639|  6.58k|        ra_unshare_container_at_index(&r->high_low_container, (uint16_t)i);
  640|  6.58k|        container_t *container = ra_get_container_at_index(
  641|  6.58k|            &r->high_low_container, (uint16_t)i, &typecode);
  642|  6.58k|        uint8_t newtypecode = typecode;
  643|  6.58k|        container_t *container2 =
  644|  6.58k|            container_remove(container, val & 0xFFFF, typecode, &newtypecode);
  645|  6.58k|        if (container2 != container) {
  ------------------
  |  Branch (645:13): [True: 10, False: 6.57k]
  ------------------
  646|     10|            container_free(container, typecode);
  647|     10|            ra_set_container_at_index(&r->high_low_container, i, container2,
  648|     10|                                      newtypecode);
  649|     10|        }
  650|  6.58k|        if (container_nonzero_cardinality(container2, newtypecode)) {
  ------------------
  |  Branch (650:13): [True: 6.53k, False: 47]
  ------------------
  651|  6.53k|            ra_set_container_at_index(&r->high_low_container, i, container2,
  652|  6.53k|                                      newtypecode);
  653|  6.53k|        } else {
  654|     47|            ra_remove_at_index_and_free(&r->high_low_container, i);
  655|     47|        }
  656|  6.58k|    }
  657|  7.18k|}
roaring_bitmap_remove_checked:
  659|  7.18k|bool roaring_bitmap_remove_checked(roaring_bitmap_t *r, uint32_t val) {
  660|  7.18k|    const uint16_t hb = val >> 16;
  661|  7.18k|    const int i = ra_get_index(&r->high_low_container, hb);
  662|  7.18k|    uint8_t typecode;
  663|  7.18k|    bool result = false;
  664|  7.18k|    if (i >= 0) {
  ------------------
  |  Branch (664:9): [True: 6.60k, False: 587]
  ------------------
  665|  6.60k|        ra_unshare_container_at_index(&r->high_low_container, (uint16_t)i);
  666|  6.60k|        container_t *container = ra_get_container_at_index(
  667|  6.60k|            &r->high_low_container, (uint16_t)i, &typecode);
  668|       |
  669|  6.60k|        const int oldCardinality =
  670|  6.60k|            container_get_cardinality(container, typecode);
  671|       |
  672|  6.60k|        uint8_t newtypecode = typecode;
  673|  6.60k|        container_t *container2 =
  674|  6.60k|            container_remove(container, val & 0xFFFF, typecode, &newtypecode);
  675|  6.60k|        if (container2 != container) {
  ------------------
  |  Branch (675:13): [True: 9, False: 6.59k]
  ------------------
  676|      9|            container_free(container, typecode);
  677|      9|            ra_set_container_at_index(&r->high_low_container, i, container2,
  678|      9|                                      newtypecode);
  679|      9|        }
  680|       |
  681|  6.60k|        const int newCardinality =
  682|  6.60k|            container_get_cardinality(container2, newtypecode);
  683|       |
  684|  6.60k|        if (newCardinality != 0) {
  ------------------
  |  Branch (684:13): [True: 6.58k, False: 13]
  ------------------
  685|  6.58k|            ra_set_container_at_index(&r->high_low_container, i, container2,
  686|  6.58k|                                      newtypecode);
  687|  6.58k|        } else {
  688|     13|            ra_remove_at_index_and_free(&r->high_low_container, i);
  689|     13|        }
  690|       |
  691|  6.60k|        result = oldCardinality != newCardinality;
  692|  6.60k|    }
  693|  7.18k|    return result;
  694|  7.18k|}
roaring_bitmap_and:
  736|  7.18k|                                     const roaring_bitmap_t *x2) {
  737|  7.18k|    uint8_t result_type = 0;
  738|  7.18k|    const int length1 = x1->high_low_container.size,
  739|  7.18k|              length2 = x2->high_low_container.size;
  740|  7.18k|    uint32_t neededcap = length1 > length2 ? length2 : length1;
  ------------------
  |  Branch (740:26): [True: 41, False: 7.14k]
  ------------------
  741|  7.18k|    roaring_bitmap_t *answer = roaring_bitmap_create_with_capacity(neededcap);
  742|  7.18k|    roaring_bitmap_set_copy_on_write(answer, is_cow(x1) || is_cow(x2));
  ------------------
  |  Branch (742:46): [True: 0, False: 7.18k]
  |  Branch (742:60): [True: 0, False: 7.18k]
  ------------------
  743|       |
  744|  7.18k|    int pos1 = 0, pos2 = 0;
  745|       |
  746|  14.3k|    while (pos1 < length1 && pos2 < length2) {
  ------------------
  |  Branch (746:12): [True: 7.18k, False: 7.14k]
  |  Branch (746:30): [True: 7.14k, False: 41]
  ------------------
  747|  7.14k|        const uint16_t s1 =
  748|  7.14k|            ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
  749|  7.14k|        const uint16_t s2 =
  750|  7.14k|            ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
  751|       |
  752|  7.14k|        if (s1 == s2) {
  ------------------
  |  Branch (752:13): [True: 7.08k, False: 57]
  ------------------
  753|  7.08k|            uint8_t type1, type2;
  754|  7.08k|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
  755|  7.08k|                                                        (uint16_t)pos1, &type1);
  756|  7.08k|            container_t *c2 = ra_get_container_at_index(&x2->high_low_container,
  757|  7.08k|                                                        (uint16_t)pos2, &type2);
  758|  7.08k|            container_t *c = container_and(c1, type1, c2, type2, &result_type);
  759|       |
  760|  7.08k|            if (container_nonzero_cardinality(c, result_type)) {
  ------------------
  |  Branch (760:17): [True: 6.79k, False: 295]
  ------------------
  761|  6.79k|                ra_append(&answer->high_low_container, s1, c, result_type);
  762|  6.79k|            } else {
  763|    295|                container_free(c, result_type);  // otherwise: memory leak!
  764|    295|            }
  765|  7.08k|            ++pos1;
  766|  7.08k|            ++pos2;
  767|  7.08k|        } else if (s1 < s2) {  // s1 < s2
  ------------------
  |  Branch (767:20): [True: 57, False: 0]
  ------------------
  768|     57|            pos1 = ra_advance_until(&x1->high_low_container, s2, pos1);
  769|     57|        } else {  // s1 > s2
  770|      0|            pos2 = ra_advance_until(&x2->high_low_container, s1, pos2);
  771|      0|        }
  772|  7.14k|    }
  773|  7.18k|    return answer;
  774|  7.18k|}
roaring_bitmap_and_inplace:
  818|  7.18k|                                const roaring_bitmap_t *x2) {
  819|  7.18k|    if (x1 == x2) return;
  ------------------
  |  Branch (819:9): [True: 0, False: 7.18k]
  ------------------
  820|  7.18k|    int pos1 = 0, pos2 = 0, intersection_size = 0;
  821|  7.18k|    const int length1 = ra_get_size(&x1->high_low_container);
  822|  7.18k|    const int length2 = ra_get_size(&x2->high_low_container);
  823|       |
  824|       |    // any skipped-over or newly emptied containers in x1
  825|       |    // have to be freed.
  826|  69.3k|    while (pos1 < length1 && pos2 < length2) {
  ------------------
  |  Branch (826:12): [True: 62.2k, False: 7.14k]
  |  Branch (826:30): [True: 62.1k, False: 41]
  ------------------
  827|  62.1k|        const uint16_t s1 =
  828|  62.1k|            ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
  829|  62.1k|        const uint16_t s2 =
  830|  62.1k|            ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
  831|       |
  832|  62.1k|        if (s1 == s2) {
  ------------------
  |  Branch (832:13): [True: 62.1k, False: 57]
  ------------------
  833|  62.1k|            uint8_t type1, type2, result_type;
  834|  62.1k|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
  835|  62.1k|                                                        (uint16_t)pos1, &type1);
  836|  62.1k|            container_t *c2 = ra_get_container_at_index(&x2->high_low_container,
  837|  62.1k|                                                        (uint16_t)pos2, &type2);
  838|       |
  839|       |            // We do the computation "in place" only when c1 is not a shared
  840|       |            // container. Rationale: using a shared container safely with in
  841|       |            // place computation would require making a copy and then doing the
  842|       |            // computation in place which is likely less efficient than avoiding
  843|       |            // in place entirely and always generating a new container.
  844|  62.1k|            container_t *c =
  845|  62.1k|                (type1 == SHARED_CONTAINER_TYPE)
  ------------------
  |  |   51|  62.1k|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (845:17): [True: 0, False: 62.1k]
  ------------------
  846|  62.1k|                    ? container_and(c1, type1, c2, type2, &result_type)
  847|  62.1k|                    : container_iand(c1, type1, c2, type2, &result_type);
  848|       |
  849|  62.1k|            if (c != c1) {  // in this instance a new container was created, and
  ------------------
  |  Branch (849:17): [True: 55.0k, False: 7.08k]
  ------------------
  850|       |                            // we need to free the old one
  851|  55.0k|                container_free(c1, type1);
  852|  55.0k|            }
  853|  62.1k|            if (container_nonzero_cardinality(c, result_type)) {
  ------------------
  |  Branch (853:17): [True: 62.1k, False: 0]
  ------------------
  854|  62.1k|                ra_replace_key_and_container_at_index(&x1->high_low_container,
  855|  62.1k|                                                      intersection_size, s1, c,
  856|  62.1k|                                                      result_type);
  857|  62.1k|                intersection_size++;
  858|  62.1k|            } else {
  859|      0|                container_free(c, result_type);
  860|      0|            }
  861|  62.1k|            ++pos1;
  862|  62.1k|            ++pos2;
  863|  62.1k|        } else if (s1 < s2) {
  ------------------
  |  Branch (863:20): [True: 57, False: 0]
  ------------------
  864|     57|            pos1 = ra_advance_until_freeing(&x1->high_low_container, s2, pos1);
  865|     57|        } else {  // s1 > s2
  866|      0|            pos2 = ra_advance_until(&x2->high_low_container, s1, pos2);
  867|      0|        }
  868|  62.1k|    }
  869|       |
  870|       |    // if we ended early because x2 ran out, then all remaining in x1 should be
  871|       |    // freed
  872|  7.22k|    while (pos1 < length1) {
  ------------------
  |  Branch (872:12): [True: 41, False: 7.18k]
  ------------------
  873|     41|        container_free(x1->high_low_container.containers[pos1],
  874|     41|                       x1->high_low_container.typecodes[pos1]);
  875|     41|        ++pos1;
  876|     41|    }
  877|       |
  878|       |    // all containers after this have either been copied or freed
  879|  7.18k|    ra_downsize(&x1->high_low_container, intersection_size);
  880|  7.18k|}
roaring_bitmap_or:
  883|  7.18k|                                    const roaring_bitmap_t *x2) {
  884|  7.18k|    uint8_t result_type = 0;
  885|  7.18k|    const int length1 = x1->high_low_container.size,
  886|  7.18k|              length2 = x2->high_low_container.size;
  887|  7.18k|    if (0 == length1) {
  ------------------
  |  Branch (887:9): [True: 0, False: 7.18k]
  ------------------
  888|      0|        return roaring_bitmap_copy(x2);
  889|      0|    }
  890|  7.18k|    if (0 == length2) {
  ------------------
  |  Branch (890:9): [True: 41, False: 7.14k]
  ------------------
  891|     41|        return roaring_bitmap_copy(x1);
  892|     41|    }
  893|  7.14k|    roaring_bitmap_t *answer =
  894|  7.14k|        roaring_bitmap_create_with_capacity(length1 + length2);
  895|  7.14k|    roaring_bitmap_set_copy_on_write(answer, is_cow(x1) || is_cow(x2));
  ------------------
  |  Branch (895:46): [True: 0, False: 7.14k]
  |  Branch (895:60): [True: 0, False: 7.14k]
  ------------------
  896|  7.14k|    int pos1 = 0, pos2 = 0;
  897|  7.14k|    uint8_t type1, type2;
  898|  7.14k|    uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
  899|  7.14k|    uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
  900|  7.14k|    while (true) {
  ------------------
  |  Branch (900:12): [True: 7.14k, Folded]
  ------------------
  901|  7.14k|        if (s1 == s2) {
  ------------------
  |  Branch (901:13): [True: 7.08k, False: 57]
  ------------------
  902|  7.08k|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
  903|  7.08k|                                                        (uint16_t)pos1, &type1);
  904|  7.08k|            container_t *c2 = ra_get_container_at_index(&x2->high_low_container,
  905|  7.08k|                                                        (uint16_t)pos2, &type2);
  906|  7.08k|            container_t *c = container_or(c1, type1, c2, type2, &result_type);
  907|       |
  908|       |            // since we assume that the initial containers are non-empty, the
  909|       |            // result here
  910|       |            // can only be non-empty
  911|  7.08k|            ra_append(&answer->high_low_container, s1, c, result_type);
  912|  7.08k|            ++pos1;
  913|  7.08k|            ++pos2;
  914|  7.08k|            if (pos1 == length1) break;
  ------------------
  |  Branch (914:17): [True: 7.08k, False: 0]
  ------------------
  915|      0|            if (pos2 == length2) break;
  ------------------
  |  Branch (915:17): [True: 0, False: 0]
  ------------------
  916|      0|            s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
  917|      0|            s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
  918|       |
  919|     57|        } else if (s1 < s2) {  // s1 < s2
  ------------------
  |  Branch (919:20): [True: 57, False: 0]
  ------------------
  920|     57|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
  921|     57|                                                        (uint16_t)pos1, &type1);
  922|       |            // c1 = container_clone(c1, type1);
  923|     57|            c1 = get_copy_of_container(c1, &type1, is_cow(x1));
  924|     57|            if (is_cow(x1)) {
  ------------------
  |  Branch (924:17): [True: 0, False: 57]
  ------------------
  925|      0|                ra_set_container_at_index(&x1->high_low_container, pos1, c1,
  926|      0|                                          type1);
  927|      0|            }
  928|     57|            ra_append(&answer->high_low_container, s1, c1, type1);
  929|     57|            pos1++;
  930|     57|            if (pos1 == length1) break;
  ------------------
  |  Branch (930:17): [True: 57, False: 0]
  ------------------
  931|      0|            s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
  932|       |
  933|      0|        } else {  // s1 > s2
  934|      0|            container_t *c2 = ra_get_container_at_index(&x2->high_low_container,
  935|      0|                                                        (uint16_t)pos2, &type2);
  936|       |            // c2 = container_clone(c2, type2);
  937|      0|            c2 = get_copy_of_container(c2, &type2, is_cow(x2));
  938|      0|            if (is_cow(x2)) {
  ------------------
  |  Branch (938:17): [True: 0, False: 0]
  ------------------
  939|      0|                ra_set_container_at_index(&x2->high_low_container, pos2, c2,
  940|      0|                                          type2);
  941|      0|            }
  942|      0|            ra_append(&answer->high_low_container, s2, c2, type2);
  943|      0|            pos2++;
  944|      0|            if (pos2 == length2) break;
  ------------------
  |  Branch (944:17): [True: 0, False: 0]
  ------------------
  945|      0|            s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
  946|      0|        }
  947|  7.14k|    }
  948|  7.14k|    if (pos1 == length1) {
  ------------------
  |  Branch (948:9): [True: 7.14k, False: 0]
  ------------------
  949|  7.14k|        ra_append_copy_range(&answer->high_low_container,
  950|  7.14k|                             &x2->high_low_container, pos2, length2,
  951|  7.14k|                             is_cow(x2));
  952|  7.14k|    } else if (pos2 == length2) {
  ------------------
  |  Branch (952:16): [True: 0, False: 0]
  ------------------
  953|      0|        ra_append_copy_range(&answer->high_low_container,
  954|      0|                             &x1->high_low_container, pos1, length1,
  955|      0|                             is_cow(x1));
  956|      0|    }
  957|  7.14k|    return answer;
  958|  7.18k|}
roaring_bitmap_or_inplace:
 1139|  7.18k|                               const roaring_bitmap_t *x2) {
 1140|  7.18k|    uint8_t result_type = 0;
 1141|  7.18k|    int length1 = x1->high_low_container.size;
 1142|  7.18k|    const int length2 = x2->high_low_container.size;
 1143|       |
 1144|  7.18k|    if (0 == length2) return;
  ------------------
  |  Branch (1144:9): [True: 0, False: 7.18k]
  ------------------
 1145|       |
 1146|  7.18k|    if (0 == length1) {
  ------------------
  |  Branch (1146:9): [True: 0, False: 7.18k]
  ------------------
 1147|      0|        roaring_bitmap_overwrite(x1, x2);
 1148|      0|        return;
 1149|      0|    }
 1150|       |    // Merging would visit all the containers of x1.
 1151|  7.18k|    if ((int64_t)length2 * 32 < length1) {
  ------------------
  |  Branch (1151:9): [True: 0, False: 7.18k]
  ------------------
 1152|      0|        roaring_inplace_union_few(x1, x2);
 1153|      0|        return;
 1154|      0|    }
 1155|  7.18k|    int pos1 = 0, pos2 = 0;
 1156|  7.18k|    uint8_t type1, type2;
 1157|  7.18k|    uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1158|  7.18k|    uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 1159|  7.18k|    while (true) {
  ------------------
  |  Branch (1159:12): [True: 7.18k, Folded]
  ------------------
 1160|  7.18k|        if (s1 == s2) {
  ------------------
  |  Branch (1160:13): [True: 7.18k, False: 0]
  ------------------
 1161|  7.18k|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
 1162|  7.18k|                                                        (uint16_t)pos1, &type1);
 1163|  7.18k|            if (!container_is_full(c1, type1)) {
  ------------------
  |  Branch (1163:17): [True: 7.18k, False: 0]
  ------------------
 1164|  7.18k|                container_t *c2 = ra_get_container_at_index(
 1165|  7.18k|                    &x2->high_low_container, (uint16_t)pos2, &type2);
 1166|  7.18k|                container_t *c =
 1167|  7.18k|                    (type1 == SHARED_CONTAINER_TYPE)
  ------------------
  |  |   51|  7.18k|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (1167:21): [True: 0, False: 7.18k]
  ------------------
 1168|  7.18k|                        ? container_or(c1, type1, c2, type2, &result_type)
 1169|  7.18k|                        : container_ior(c1, type1, c2, type2, &result_type);
 1170|       |
 1171|  7.18k|                if (c != c1) {  // in this instance a new container was created,
  ------------------
  |  Branch (1171:21): [True: 5.54k, False: 1.64k]
  ------------------
 1172|       |                                // and we need to free the old one
 1173|  5.54k|                    container_free(c1, type1);
 1174|  5.54k|                }
 1175|  7.18k|                ra_set_container_at_index(&x1->high_low_container, pos1, c,
 1176|  7.18k|                                          result_type);
 1177|  7.18k|            }
 1178|  7.18k|            ++pos1;
 1179|  7.18k|            ++pos2;
 1180|  7.18k|            if (pos1 == length1) break;
  ------------------
  |  Branch (1180:17): [True: 7.18k, False: 0]
  ------------------
 1181|      0|            if (pos2 == length2) break;
  ------------------
  |  Branch (1181:17): [True: 0, False: 0]
  ------------------
 1182|      0|            s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1183|      0|            s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 1184|       |
 1185|      0|        } else if (s1 < s2) {  // s1 < s2
  ------------------
  |  Branch (1185:20): [True: 0, False: 0]
  ------------------
 1186|      0|            pos1++;
 1187|      0|            if (pos1 == length1) break;
  ------------------
  |  Branch (1187:17): [True: 0, False: 0]
  ------------------
 1188|      0|            s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1189|       |
 1190|      0|        } else {  // s1 > s2
 1191|      0|            roaring_inplace_merge_bulk(x1, x2, pos1, pos1, pos2, false);
 1192|      0|            return;
 1193|      0|        }
 1194|  7.18k|    }
 1195|  7.18k|    if (pos1 == length1) {
  ------------------
  |  Branch (1195:9): [True: 7.18k, False: 0]
  ------------------
 1196|  7.18k|        ra_append_copy_range(&x1->high_low_container, &x2->high_low_container,
 1197|  7.18k|                             pos2, length2, is_cow(x2));
 1198|  7.18k|    }
 1199|  7.18k|}
roaring_bitmap_xor:
 1202|  7.18k|                                     const roaring_bitmap_t *x2) {
 1203|  7.18k|    uint8_t result_type = 0;
 1204|  7.18k|    const int length1 = x1->high_low_container.size,
 1205|  7.18k|              length2 = x2->high_low_container.size;
 1206|  7.18k|    if (0 == length1) {
  ------------------
  |  Branch (1206:9): [True: 0, False: 7.18k]
  ------------------
 1207|      0|        return roaring_bitmap_copy(x2);
 1208|      0|    }
 1209|  7.18k|    if (0 == length2) {
  ------------------
  |  Branch (1209:9): [True: 41, False: 7.14k]
  ------------------
 1210|     41|        return roaring_bitmap_copy(x1);
 1211|     41|    }
 1212|  7.14k|    roaring_bitmap_t *answer =
 1213|  7.14k|        roaring_bitmap_create_with_capacity(length1 + length2);
 1214|  7.14k|    roaring_bitmap_set_copy_on_write(answer, is_cow(x1) || is_cow(x2));
  ------------------
  |  Branch (1214:46): [True: 0, False: 7.14k]
  |  Branch (1214:60): [True: 0, False: 7.14k]
  ------------------
 1215|  7.14k|    int pos1 = 0, pos2 = 0;
 1216|  7.14k|    uint8_t type1, type2;
 1217|  7.14k|    uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1218|  7.14k|    uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 1219|  7.14k|    while (true) {
  ------------------
  |  Branch (1219:12): [True: 7.14k, Folded]
  ------------------
 1220|  7.14k|        if (s1 == s2) {
  ------------------
  |  Branch (1220:13): [True: 7.08k, False: 57]
  ------------------
 1221|  7.08k|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
 1222|  7.08k|                                                        (uint16_t)pos1, &type1);
 1223|  7.08k|            container_t *c2 = ra_get_container_at_index(&x2->high_low_container,
 1224|  7.08k|                                                        (uint16_t)pos2, &type2);
 1225|  7.08k|            container_t *c = container_xor(c1, type1, c2, type2, &result_type);
 1226|       |
 1227|  7.08k|            if (container_nonzero_cardinality(c, result_type)) {
  ------------------
  |  Branch (1227:17): [True: 7.07k, False: 16]
  ------------------
 1228|  7.07k|                ra_append(&answer->high_low_container, s1, c, result_type);
 1229|  7.07k|            } else {
 1230|     16|                container_free(c, result_type);
 1231|     16|            }
 1232|  7.08k|            ++pos1;
 1233|  7.08k|            ++pos2;
 1234|  7.08k|            if (pos1 == length1) break;
  ------------------
  |  Branch (1234:17): [True: 7.08k, False: 0]
  ------------------
 1235|      0|            if (pos2 == length2) break;
  ------------------
  |  Branch (1235:17): [True: 0, False: 0]
  ------------------
 1236|      0|            s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1237|      0|            s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 1238|       |
 1239|     57|        } else if (s1 < s2) {  // s1 < s2
  ------------------
  |  Branch (1239:20): [True: 57, False: 0]
  ------------------
 1240|     57|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
 1241|     57|                                                        (uint16_t)pos1, &type1);
 1242|     57|            c1 = get_copy_of_container(c1, &type1, is_cow(x1));
 1243|     57|            if (is_cow(x1)) {
  ------------------
  |  Branch (1243:17): [True: 0, False: 57]
  ------------------
 1244|      0|                ra_set_container_at_index(&x1->high_low_container, pos1, c1,
 1245|      0|                                          type1);
 1246|      0|            }
 1247|     57|            ra_append(&answer->high_low_container, s1, c1, type1);
 1248|     57|            pos1++;
 1249|     57|            if (pos1 == length1) break;
  ------------------
  |  Branch (1249:17): [True: 57, False: 0]
  ------------------
 1250|      0|            s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1251|       |
 1252|      0|        } else {  // s1 > s2
 1253|      0|            container_t *c2 = ra_get_container_at_index(&x2->high_low_container,
 1254|      0|                                                        (uint16_t)pos2, &type2);
 1255|      0|            c2 = get_copy_of_container(c2, &type2, is_cow(x2));
 1256|      0|            if (is_cow(x2)) {
  ------------------
  |  Branch (1256:17): [True: 0, False: 0]
  ------------------
 1257|      0|                ra_set_container_at_index(&x2->high_low_container, pos2, c2,
 1258|      0|                                          type2);
 1259|      0|            }
 1260|      0|            ra_append(&answer->high_low_container, s2, c2, type2);
 1261|      0|            pos2++;
 1262|      0|            if (pos2 == length2) break;
  ------------------
  |  Branch (1262:17): [True: 0, False: 0]
  ------------------
 1263|      0|            s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 1264|      0|        }
 1265|  7.14k|    }
 1266|  7.14k|    if (pos1 == length1) {
  ------------------
  |  Branch (1266:9): [True: 7.14k, False: 0]
  ------------------
 1267|  7.14k|        ra_append_copy_range(&answer->high_low_container,
 1268|  7.14k|                             &x2->high_low_container, pos2, length2,
 1269|  7.14k|                             is_cow(x2));
 1270|  7.14k|    } else if (pos2 == length2) {
  ------------------
  |  Branch (1270:16): [True: 0, False: 0]
  ------------------
 1271|      0|        ra_append_copy_range(&answer->high_low_container,
 1272|      0|                             &x1->high_low_container, pos1, length1,
 1273|      0|                             is_cow(x1));
 1274|      0|    }
 1275|  7.14k|    return answer;
 1276|  7.18k|}
roaring_bitmap_xor_inplace:
 1281|  7.18k|                                const roaring_bitmap_t *x2) {
 1282|  7.18k|    assert(x1 != x2);
 1283|  7.18k|    uint8_t result_type = 0;
 1284|  7.18k|    int length1 = x1->high_low_container.size;
 1285|  7.18k|    const int length2 = x2->high_low_container.size;
 1286|       |
 1287|  7.18k|    if (0 == length2) return;
  ------------------
  |  Branch (1287:9): [True: 13, False: 7.17k]
  ------------------
 1288|       |
 1289|  7.17k|    if (0 == length1) {
  ------------------
  |  Branch (1289:9): [True: 1.93k, False: 5.24k]
  ------------------
 1290|  1.93k|        roaring_bitmap_overwrite(x1, x2);
 1291|  1.93k|        return;
 1292|  1.93k|    }
 1293|       |
 1294|       |    // XOR can have new containers inserted from x2, but can also
 1295|       |    // lose containers when x1 and x2 are nonempty and identical.
 1296|       |
 1297|  5.24k|    int pos1 = 0, pos2 = 0;
 1298|  5.24k|    uint8_t type1, type2;
 1299|  5.24k|    uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1300|  5.24k|    uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 1301|  7.23k|    while (true) {
  ------------------
  |  Branch (1301:12): [True: 7.23k, Folded]
  ------------------
 1302|  7.23k|        if (s1 == s2) {
  ------------------
  |  Branch (1302:13): [True: 7.15k, False: 78]
  ------------------
 1303|  7.15k|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
 1304|  7.15k|                                                        (uint16_t)pos1, &type1);
 1305|  7.15k|            container_t *c2 = ra_get_container_at_index(&x2->high_low_container,
 1306|  7.15k|                                                        (uint16_t)pos2, &type2);
 1307|       |
 1308|       |            // We do the computation "in place" only when c1 is not a shared
 1309|       |            // container. Rationale: using a shared container safely with in
 1310|       |            // place computation would require making a copy and then doing the
 1311|       |            // computation in place which is likely less efficient than avoiding
 1312|       |            // in place entirely and always generating a new container.
 1313|       |
 1314|  7.15k|            container_t *c;
 1315|  7.15k|            if (type1 == SHARED_CONTAINER_TYPE) {
  ------------------
  |  |   51|  7.15k|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (1315:17): [True: 0, False: 7.15k]
  ------------------
 1316|      0|                c = container_xor(c1, type1, c2, type2, &result_type);
 1317|      0|                shared_container_free(CAST_shared(c1));  // so release
  ------------------
  |  |   79|      0|#define CAST_shared(c) CAST(shared_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1318|  7.15k|            } else {
 1319|  7.15k|                c = container_ixor(c1, type1, c2, type2, &result_type);
 1320|  7.15k|            }
 1321|       |
 1322|  7.15k|            if (container_nonzero_cardinality(c, result_type)) {
  ------------------
  |  Branch (1322:17): [True: 4.93k, False: 2.22k]
  ------------------
 1323|  4.93k|                ra_set_container_at_index(&x1->high_low_container, pos1, c,
 1324|  4.93k|                                          result_type);
 1325|  4.93k|                ++pos1;
 1326|  4.93k|            } else {
 1327|  2.22k|                container_free(c, result_type);
 1328|  2.22k|                roaring_inplace_merge_bulk(x1, x2, pos1, pos1 + 1, pos2 + 1,
 1329|  2.22k|                                           true);
 1330|  2.22k|                return;
 1331|  2.22k|            }
 1332|       |
 1333|  4.93k|            ++pos2;
 1334|  4.93k|            if (pos1 == length1) break;
  ------------------
  |  Branch (1334:17): [True: 2.94k, False: 1.99k]
  ------------------
 1335|  1.99k|            if (pos2 == length2) break;
  ------------------
  |  Branch (1335:17): [True: 0, False: 1.99k]
  ------------------
 1336|  1.99k|            s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1337|  1.99k|            s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 1338|       |
 1339|  1.99k|        } else if (s1 < s2) {  // s1 < s2
  ------------------
  |  Branch (1339:20): [True: 0, False: 78]
  ------------------
 1340|      0|            pos1++;
 1341|      0|            if (pos1 == length1) break;
  ------------------
  |  Branch (1341:17): [True: 0, False: 0]
  ------------------
 1342|      0|            s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1343|       |
 1344|     78|        } else {  // s1 > s2
 1345|     78|            roaring_inplace_merge_bulk(x1, x2, pos1, pos1, pos2, true);
 1346|     78|            return;
 1347|     78|        }
 1348|  7.23k|    }
 1349|  2.94k|    if (pos1 == length1) {
  ------------------
  |  Branch (1349:9): [True: 2.94k, False: 0]
  ------------------
 1350|  2.94k|        ra_append_copy_range(&x1->high_low_container, &x2->high_low_container,
 1351|  2.94k|                             pos2, length2, is_cow(x2));
 1352|  2.94k|    }
 1353|  2.94k|}
roaring_bitmap_andnot:
 1356|  7.18k|                                        const roaring_bitmap_t *x2) {
 1357|  7.18k|    uint8_t result_type = 0;
 1358|  7.18k|    const int length1 = x1->high_low_container.size,
 1359|  7.18k|              length2 = x2->high_low_container.size;
 1360|  7.18k|    if (0 == length1) {
  ------------------
  |  Branch (1360:9): [True: 0, False: 7.18k]
  ------------------
 1361|      0|        roaring_bitmap_t *empty_bitmap = roaring_bitmap_create();
 1362|      0|        roaring_bitmap_set_copy_on_write(empty_bitmap,
 1363|      0|                                         is_cow(x1) || is_cow(x2));
  ------------------
  |  Branch (1363:42): [True: 0, False: 0]
  |  Branch (1363:56): [True: 0, False: 0]
  ------------------
 1364|      0|        return empty_bitmap;
 1365|      0|    }
 1366|  7.18k|    if (0 == length2) {
  ------------------
  |  Branch (1366:9): [True: 41, False: 7.14k]
  ------------------
 1367|     41|        return roaring_bitmap_copy(x1);
 1368|     41|    }
 1369|  7.14k|    roaring_bitmap_t *answer = roaring_bitmap_create_with_capacity(length1);
 1370|  7.14k|    roaring_bitmap_set_copy_on_write(answer, is_cow(x1) || is_cow(x2));
  ------------------
  |  Branch (1370:46): [True: 0, False: 7.14k]
  |  Branch (1370:60): [True: 0, False: 7.14k]
  ------------------
 1371|       |
 1372|  7.14k|    int pos1 = 0, pos2 = 0;
 1373|  7.14k|    uint8_t type1, type2;
 1374|  7.14k|    uint16_t s1 = 0;
 1375|  7.14k|    uint16_t s2 = 0;
 1376|  7.14k|    while (true) {
  ------------------
  |  Branch (1376:12): [True: 7.14k, Folded]
  ------------------
 1377|  7.14k|        s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1378|  7.14k|        s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 1379|       |
 1380|  7.14k|        if (s1 == s2) {
  ------------------
  |  Branch (1380:13): [True: 7.08k, False: 57]
  ------------------
 1381|  7.08k|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
 1382|  7.08k|                                                        (uint16_t)pos1, &type1);
 1383|  7.08k|            container_t *c2 = ra_get_container_at_index(&x2->high_low_container,
 1384|  7.08k|                                                        (uint16_t)pos2, &type2);
 1385|  7.08k|            container_t *c =
 1386|  7.08k|                container_andnot(c1, type1, c2, type2, &result_type);
 1387|       |
 1388|  7.08k|            if (container_nonzero_cardinality(c, result_type)) {
  ------------------
  |  Branch (1388:17): [True: 6.84k, False: 242]
  ------------------
 1389|  6.84k|                ra_append(&answer->high_low_container, s1, c, result_type);
 1390|  6.84k|            } else {
 1391|    242|                container_free(c, result_type);
 1392|    242|            }
 1393|  7.08k|            ++pos1;
 1394|  7.08k|            ++pos2;
 1395|  7.08k|            if (pos1 == length1) break;
  ------------------
  |  Branch (1395:17): [True: 7.08k, False: 0]
  ------------------
 1396|      0|            if (pos2 == length2) break;
  ------------------
  |  Branch (1396:17): [True: 0, False: 0]
  ------------------
 1397|     57|        } else if (s1 < s2) {  // s1 < s2
  ------------------
  |  Branch (1397:20): [True: 57, False: 0]
  ------------------
 1398|     57|            const int next_pos1 =
 1399|     57|                ra_advance_until(&x1->high_low_container, s2, pos1);
 1400|     57|            ra_append_copy_range(&answer->high_low_container,
 1401|     57|                                 &x1->high_low_container, pos1, next_pos1,
 1402|     57|                                 is_cow(x1));
 1403|       |            // TODO : perhaps some of the copy_on_write should be based on
 1404|       |            // answer rather than x1 (more stringent?).  Many similar cases
 1405|     57|            pos1 = next_pos1;
 1406|     57|            if (pos1 == length1) break;
  ------------------
  |  Branch (1406:17): [True: 57, False: 0]
  ------------------
 1407|     57|        } else {  // s1 > s2
 1408|      0|            pos2 = ra_advance_until(&x2->high_low_container, s1, pos2);
 1409|      0|            if (pos2 == length2) break;
  ------------------
  |  Branch (1409:17): [True: 0, False: 0]
  ------------------
 1410|      0|        }
 1411|  7.14k|    }
 1412|  7.14k|    if (pos2 == length2) {
  ------------------
  |  Branch (1412:9): [True: 4.95k, False: 2.18k]
  ------------------
 1413|  4.95k|        ra_append_copy_range(&answer->high_low_container,
 1414|  4.95k|                             &x1->high_low_container, pos1, length1,
 1415|  4.95k|                             is_cow(x1));
 1416|  4.95k|    }
 1417|  7.14k|    return answer;
 1418|  7.18k|}
roaring_bitmap_andnot_inplace:
 1423|  7.18k|                                   const roaring_bitmap_t *x2) {
 1424|  7.18k|    assert(x1 != x2);
 1425|       |
 1426|  7.18k|    uint8_t result_type = 0;
 1427|  7.18k|    int length1 = x1->high_low_container.size;
 1428|  7.18k|    const int length2 = x2->high_low_container.size;
 1429|  7.18k|    int intersection_size = 0;
 1430|       |
 1431|  7.18k|    if (0 == length2) return;
  ------------------
  |  Branch (1431:9): [True: 393, False: 6.79k]
  ------------------
 1432|       |
 1433|  6.79k|    if (0 == length1) {
  ------------------
  |  Branch (1433:9): [True: 0, False: 6.79k]
  ------------------
 1434|      0|        roaring_bitmap_clear(x1);
 1435|      0|        return;
 1436|      0|    }
 1437|       |
 1438|  6.79k|    int pos1 = 0, pos2 = 0;
 1439|  6.79k|    uint8_t type1, type2;
 1440|  6.79k|    uint16_t s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1441|  6.79k|    uint16_t s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 1442|  6.79k|    while (true) {
  ------------------
  |  Branch (1442:12): [True: 6.79k, Folded]
  ------------------
 1443|  6.79k|        if (s1 == s2) {
  ------------------
  |  Branch (1443:13): [True: 6.79k, False: 0]
  ------------------
 1444|  6.79k|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
 1445|  6.79k|                                                        (uint16_t)pos1, &type1);
 1446|  6.79k|            container_t *c2 = ra_get_container_at_index(&x2->high_low_container,
 1447|  6.79k|                                                        (uint16_t)pos2, &type2);
 1448|       |
 1449|       |            // We do the computation "in place" only when c1 is not a shared
 1450|       |            // container. Rationale: using a shared container safely with in
 1451|       |            // place computation would require making a copy and then doing the
 1452|       |            // computation in place which is likely less efficient than avoiding
 1453|       |            // in place entirely and always generating a new container.
 1454|       |
 1455|  6.79k|            container_t *c;
 1456|  6.79k|            if (type1 == SHARED_CONTAINER_TYPE) {
  ------------------
  |  |   51|  6.79k|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (1456:17): [True: 0, False: 6.79k]
  ------------------
 1457|      0|                c = container_andnot(c1, type1, c2, type2, &result_type);
 1458|      0|                shared_container_free(CAST_shared(c1));  // release
  ------------------
  |  |   79|      0|#define CAST_shared(c) CAST(shared_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1459|  6.79k|            } else {
 1460|  6.79k|                c = container_iandnot(c1, type1, c2, type2, &result_type);
 1461|  6.79k|            }
 1462|       |
 1463|  6.79k|            if (container_nonzero_cardinality(c, result_type)) {
  ------------------
  |  Branch (1463:17): [True: 4.86k, False: 1.92k]
  ------------------
 1464|  4.86k|                ra_replace_key_and_container_at_index(&x1->high_low_container,
 1465|  4.86k|                                                      intersection_size++, s1,
 1466|  4.86k|                                                      c, result_type);
 1467|  4.86k|            } else {
 1468|  1.92k|                container_free(c, result_type);
 1469|  1.92k|            }
 1470|       |
 1471|  6.79k|            ++pos1;
 1472|  6.79k|            ++pos2;
 1473|  6.79k|            if (pos1 == length1) break;
  ------------------
  |  Branch (1473:17): [True: 4.74k, False: 2.05k]
  ------------------
 1474|  2.05k|            if (pos2 == length2) break;
  ------------------
  |  Branch (1474:17): [True: 2.05k, False: 0]
  ------------------
 1475|      0|            s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1476|      0|            s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 1477|       |
 1478|      0|        } else if (s1 < s2) {  // s1 < s2
  ------------------
  |  Branch (1478:20): [True: 0, False: 0]
  ------------------
 1479|      0|            if (pos1 != intersection_size) {
  ------------------
  |  Branch (1479:17): [True: 0, False: 0]
  ------------------
 1480|      0|                container_t *c1 = ra_get_container_at_index(
 1481|      0|                    &x1->high_low_container, (uint16_t)pos1, &type1);
 1482|       |
 1483|      0|                ra_replace_key_and_container_at_index(
 1484|      0|                    &x1->high_low_container, intersection_size, s1, c1, type1);
 1485|      0|            }
 1486|      0|            intersection_size++;
 1487|      0|            pos1++;
 1488|      0|            if (pos1 == length1) break;
  ------------------
  |  Branch (1488:17): [True: 0, False: 0]
  ------------------
 1489|      0|            s1 = ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 1490|       |
 1491|      0|        } else {  // s1 > s2
 1492|      0|            pos2 = ra_advance_until(&x2->high_low_container, s1, pos2);
 1493|      0|            if (pos2 == length2) break;
  ------------------
  |  Branch (1493:17): [True: 0, False: 0]
  ------------------
 1494|      0|            s2 = ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 1495|      0|        }
 1496|  6.79k|    }
 1497|       |
 1498|  6.79k|    if (pos1 < length1) {
  ------------------
  |  Branch (1498:9): [True: 2.05k, False: 4.74k]
  ------------------
 1499|       |        // all containers between intersection_size and
 1500|       |        // pos1 are junk.  However, they have either been moved
 1501|       |        // (thus still referenced) or involved in an iandnot
 1502|       |        // that will clean up all containers that could not be reused.
 1503|       |        // Thus we should not free the junk containers between
 1504|       |        // intersection_size and pos1.
 1505|  2.05k|        if (pos1 > intersection_size) {
  ------------------
  |  Branch (1505:13): [True: 24, False: 2.02k]
  ------------------
 1506|       |            // left slide of remaining items
 1507|     24|            ra_copy_range(&x1->high_low_container, pos1, length1,
 1508|     24|                          intersection_size);
 1509|     24|        }
 1510|       |        // else current placement is fine
 1511|  2.05k|        intersection_size += (length1 - pos1);
 1512|  2.05k|    }
 1513|  6.79k|    ra_downsize(&x1->high_low_container, intersection_size);
 1514|  6.79k|}
roaring_bitmap_get_cardinality:
 1516|  71.8k|uint64_t roaring_bitmap_get_cardinality(const roaring_bitmap_t *r) {
 1517|  71.8k|    const roaring_array_t *ra = &r->high_low_container;
 1518|       |
 1519|  71.8k|    uint64_t card = 0;
 1520|   418k|    for (int i = 0; i < ra->size; ++i)
  ------------------
  |  Branch (1520:21): [True: 346k, False: 71.8k]
  ------------------
 1521|   346k|        card += container_get_cardinality(ra->containers[i], ra->typecodes[i]);
 1522|  71.8k|    return card;
 1523|  71.8k|}
roaring_bitmap_is_empty:
 1586|  14.3k|bool roaring_bitmap_is_empty(const roaring_bitmap_t *r) {
 1587|  14.3k|    return r->high_low_container.size == 0;
 1588|  14.3k|}
roaring_bitmap_to_uint32_array:
 1590|  7.18k|void roaring_bitmap_to_uint32_array(const roaring_bitmap_t *r, uint32_t *ans) {
 1591|  7.18k|    ra_to_uint32_array(&r->high_low_container, ans);
 1592|  7.18k|}
roaring_bitmap_run_optimize:
 1610|  14.3k|bool roaring_bitmap_run_optimize(roaring_bitmap_t *r) {
 1611|  14.3k|    bool answer = false;
 1612|  28.7k|    for (int i = 0; i < r->high_low_container.size; i++) {
  ------------------
  |  Branch (1612:21): [True: 14.3k, False: 14.3k]
  ------------------
 1613|  14.3k|        uint8_t type_original, type_after;
 1614|  14.3k|        ra_unshare_container_at_index(
 1615|  14.3k|            &r->high_low_container,
 1616|  14.3k|            (uint16_t)i);  // TODO: this introduces extra cloning!
 1617|  14.3k|        container_t *c = ra_get_container_at_index(&r->high_low_container,
 1618|  14.3k|                                                   (uint16_t)i, &type_original);
 1619|  14.3k|        container_t *c1 = convert_run_optimize(c, type_original, &type_after);
 1620|  14.3k|        if (type_after == RUN_CONTAINER_TYPE) {
  ------------------
  |  |   50|  14.3k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (1620:13): [True: 3.76k, False: 10.6k]
  ------------------
 1621|       |            answer = true;
 1622|  3.76k|        }
 1623|  14.3k|        ra_set_container_at_index(&r->high_low_container, i, c1, type_after);
 1624|  14.3k|    }
 1625|  14.3k|    return answer;
 1626|  14.3k|}
roaring_bitmap_shrink_to_fit:
 1628|  7.18k|size_t roaring_bitmap_shrink_to_fit(roaring_bitmap_t *r) {
 1629|  7.18k|    size_t answer = 0;
 1630|  14.3k|    for (int i = 0; i < r->high_low_container.size; i++) {
  ------------------
  |  Branch (1630:21): [True: 7.18k, False: 7.18k]
  ------------------
 1631|  7.18k|        uint8_t type_original;
 1632|  7.18k|        container_t *c = ra_get_container_at_index(&r->high_low_container,
 1633|  7.18k|                                                   (uint16_t)i, &type_original);
 1634|  7.18k|        answer += container_shrink_to_fit(c, type_original);
 1635|  7.18k|    }
 1636|  7.18k|    answer += ra_shrink_to_fit(&r->high_low_container);
 1637|  7.18k|    return answer;
 1638|  7.18k|}
roaring_bitmap_remove_run_compression:
 1644|  7.18k|bool roaring_bitmap_remove_run_compression(roaring_bitmap_t *r) {
 1645|  7.18k|    bool answer = false;
 1646|  81.1k|    for (int i = 0; i < r->high_low_container.size; i++) {
  ------------------
  |  Branch (1646:21): [True: 73.9k, False: 7.18k]
  ------------------
 1647|  73.9k|        uint8_t type_original, type_after;
 1648|  73.9k|        container_t *c = ra_get_container_at_index(&r->high_low_container,
 1649|  73.9k|                                                   (uint16_t)i, &type_original);
 1650|  73.9k|        if (get_container_type(c, type_original) == RUN_CONTAINER_TYPE) {
  ------------------
  |  |   50|  73.9k|#define RUN_CONTAINER_TYPE 3
  ------------------
  |  Branch (1650:13): [True: 66.0k, False: 7.92k]
  ------------------
 1651|  66.0k|            answer = true;
 1652|  66.0k|            if (type_original == SHARED_CONTAINER_TYPE) {
  ------------------
  |  |   51|  66.0k|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (1652:17): [True: 0, False: 66.0k]
  ------------------
 1653|      0|                run_container_t *truec = CAST_run(CAST_shared(c)->container);
  ------------------
  |  |   77|      0|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1654|      0|                int32_t card = run_container_cardinality(truec);
 1655|      0|                container_t *c1 = convert_to_bitset_or_array_container(
 1656|      0|                    truec, card, &type_after);
 1657|      0|                shared_container_free(CAST_shared(c));  // frees run as needed
  ------------------
  |  |   79|      0|#define CAST_shared(c) CAST(shared_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1658|      0|                ra_set_container_at_index(&r->high_low_container, i, c1,
 1659|      0|                                          type_after);
 1660|       |
 1661|  66.0k|            } else {
 1662|  66.0k|                int32_t card = run_container_cardinality(CAST_run(c));
  ------------------
  |  |   77|  66.0k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  66.0k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1663|  66.0k|                container_t *c1 = convert_to_bitset_or_array_container(
 1664|  66.0k|                    CAST_run(c), card, &type_after);
  ------------------
  |  |   77|  66.0k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  66.0k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1665|  66.0k|                run_container_free(CAST_run(c));
  ------------------
  |  |   77|  66.0k|#define CAST_run(c) CAST(run_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|  66.0k|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1666|  66.0k|                ra_set_container_at_index(&r->high_low_container, i, c1,
 1667|  66.0k|                                          type_after);
 1668|  66.0k|            }
 1669|  66.0k|        }
 1670|  73.9k|    }
 1671|  7.18k|    return answer;
 1672|  7.18k|}
roaring_bitmap_portable_size_in_bytes:
 1707|  14.3k|size_t roaring_bitmap_portable_size_in_bytes(const roaring_bitmap_t *r) {
 1708|  14.3k|    return ra_portable_size_in_bytes(&r->high_low_container);
 1709|  14.3k|}
roaring_bitmap_portable_deserialize_safe:
 1712|  14.3k|                                                           size_t maxbytes) {
 1713|  14.3k|    roaring_bitmap_t *ans =
 1714|  14.3k|        (roaring_bitmap_t *)roaring_malloc(sizeof(roaring_bitmap_t));
 1715|  14.3k|    if (ans == NULL) {
  ------------------
  |  Branch (1715:9): [True: 0, False: 14.3k]
  ------------------
 1716|      0|        return NULL;
 1717|      0|    }
 1718|  14.3k|    size_t bytesread;
 1719|  14.3k|    bool is_ok = ra_portable_deserialize(&ans->high_low_container, buf,
 1720|  14.3k|                                         maxbytes, &bytesread);
 1721|  14.3k|    if (!is_ok) {
  ------------------
  |  Branch (1721:9): [True: 7.17k, False: 7.20k]
  ------------------
 1722|  7.17k|        roaring_free(ans);
 1723|  7.17k|        return NULL;
 1724|  7.17k|    }
 1725|  7.20k|    roaring_bitmap_set_copy_on_write(ans, false);
 1726|  7.20k|    if (!is_ok) {
  ------------------
  |  Branch (1726:9): [True: 0, False: 7.20k]
  ------------------
 1727|      0|        roaring_free(ans);
 1728|      0|        return NULL;
 1729|      0|    }
 1730|  7.20k|    return ans;
 1731|  7.20k|}
roaring_bitmap_portable_serialize:
 1742|  7.18k|size_t roaring_bitmap_portable_serialize(const roaring_bitmap_t *r, char *buf) {
 1743|  7.18k|    return ra_portable_serialize(&r->high_low_container, buf);
 1744|  7.18k|}
roaring_iterate:
 1825|  7.17k|                     void *ptr) {
 1826|  7.17k|    const roaring_array_t *ra = &r->high_low_container;
 1827|       |
 1828|  69.3k|    for (int i = 0; i < ra->size; ++i)
  ------------------
  |  Branch (1828:21): [True: 62.1k, False: 7.17k]
  ------------------
 1829|  62.1k|        if (!container_iterate(ra->containers[i], ra->typecodes[i],
  ------------------
  |  Branch (1829:13): [True: 0, False: 62.1k]
  ------------------
 1830|  62.1k|                               ((uint32_t)ra->keys[i]) << 16, iterator, ptr)) {
 1831|      0|            return false;
 1832|      0|        }
 1833|  7.17k|    return true;
 1834|  7.17k|}
roaring_iterator_init:
 1941|  14.3k|                           roaring_uint32_iterator_t *newit) {
 1942|  14.3k|    newit->parent = r;
 1943|  14.3k|    newit->container_index = 0;
 1944|  14.3k|    newit->has_value = loadfirstvalue(newit);
 1945|  14.3k|}
roaring_uint32_iterator_move_equalorlarger:
 1973|  7.18k|                                                uint32_t val) {
 1974|  7.18k|    uint16_t hb = val >> 16;
 1975|  7.18k|    const int i = ra_get_index(&it->parent->high_low_container, hb);
 1976|  7.18k|    if (i >= 0) {
  ------------------
  |  Branch (1976:9): [True: 7.11k, False: 70]
  ------------------
 1977|  7.11k|        uint32_t lowvalue =
 1978|  7.11k|            container_maximum(it->parent->high_low_container.containers[i],
 1979|  7.11k|                              it->parent->high_low_container.typecodes[i]);
 1980|  7.11k|        uint16_t lb = val & 0xFFFF;
 1981|  7.11k|        if (lowvalue < lb) {
  ------------------
  |  Branch (1981:13): [True: 19, False: 7.09k]
  ------------------
 1982|       |            // will have to load first value of next container
 1983|     19|            it->container_index = i + 1;
 1984|  7.09k|        } else {
 1985|       |            // the value is necessarily within the range of the container
 1986|  7.09k|            it->container_index = i;
 1987|  7.09k|            it->has_value = loadfirstvalue_largeorequal(it, val);
 1988|  7.09k|            return it->has_value;
 1989|  7.09k|        }
 1990|  7.11k|    } else {
 1991|       |        // there is no matching, so we are going for the next container
 1992|     70|        it->container_index = -i - 1;
 1993|     70|    }
 1994|     89|    it->has_value = loadfirstvalue(it);
 1995|     89|    return it->has_value;
 1996|  7.18k|}
roaring_uint32_iterator_advance:
 1998|   337k|bool roaring_uint32_iterator_advance(roaring_uint32_iterator_t *it) {
 1999|   337k|    if (it->container_index >= it->parent->high_low_container.size) {
  ------------------
  |  Branch (1999:9): [True: 0, False: 337k]
  ------------------
 2000|      0|        return (it->has_value = false);
 2001|      0|    }
 2002|   337k|    if (it->container_index < 0) {
  ------------------
  |  Branch (2002:9): [True: 0, False: 337k]
  ------------------
 2003|      0|        it->container_index = 0;
 2004|      0|        return (it->has_value = loadfirstvalue(it));
 2005|      0|    }
 2006|   337k|    uint16_t low16 = (uint16_t)it->current_value;
 2007|   337k|    if (container_iterator_next(it->container, it->typecode, &it->container_it,
  ------------------
  |  Branch (2007:9): [True: 330k, False: 6.94k]
  ------------------
 2008|   337k|                                &low16)) {
 2009|   330k|        it->current_value = it->highbits | low16;
 2010|   330k|        return (it->has_value = true);
 2011|   330k|    }
 2012|  6.94k|    it->container_index++;
 2013|  6.94k|    return (it->has_value = loadfirstvalue(it));
 2014|   337k|}
roaring_bitmap_equals:
 2209|  14.3k|                           const roaring_bitmap_t *r2) {
 2210|  14.3k|    const roaring_array_t *ra1 = &r1->high_low_container;
 2211|  14.3k|    const roaring_array_t *ra2 = &r2->high_low_container;
 2212|       |
 2213|  14.3k|    if (ra1->size != ra2->size) {
  ------------------
  |  Branch (2213:9): [True: 2.33k, False: 12.0k]
  ------------------
 2214|  2.33k|        return false;
 2215|  2.33k|    }
 2216|  90.8k|    for (int i = 0; i < ra1->size; ++i) {
  ------------------
  |  Branch (2216:21): [True: 78.8k, False: 12.0k]
  ------------------
 2217|  78.8k|        if (ra1->keys[i] != ra2->keys[i]) {
  ------------------
  |  Branch (2217:13): [True: 15, False: 78.7k]
  ------------------
 2218|     15|            return false;
 2219|     15|        }
 2220|  78.8k|    }
 2221|  85.9k|    for (int i = 0; i < ra1->size; ++i) {
  ------------------
  |  Branch (2221:21): [True: 78.7k, False: 7.18k]
  ------------------
 2222|  78.7k|        bool areequal = container_equals(ra1->containers[i], ra1->typecodes[i],
 2223|  78.7k|                                         ra2->containers[i], ra2->typecodes[i]);
 2224|  78.7k|        if (!areequal) {
  ------------------
  |  Branch (2224:13): [True: 4.83k, False: 73.9k]
  ------------------
 2225|  4.83k|            return false;
 2226|  4.83k|        }
 2227|  78.7k|    }
 2228|  7.18k|    return true;
 2229|  12.0k|}
roaring_bitmap_is_subset:
 2232|  12.6k|                              const roaring_bitmap_t *r2) {
 2233|  12.6k|    const roaring_array_t *ra1 = &r1->high_low_container;
 2234|  12.6k|    const roaring_array_t *ra2 = &r2->high_low_container;
 2235|       |
 2236|  12.6k|    const int length1 = ra1->size, length2 = ra2->size;
 2237|       |
 2238|  12.6k|    int pos1 = 0, pos2 = 0;
 2239|       |
 2240|  12.6k|    while (pos1 < length1 && pos2 < length2) {
  ------------------
  |  Branch (2240:12): [True: 12.2k, False: 484]
  |  Branch (2240:30): [True: 12.1k, False: 41]
  ------------------
 2241|  12.1k|        const uint16_t s1 = ra_get_key_at_index(ra1, (uint16_t)pos1);
 2242|  12.1k|        const uint16_t s2 = ra_get_key_at_index(ra2, (uint16_t)pos2);
 2243|       |
 2244|  12.1k|        if (s1 == s2) {
  ------------------
  |  Branch (2244:13): [True: 12.0k, False: 92]
  ------------------
 2245|  12.0k|            uint8_t type1, type2;
 2246|  12.0k|            container_t *c1 =
 2247|  12.0k|                ra_get_container_at_index(ra1, (uint16_t)pos1, &type1);
 2248|  12.0k|            container_t *c2 =
 2249|  12.0k|                ra_get_container_at_index(ra2, (uint16_t)pos2, &type2);
 2250|  12.0k|            if (!container_is_subset(c1, type1, c2, type2)) return false;
  ------------------
  |  Branch (2250:17): [True: 12.0k, False: 0]
  ------------------
 2251|      0|            ++pos1;
 2252|      0|            ++pos2;
 2253|     92|        } else if (s1 < s2) {  // s1 < s2
  ------------------
  |  Branch (2253:20): [True: 92, False: 0]
  ------------------
 2254|     92|            return false;
 2255|     92|        } else {  // s1 > s2
 2256|      0|            pos2 = ra_advance_until(ra2, s1, pos2);
 2257|      0|        }
 2258|  12.1k|    }
 2259|    525|    if (pos1 == length1)
  ------------------
  |  Branch (2259:9): [True: 484, False: 41]
  ------------------
 2260|    484|        return true;
 2261|     41|    else
 2262|     41|        return false;
 2263|    525|}
roaring_bitmap_flip_inplace:
 2432|  7.18k|                                 uint64_t range_end) {
 2433|  7.18k|    if (range_start >= range_end || range_start > (uint64_t)UINT32_MAX + 1) {
  ------------------
  |  Branch (2433:9): [True: 6.64k, False: 538]
  |  Branch (2433:37): [True: 0, False: 538]
  ------------------
 2434|  6.64k|        return;
 2435|  6.64k|    }
 2436|    538|    roaring_bitmap_flip_inplace_closed(x1, (uint32_t)range_start,
 2437|    538|                                       (uint32_t)(range_end - 1));
 2438|    538|}
roaring_bitmap_flip_inplace_closed:
 2442|  7.72k|                                        uint32_t range_end) {
 2443|  7.72k|    if (range_start > range_end) {
  ------------------
  |  Branch (2443:9): [True: 151, False: 7.57k]
  ------------------
 2444|    151|        return;  // empty range
 2445|    151|    }
 2446|       |
 2447|  7.57k|    uint16_t hb_start = (uint16_t)(range_start >> 16);
 2448|  7.57k|    const uint16_t lb_start = (uint16_t)range_start;
 2449|  7.57k|    uint16_t hb_end = (uint16_t)(range_end >> 16);
 2450|  7.57k|    const uint16_t lb_end = (uint16_t)range_end;
 2451|       |
 2452|  7.57k|    if (hb_start == hb_end) {
  ------------------
  |  Branch (2452:9): [True: 7.11k, False: 462]
  ------------------
 2453|  7.11k|        inplace_flip_container(&x1->high_low_container, hb_start, lb_start,
 2454|  7.11k|                               lb_end);
 2455|  7.11k|    } else {
 2456|       |        // start and end containers are distinct
 2457|    462|        if (lb_start > 0) {
  ------------------
  |  Branch (2457:13): [True: 374, False: 88]
  ------------------
 2458|       |            // handle first (partial) container
 2459|    374|            inplace_flip_container(&x1->high_low_container, hb_start, lb_start,
 2460|    374|                                   0xFFFF);
 2461|    374|            ++hb_start;  // for the full containers.  Can't wrap.
 2462|    374|        }
 2463|       |
 2464|    462|        if (lb_end != 0xFFFF) --hb_end;
  ------------------
  |  Branch (2464:13): [True: 444, False: 18]
  ------------------
 2465|       |
 2466|  24.5k|        for (uint32_t hb = hb_start; hb <= hb_end; ++hb) {
  ------------------
  |  Branch (2466:38): [True: 24.1k, False: 462]
  ------------------
 2467|  24.1k|            inplace_fully_flip_container(&x1->high_low_container, (uint16_t)hb);
 2468|  24.1k|        }
 2469|       |        // handle a partial final container
 2470|    462|        if (lb_end != 0xFFFF) {
  ------------------
  |  Branch (2470:13): [True: 444, False: 18]
  ------------------
 2471|    444|            inplace_flip_container(&x1->high_low_container, hb_end + 1, 0,
 2472|    444|                                   lb_end);
 2473|    444|            ++hb_end;
 2474|    444|        }
 2475|    462|    }
 2476|  7.57k|}
roaring_bitmap_rank:
 2942|  7.18k|uint64_t roaring_bitmap_rank(const roaring_bitmap_t *bm, uint32_t x) {
 2943|  7.18k|    uint64_t size = 0;
 2944|  7.18k|    uint32_t xhigh = x >> 16;
 2945|  7.18k|    for (int i = 0; i < bm->high_low_container.size; i++) {
  ------------------
  |  Branch (2945:21): [True: 7.18k, False: 0]
  ------------------
 2946|  7.18k|        uint32_t key = bm->high_low_container.keys[i];
 2947|  7.18k|        if (xhigh > key) {
  ------------------
  |  Branch (2947:13): [True: 0, False: 7.18k]
  ------------------
 2948|      0|            size +=
 2949|      0|                container_get_cardinality(bm->high_low_container.containers[i],
 2950|      0|                                          bm->high_low_container.typecodes[i]);
 2951|  7.18k|        } else if (xhigh == key) {
  ------------------
  |  Branch (2951:20): [True: 7.18k, False: 0]
  ------------------
 2952|  7.18k|            return size + container_rank(bm->high_low_container.containers[i],
 2953|  7.18k|                                         bm->high_low_container.typecodes[i],
 2954|  7.18k|                                         x & 0xFFFF);
 2955|  7.18k|        } else {
 2956|      0|            return size;
 2957|      0|        }
 2958|  7.18k|    }
 2959|      0|    return size;
 2960|  7.18k|}
roaring_bitmap_minimum:
 3025|  7.18k|uint32_t roaring_bitmap_minimum(const roaring_bitmap_t *bm) {
 3026|  7.18k|    if (bm->high_low_container.size > 0) {
  ------------------
  |  Branch (3026:9): [True: 7.14k, False: 41]
  ------------------
 3027|  7.14k|        container_t *c = bm->high_low_container.containers[0];
 3028|  7.14k|        uint8_t type = bm->high_low_container.typecodes[0];
 3029|  7.14k|        uint32_t key = bm->high_low_container.keys[0];
 3030|  7.14k|        uint32_t lowvalue = container_minimum(c, type);
 3031|  7.14k|        return lowvalue | (key << 16);
 3032|  7.14k|    }
 3033|     41|    return UINT32_MAX;
 3034|  7.18k|}
roaring_bitmap_maximum:
 3040|  7.18k|uint32_t roaring_bitmap_maximum(const roaring_bitmap_t *bm) {
 3041|  7.18k|    if (bm->high_low_container.size > 0) {
  ------------------
  |  Branch (3041:9): [True: 7.14k, False: 41]
  ------------------
 3042|  7.14k|        container_t *container =
 3043|  7.14k|            bm->high_low_container.containers[bm->high_low_container.size - 1];
 3044|  7.14k|        uint8_t typecode =
 3045|  7.14k|            bm->high_low_container.typecodes[bm->high_low_container.size - 1];
 3046|  7.14k|        uint32_t key =
 3047|  7.14k|            bm->high_low_container.keys[bm->high_low_container.size - 1];
 3048|  7.14k|        uint32_t lowvalue = container_maximum(container, typecode);
 3049|  7.14k|        return lowvalue | (key << 16);
 3050|  7.14k|    }
 3051|     41|    return 0;
 3052|  7.18k|}
roaring_bitmap_select:
 3055|  7.18k|                           uint32_t *element) {
 3056|  7.18k|    container_t *container;
 3057|  7.18k|    uint8_t typecode;
 3058|  7.18k|    uint16_t key;
 3059|  7.18k|    uint32_t start_rank = 0;
 3060|  7.18k|    int i = 0;
 3061|  7.18k|    bool valid = false;
 3062|  14.3k|    while (!valid && i < bm->high_low_container.size) {
  ------------------
  |  Branch (3062:12): [True: 7.61k, False: 6.76k]
  |  Branch (3062:22): [True: 7.18k, False: 423]
  ------------------
 3063|  7.18k|        container = bm->high_low_container.containers[i];
 3064|  7.18k|        typecode = bm->high_low_container.typecodes[i];
 3065|  7.18k|        valid =
 3066|  7.18k|            container_select(container, typecode, &start_rank, rank, element);
 3067|  7.18k|        i++;
 3068|  7.18k|    }
 3069|       |
 3070|  7.18k|    if (valid) {
  ------------------
  |  Branch (3070:9): [True: 6.76k, False: 423]
  ------------------
 3071|  6.76k|        key = bm->high_low_container.keys[i - 1];
 3072|  6.76k|        *element |= (((uint32_t)key) << 16);  // w/o cast, key promotes signed
 3073|  6.76k|        return true;
 3074|  6.76k|    } else
 3075|    423|        return false;
 3076|  7.18k|}
roaring_bitmap_intersect:
 3079|  7.18k|                              const roaring_bitmap_t *x2) {
 3080|  7.18k|    const int length1 = x1->high_low_container.size,
 3081|  7.18k|              length2 = x2->high_low_container.size;
 3082|  7.18k|    uint64_t answer = 0;
 3083|  7.18k|    int pos1 = 0, pos2 = 0;
 3084|       |
 3085|  7.53k|    while (pos1 < length1 && pos2 < length2) {
  ------------------
  |  Branch (3085:12): [True: 7.18k, False: 352]
  |  Branch (3085:30): [True: 7.14k, False: 41]
  ------------------
 3086|  7.14k|        const uint16_t s1 =
 3087|  7.14k|            ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 3088|  7.14k|        const uint16_t s2 =
 3089|  7.14k|            ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 3090|       |
 3091|  7.14k|        if (s1 == s2) {
  ------------------
  |  Branch (3091:13): [True: 7.08k, False: 57]
  ------------------
 3092|  7.08k|            uint8_t type1, type2;
 3093|  7.08k|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
 3094|  7.08k|                                                        (uint16_t)pos1, &type1);
 3095|  7.08k|            container_t *c2 = ra_get_container_at_index(&x2->high_low_container,
 3096|  7.08k|                                                        (uint16_t)pos2, &type2);
 3097|  7.08k|            if (container_intersect(c1, type1, c2, type2)) return true;
  ------------------
  |  Branch (3097:17): [True: 6.79k, False: 295]
  ------------------
 3098|    295|            ++pos1;
 3099|    295|            ++pos2;
 3100|    295|        } else if (s1 < s2) {  // s1 < s2
  ------------------
  |  Branch (3100:20): [True: 57, False: 0]
  ------------------
 3101|     57|            pos1 = ra_advance_until(&x1->high_low_container, s2, pos1);
 3102|     57|        } else {  // s1 > s2
 3103|      0|            pos2 = ra_advance_until(&x2->high_low_container, s1, pos2);
 3104|      0|        }
 3105|  7.14k|    }
 3106|    393|    return answer != 0;
 3107|  7.18k|}
roaring_bitmap_and_cardinality:
 3129|  28.7k|                                        const roaring_bitmap_t *x2) {
 3130|  28.7k|    const int length1 = x1->high_low_container.size,
 3131|  28.7k|              length2 = x2->high_low_container.size;
 3132|  28.7k|    uint64_t answer = 0;
 3133|  28.7k|    int pos1 = 0, pos2 = 0;
 3134|  57.3k|    while (pos1 < length1 && pos2 < length2) {
  ------------------
  |  Branch (3134:12): [True: 28.7k, False: 28.5k]
  |  Branch (3134:30): [True: 28.5k, False: 164]
  ------------------
 3135|  28.5k|        const uint16_t s1 =
 3136|  28.5k|            ra_get_key_at_index(&x1->high_low_container, (uint16_t)pos1);
 3137|  28.5k|        const uint16_t s2 =
 3138|  28.5k|            ra_get_key_at_index(&x2->high_low_container, (uint16_t)pos2);
 3139|       |
 3140|  28.5k|        if (s1 == s2) {
  ------------------
  |  Branch (3140:13): [True: 28.3k, False: 228]
  ------------------
 3141|  28.3k|            uint8_t type1, type2;
 3142|  28.3k|            container_t *c1 = ra_get_container_at_index(&x1->high_low_container,
 3143|  28.3k|                                                        (uint16_t)pos1, &type1);
 3144|  28.3k|            container_t *c2 = ra_get_container_at_index(&x2->high_low_container,
 3145|  28.3k|                                                        (uint16_t)pos2, &type2);
 3146|  28.3k|            answer += container_and_cardinality(c1, type1, c2, type2);
 3147|  28.3k|            ++pos1;
 3148|  28.3k|            ++pos2;
 3149|  28.3k|        } else if (s1 < s2) {  // s1 < s2
  ------------------
  |  Branch (3149:20): [True: 228, False: 0]
  ------------------
 3150|    228|            pos1 = ra_advance_until(&x1->high_low_container, s2, pos1);
 3151|    228|        } else {  // s1 > s2
 3152|      0|            pos2 = ra_advance_until(&x2->high_low_container, s1, pos2);
 3153|      0|        }
 3154|  28.5k|    }
 3155|  28.7k|    return answer;
 3156|  28.7k|}
roaring_bitmap_jaccard_index:
 3159|  7.18k|                                    const roaring_bitmap_t *x2) {
 3160|  7.18k|    const uint64_t c1 = roaring_bitmap_get_cardinality(x1);
 3161|  7.18k|    const uint64_t c2 = roaring_bitmap_get_cardinality(x2);
 3162|  7.18k|    const uint64_t inter = roaring_bitmap_and_cardinality(x1, x2);
 3163|  7.18k|    return (double)inter / (double)(c1 + c2 - inter);
 3164|  7.18k|}
roaring_bitmap_or_cardinality:
 3167|  7.18k|                                       const roaring_bitmap_t *x2) {
 3168|  7.18k|    const uint64_t c1 = roaring_bitmap_get_cardinality(x1);
 3169|  7.18k|    const uint64_t c2 = roaring_bitmap_get_cardinality(x2);
 3170|  7.18k|    const uint64_t inter = roaring_bitmap_and_cardinality(x1, x2);
 3171|  7.18k|    return c1 + c2 - inter;
 3172|  7.18k|}
roaring_bitmap_andnot_cardinality:
 3175|  7.18k|                                           const roaring_bitmap_t *x2) {
 3176|  7.18k|    const uint64_t c1 = roaring_bitmap_get_cardinality(x1);
 3177|  7.18k|    const uint64_t inter = roaring_bitmap_and_cardinality(x1, x2);
 3178|  7.18k|    return c1 - inter;
 3179|  7.18k|}
roaring_bitmap_xor_cardinality:
 3182|  7.18k|                                        const roaring_bitmap_t *x2) {
 3183|  7.18k|    const uint64_t c1 = roaring_bitmap_get_cardinality(x1);
 3184|  7.18k|    const uint64_t c2 = roaring_bitmap_get_cardinality(x2);
 3185|  7.18k|    const uint64_t inter = roaring_bitmap_and_cardinality(x1, x2);
 3186|  7.18k|    return c1 + c2 - 2 * inter;
 3187|  7.18k|}
roaring_bitmap_contains_range:
 3194|  7.18k|                                   uint64_t range_start, uint64_t range_end) {
 3195|  7.18k|    if (range_start >= range_end || range_start > (uint64_t)UINT32_MAX + 1) {
  ------------------
  |  Branch (3195:9): [True: 6.40k, False: 783]
  |  Branch (3195:37): [True: 0, False: 783]
  ------------------
 3196|  6.40k|        return true;
 3197|  6.40k|    }
 3198|    783|    return roaring_bitmap_contains_range_closed(r, (uint32_t)range_start,
 3199|    783|                                                (uint32_t)(range_end - 1));
 3200|  7.18k|}
roaring_bitmap_contains_range_closed:
 3208|    783|                                          uint32_t range_end) {
 3209|    783|    if (range_start > range_end) {
  ------------------
  |  Branch (3209:9): [True: 0, False: 783]
  ------------------
 3210|      0|        return true;
 3211|      0|    }  // empty range are always contained!
 3212|    783|    if (range_end == range_start) {
  ------------------
  |  Branch (3212:9): [True: 56, False: 727]
  ------------------
 3213|     56|        return roaring_bitmap_contains(r, (uint32_t)range_start);
 3214|     56|    }
 3215|    727|    uint16_t hb_rs = (uint16_t)(range_start >> 16);
 3216|    727|    uint16_t hb_re = (uint16_t)(range_end >> 16);
 3217|    727|    const int32_t span = hb_re - hb_rs;
 3218|    727|    const int32_t hlc_sz = ra_get_size(&r->high_low_container);
 3219|    727|    if (hlc_sz < span + 1) {
  ------------------
  |  Branch (3219:9): [True: 243, False: 484]
  ------------------
 3220|    243|        return false;
 3221|    243|    }
 3222|    484|    int32_t is = ra_get_index(&r->high_low_container, hb_rs);
 3223|    484|    int32_t ie = ra_get_index(&r->high_low_container, hb_re);
 3224|    484|    if ((ie < 0) || (is < 0) || ((ie - is) != span) || ie >= hlc_sz) {
  ------------------
  |  Branch (3224:9): [True: 49, False: 435]
  |  Branch (3224:21): [True: 16, False: 419]
  |  Branch (3224:33): [True: 8, False: 411]
  |  Branch (3224:56): [True: 0, False: 411]
  ------------------
 3225|     73|        return false;
 3226|     73|    }
 3227|    411|    const uint32_t lb_rs = range_start & 0xFFFF;
 3228|    411|    const uint32_t lb_re = (range_end & 0xFFFF) + 1;
 3229|    411|    uint8_t type;
 3230|    411|    container_t *c =
 3231|    411|        ra_get_container_at_index(&r->high_low_container, (uint16_t)is, &type);
 3232|    411|    if (hb_rs == hb_re) {
  ------------------
  |  Branch (3232:9): [True: 354, False: 57]
  ------------------
 3233|    354|        return container_contains_range(c, lb_rs, lb_re, type);
 3234|    354|    }
 3235|     57|    if (!container_contains_range(c, lb_rs, 1 << 16, type)) {
  ------------------
  |  Branch (3235:9): [True: 14, False: 43]
  ------------------
 3236|     14|        return false;
 3237|     14|    }
 3238|     43|    c = ra_get_container_at_index(&r->high_low_container, (uint16_t)ie, &type);
 3239|     43|    if (!container_contains_range(c, 0, lb_re, type)) {
  ------------------
  |  Branch (3239:9): [True: 8, False: 35]
  ------------------
 3240|      8|        return false;
 3241|      8|    }
 3242|    662|    for (int32_t i = is + 1; i < ie; ++i) {
  ------------------
  |  Branch (3242:30): [True: 639, False: 23]
  ------------------
 3243|    639|        c = ra_get_container_at_index(&r->high_low_container, (uint16_t)i,
 3244|    639|                                      &type);
 3245|    639|        if (!container_is_full(c, type)) {
  ------------------
  |  Branch (3245:13): [True: 12, False: 627]
  ------------------
 3246|     12|            return false;
 3247|     12|        }
 3248|    639|    }
 3249|     23|    return true;
 3250|     35|}
roaring_bitmap_is_strict_subset:
 3253|  7.18k|                                     const roaring_bitmap_t *r2) {
 3254|  7.18k|    return (roaring_bitmap_get_cardinality(r2) >
  ------------------
  |  Branch (3254:13): [True: 5.50k, False: 1.68k]
  ------------------
 3255|  7.18k|                roaring_bitmap_get_cardinality(r1) &&
 3256|  5.50k|            roaring_bitmap_is_subset(r1, r2));
  ------------------
  |  Branch (3256:13): [True: 242, False: 5.26k]
  ------------------
 3257|  7.18k|}
roaring.c:containerptr_roaring_bitmap_add:
   56|  21.5k|                                                           int *index) {
   57|  21.5k|    roaring_array_t *ra = &r->high_low_container;
   58|       |
   59|  21.5k|    uint16_t hb = val >> 16;
   60|  21.5k|    const int i = ra_get_index(ra, hb);
   61|  21.5k|    if (i >= 0) {
  ------------------
  |  Branch (61:9): [True: 7.18k, False: 14.3k]
  ------------------
   62|  7.18k|        ra_unshare_container_at_index(ra, (uint16_t)i);
   63|  7.18k|        container_t *c = ra_get_container_at_index(ra, (uint16_t)i, type);
   64|  7.18k|        uint8_t new_type = *type;
   65|  7.18k|        container_t *c2 = container_add(c, val & 0xFFFF, *type, &new_type);
   66|  7.18k|        *index = i;
   67|  7.18k|        if (c2 != c) {
  ------------------
  |  Branch (67:13): [True: 5, False: 7.18k]
  ------------------
   68|      5|            container_free(c, *type);
   69|      5|            ra_set_container_at_index(ra, i, c2, new_type);
   70|      5|            *type = new_type;
   71|      5|            return c2;
   72|  7.18k|        } else {
   73|  7.18k|            return c;
   74|  7.18k|        }
   75|  14.3k|    } else {
   76|  14.3k|        array_container_t *new_ac = array_container_create();
   77|  14.3k|        container_t *c =
   78|  14.3k|            container_add(new_ac, val & 0xFFFF, ARRAY_CONTAINER_TYPE, type);
  ------------------
  |  |   49|  14.3k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
   79|       |        // we could just assume that it stays an array container
   80|  14.3k|        ra_insert_new_key_value_at(ra, -i - 1, hb, c, *type);
   81|  14.3k|        *index = -i - 1;
   82|  14.3k|        return c;
   83|  14.3k|    }
   84|  21.5k|}
roaring.c:add_bulk_impl:
  106|  8.98M|                                 uint32_t val) {
  107|  8.98M|    uint16_t key = val >> 16;
  108|  8.98M|    if (context->container == NULL || context->key != key) {
  ------------------
  |  Branch (108:9): [True: 0, False: 8.98M]
  |  Branch (108:39): [True: 0, False: 8.98M]
  ------------------
  109|      0|        uint8_t typecode;
  110|      0|        int idx;
  111|      0|        context->container =
  112|      0|            containerptr_roaring_bitmap_add(r, val, &typecode, &idx);
  113|      0|        context->typecode = typecode;
  114|      0|        context->idx = idx;
  115|      0|        context->key = key;
  116|  8.98M|    } else {
  117|       |        // no need to seek the container, it is at hand
  118|       |        // because we already have the container at hand, we can do the
  119|       |        // insertion directly, bypassing the roaring_bitmap_add call
  120|  8.98M|        uint8_t new_typecode;
  121|  8.98M|        container_t *container2 = container_add(
  122|  8.98M|            context->container, val & 0xFFFF, context->typecode, &new_typecode);
  123|  8.98M|        if (container2 != context->container) {
  ------------------
  |  Branch (123:13): [True: 157, False: 8.98M]
  ------------------
  124|       |            // rare instance when we need to change the container type
  125|    157|            container_free(context->container, context->typecode);
  126|    157|            ra_set_container_at_index(&r->high_low_container, context->idx,
  127|    157|                                      container2, new_typecode);
  128|    157|            context->typecode = new_typecode;
  129|    157|            context->container = container2;
  130|    157|        }
  131|  8.98M|    }
  132|  8.98M|}
roaring.c:is_cow:
   41|   122k|static inline bool is_cow(const roaring_bitmap_t *r) {
   42|       |    return r->high_low_container.flags & ROARING_FLAG_COW;
  ------------------
  |  |   46|   122k|#define ROARING_FLAG_COW UINT8_C(0x1)
  ------------------
   43|   122k|}
roaring.c:roaring_inplace_merge_bulk:
  962|  2.30k|                                       int left, int right, bool is_xor) {
  963|  2.30k|    roaring_array_t *ra1 = &x1->high_low_container;
  964|  2.30k|    const roaring_array_t *ra2 = &x2->high_low_container;
  965|  2.30k|    const bool cow2 = is_cow(x2);
  966|  2.30k|    const int length1 = ra1->size;
  967|  2.30k|    const int length2 = ra2->size;
  968|       |
  969|  2.30k|    int distinct = 0;
  970|  2.30k|    {
  971|  2.30k|        int l = left, r = right;
  972|  55.4k|        while (l < length1 && r < length2) {
  ------------------
  |  Branch (972:16): [True: 53.1k, False: 2.30k]
  |  Branch (972:31): [True: 53.1k, False: 0]
  ------------------
  973|  53.1k|            uint16_t k1 = ra1->keys[l];
  974|  53.1k|            uint16_t k2 = ra2->keys[r];
  975|  53.1k|            if (k1 < k2) {
  ------------------
  |  Branch (975:17): [True: 0, False: 53.1k]
  ------------------
  976|      0|                l++;
  977|  53.1k|            } else if (k1 > k2) {
  ------------------
  |  Branch (977:24): [True: 78, False: 53.0k]
  ------------------
  978|     78|                r++;
  979|  53.0k|            } else {
  980|  53.0k|                l++;
  981|  53.0k|                r++;
  982|  53.0k|            }
  983|  53.1k|            distinct++;
  984|  53.1k|        }
  985|  2.30k|        distinct += (length1 - l) + (length2 - r);
  986|  2.30k|    }
  987|  2.30k|    const int total = dst + distinct;
  988|       |
  989|  2.30k|    roaring_array_t merged;
  990|  2.30k|    ra_init_with_capacity(&merged, total > 0 ? (uint32_t)total : 1);
  ------------------
  |  Branch (990:36): [True: 2.18k, False: 114]
  ------------------
  991|       |
  992|  4.29k|    for (int i = 0; i < dst; i++) {
  ------------------
  |  Branch (992:21): [True: 1.99k, False: 2.30k]
  ------------------
  993|  1.99k|        ra_append(&merged, ra1->keys[i], ra1->containers[i], ra1->typecodes[i]);
  994|  1.99k|    }
  995|       |
  996|  2.30k|    uint8_t result_type = 0;
  997|  55.4k|    while (left < length1 && right < length2) {
  ------------------
  |  Branch (997:12): [True: 53.1k, False: 2.30k]
  |  Branch (997:30): [True: 53.1k, False: 0]
  ------------------
  998|  53.1k|        uint16_t k1 = ra1->keys[left];
  999|  53.1k|        uint16_t k2 = ra2->keys[right];
 1000|  53.1k|        if (k1 < k2) {
  ------------------
  |  Branch (1000:13): [True: 0, False: 53.1k]
  ------------------
 1001|      0|            ra_append(&merged, k1, ra1->containers[left], ra1->typecodes[left]);
 1002|      0|            left++;
 1003|  53.1k|        } else if (k1 > k2) {
  ------------------
  |  Branch (1003:20): [True: 78, False: 53.0k]
  ------------------
 1004|     78|            uint8_t type2 = ra2->typecodes[right];
 1005|     78|            container_t *c2 =
 1006|     78|                get_copy_of_container(ra2->containers[right], &type2, cow2);
 1007|     78|            if (cow2) {
  ------------------
  |  Branch (1007:17): [True: 0, False: 78]
  ------------------
 1008|      0|                ra_set_container_at_index(ra2, right, c2, type2);
 1009|      0|            }
 1010|     78|            ra_append(&merged, k2, c2, type2);
 1011|     78|            right++;
 1012|  53.0k|        } else {
 1013|  53.0k|            uint8_t type1 = ra1->typecodes[left];
 1014|  53.0k|            container_t *c1 = ra1->containers[left];
 1015|  53.0k|            uint8_t type2 = ra2->typecodes[right];
 1016|  53.0k|            container_t *c2 = ra2->containers[right];
 1017|  53.0k|            if (is_xor) {
  ------------------
  |  Branch (1017:17): [True: 53.0k, False: 0]
  ------------------
 1018|  53.0k|                container_t *c;
 1019|  53.0k|                if (type1 == SHARED_CONTAINER_TYPE) {
  ------------------
  |  |   51|  53.0k|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (1019:21): [True: 0, False: 53.0k]
  ------------------
 1020|      0|                    c = container_xor(c1, type1, c2, type2, &result_type);
 1021|      0|                    shared_container_free(CAST_shared(c1));
  ------------------
  |  |   79|      0|#define CAST_shared(c) CAST(shared_container_t *, c)  // safer downcast
  |  |  ------------------
  |  |  |  |   86|      0|#define CAST(type, value) ((type)value)
  |  |  ------------------
  ------------------
 1022|  53.0k|                } else {
 1023|  53.0k|                    c = container_ixor(c1, type1, c2, type2, &result_type);
 1024|  53.0k|                }
 1025|  53.0k|                if (container_nonzero_cardinality(c, result_type)) {
  ------------------
  |  Branch (1025:21): [True: 0, False: 53.0k]
  ------------------
 1026|      0|                    ra_append(&merged, k1, c, result_type);
 1027|  53.0k|                } else {
 1028|  53.0k|                    container_free(c, result_type);
 1029|  53.0k|                }
 1030|  53.0k|            } else {
 1031|      0|                if (container_is_full(c1, type1)) {
  ------------------
  |  Branch (1031:21): [True: 0, False: 0]
  ------------------
 1032|      0|                    ra_append(&merged, k1, c1, type1);
 1033|      0|                } else {
 1034|      0|                    container_t *c =
 1035|      0|                        (type1 == SHARED_CONTAINER_TYPE)
  ------------------
  |  |   51|      0|#define SHARED_CONTAINER_TYPE 4
  ------------------
  |  Branch (1035:25): [True: 0, False: 0]
  ------------------
 1036|      0|                            ? container_or(c1, type1, c2, type2, &result_type)
 1037|      0|                            : container_ior(c1, type1, c2, type2, &result_type);
 1038|      0|                    if (c != c1) {
  ------------------
  |  Branch (1038:25): [True: 0, False: 0]
  ------------------
 1039|      0|                        container_free(c1, type1);
 1040|      0|                    }
 1041|      0|                    ra_append(&merged, k1, c, result_type);
 1042|      0|                }
 1043|      0|            }
 1044|  53.0k|            left++;
 1045|  53.0k|            right++;
 1046|  53.0k|        }
 1047|  53.1k|    }
 1048|  2.30k|    for (; left < length1; left++) {
  ------------------
  |  Branch (1048:12): [True: 0, False: 2.30k]
  ------------------
 1049|      0|        ra_append(&merged, ra1->keys[left], ra1->containers[left],
 1050|      0|                  ra1->typecodes[left]);
 1051|      0|    }
 1052|  2.30k|    for (; right < length2; right++) {
  ------------------
  |  Branch (1052:12): [True: 0, False: 2.30k]
  ------------------
 1053|      0|        uint8_t type2 = ra2->typecodes[right];
 1054|      0|        container_t *c2 =
 1055|      0|            get_copy_of_container(ra2->containers[right], &type2, cow2);
 1056|      0|        if (cow2) {
  ------------------
  |  Branch (1056:13): [True: 0, False: 0]
  ------------------
 1057|      0|            ra_set_container_at_index(ra2, right, c2, type2);
 1058|      0|        }
 1059|      0|        ra_append(&merged, ra2->keys[right], c2, type2);
 1060|      0|    }
 1061|       |
 1062|  2.30k|    merged.flags = ra1->flags;
 1063|  2.30k|    ra_clear_without_containers(ra1);
 1064|  2.30k|    *ra1 = merged;
 1065|  2.30k|}
roaring.c:loadfirstvalue:
 1889|  21.4k|    roaring_uint32_iterator_t *newit) {
 1890|  21.4k|    if (iter_new_container_partial_init(newit)) {
  ------------------
  |  Branch (1890:9): [True: 14.1k, False: 7.23k]
  ------------------
 1891|  14.1k|        uint16_t value = 0;
 1892|  14.1k|        newit->container_it =
 1893|  14.1k|            container_init_iterator(newit->container, newit->typecode, &value);
 1894|  14.1k|        newit->current_value = newit->highbits | value;
 1895|  14.1k|    }
 1896|  21.4k|    return newit->has_value;
 1897|  21.4k|}
roaring.c:iter_new_container_partial_init:
 1859|  28.5k|    roaring_uint32_iterator_t *newit) {
 1860|  28.5k|    newit->current_value = 0;
 1861|  28.5k|    if (newit->container_index >= newit->parent->high_low_container.size ||
  ------------------
  |  Branch (1861:9): [True: 7.23k, False: 21.2k]
  ------------------
 1862|  21.2k|        newit->container_index < 0) {
  ------------------
  |  Branch (1862:9): [True: 0, False: 21.2k]
  ------------------
 1863|  7.23k|        newit->current_value = UINT32_MAX;
 1864|  7.23k|        return (newit->has_value = false);
 1865|  7.23k|    }
 1866|  21.2k|    newit->has_value = true;
 1867|       |    // we precompute container, typecode and highbits so that successive
 1868|       |    // iterators do not have to grab them from odd memory locations
 1869|       |    // and have to worry about the (easily predicted) container_unwrap_shared
 1870|       |    // call.
 1871|  21.2k|    newit->container =
 1872|  21.2k|        newit->parent->high_low_container.containers[newit->container_index];
 1873|  21.2k|    newit->typecode =
 1874|  21.2k|        newit->parent->high_low_container.typecodes[newit->container_index];
 1875|  21.2k|    newit->highbits =
 1876|  21.2k|        ((uint32_t)
 1877|  21.2k|             newit->parent->high_low_container.keys[newit->container_index])
 1878|  21.2k|        << 16;
 1879|  21.2k|    newit->container =
 1880|  21.2k|        container_unwrap_shared(newit->container, &(newit->typecode));
 1881|       |    return true;
 1882|  28.5k|}
roaring.c:loadfirstvalue_largeorequal:
 1920|  7.09k|    roaring_uint32_iterator_t *newit, uint32_t val) {
 1921|  7.09k|    bool partial_init = iter_new_container_partial_init(newit);
 1922|  7.09k|    assert(partial_init);
 1923|  7.09k|    if (!partial_init) {
  ------------------
  |  Branch (1923:9): [True: 0, False: 7.09k]
  ------------------
 1924|      0|        return false;
 1925|      0|    }
 1926|  7.09k|    uint16_t value = 0;
 1927|  7.09k|    newit->container_it =
 1928|  7.09k|        container_init_iterator(newit->container, newit->typecode, &value);
 1929|  7.09k|    bool found = container_iterator_lower_bound(
 1930|  7.09k|        newit->container, newit->typecode, &newit->container_it, &value,
 1931|  7.09k|        val & 0xFFFF);
 1932|  7.09k|    assert(found);
 1933|  7.09k|    if (!found) {
  ------------------
  |  Branch (1933:9): [True: 0, False: 7.09k]
  ------------------
 1934|      0|        return false;
 1935|      0|    }
 1936|  7.09k|    newit->current_value = newit->highbits | value;
 1937|       |    return true;
 1938|  7.09k|}
roaring.c:inplace_flip_container:
 2294|  7.93k|                                   uint16_t lb_start, uint16_t lb_end) {
 2295|  7.93k|    const int i = ra_get_index(x1_arr, hb);
 2296|  7.93k|    uint8_t ctype_in, ctype_out;
 2297|  7.93k|    container_t *flipped_container = NULL;
 2298|  7.93k|    if (i >= 0) {
  ------------------
  |  Branch (2298:9): [True: 7.41k, False: 512]
  ------------------
 2299|  7.41k|        container_t *container_to_flip =
 2300|  7.41k|            ra_get_container_at_index(x1_arr, (uint16_t)i, &ctype_in);
 2301|  7.41k|        flipped_container = container_inot_range(
 2302|  7.41k|            container_to_flip, ctype_in, (uint32_t)lb_start,
 2303|  7.41k|            (uint32_t)(lb_end + 1), &ctype_out);
 2304|       |        // if a new container was created, the old one was already freed
 2305|  7.41k|        if (container_nonzero_cardinality(flipped_container, ctype_out)) {
  ------------------
  |  Branch (2305:13): [True: 7.39k, False: 20]
  ------------------
 2306|  7.39k|            ra_set_container_at_index(x1_arr, i, flipped_container, ctype_out);
 2307|  7.39k|        } else {
 2308|     20|            container_free(flipped_container, ctype_out);
 2309|     20|            ra_remove_at_index(x1_arr, i);
 2310|     20|        }
 2311|       |
 2312|  7.41k|    } else {
 2313|    512|        flipped_container = container_range_of_ones(
 2314|    512|            (uint32_t)lb_start, (uint32_t)(lb_end + 1), &ctype_out);
 2315|    512|        ra_insert_new_key_value_at(x1_arr, -i - 1, hb, flipped_container,
 2316|    512|                                   ctype_out);
 2317|    512|    }
 2318|  7.93k|}
roaring.c:inplace_fully_flip_container:
 2345|  24.1k|static void inplace_fully_flip_container(roaring_array_t *x1_arr, uint16_t hb) {
 2346|  24.1k|    const int i = ra_get_index(x1_arr, hb);
 2347|  24.1k|    uint8_t ctype_in, ctype_out;
 2348|  24.1k|    container_t *flipped_container = NULL;
 2349|  24.1k|    if (i >= 0) {
  ------------------
  |  Branch (2349:9): [True: 6.64k, False: 17.4k]
  ------------------
 2350|  6.64k|        container_t *container_to_flip =
 2351|  6.64k|            ra_get_container_at_index(x1_arr, (uint16_t)i, &ctype_in);
 2352|  6.64k|        flipped_container =
 2353|  6.64k|            container_inot(container_to_flip, ctype_in, &ctype_out);
 2354|       |
 2355|  6.64k|        if (container_nonzero_cardinality(flipped_container, ctype_out)) {
  ------------------
  |  Branch (2355:13): [True: 515, False: 6.13k]
  ------------------
 2356|    515|            ra_set_container_at_index(x1_arr, i, flipped_container, ctype_out);
 2357|  6.13k|        } else {
 2358|  6.13k|            container_free(flipped_container, ctype_out);
 2359|  6.13k|            ra_remove_at_index(x1_arr, i);
 2360|  6.13k|        }
 2361|       |
 2362|  17.4k|    } else {
 2363|  17.4k|        flipped_container = container_range_of_ones(0U, 0x10000U, &ctype_out);
 2364|  17.4k|        ra_insert_new_key_value_at(x1_arr, -i - 1, hb, flipped_container,
 2365|  17.4k|                                   ctype_out);
 2366|  17.4k|    }
 2367|  24.1k|}

ra_init_with_capacity:
   80|  74.2k|bool ra_init_with_capacity(roaring_array_t *new_ra, uint32_t cap) {
   81|  74.2k|    if (!new_ra) return false;
  ------------------
  |  Branch (81:9): [True: 0, False: 74.2k]
  ------------------
   82|  74.2k|    ra_init(new_ra);
   83|       |
   84|       |    // Containers hold 64Ki elements, so 64Ki containers is enough to hold
   85|       |    // `0x10000 * 0x10000` (all 2^32) elements
   86|  74.2k|    if (cap > 0x10000) {
  ------------------
  |  Branch (86:9): [True: 0, False: 74.2k]
  ------------------
   87|      0|        cap = 0x10000;
   88|      0|    }
   89|       |
   90|  74.2k|    if (cap > 0) {
  ------------------
  |  Branch (90:9): [True: 38.2k, False: 35.9k]
  ------------------
   91|  38.2k|        void *bigalloc = roaring_malloc(
   92|  38.2k|            cap * (sizeof(uint16_t) + sizeof(container_t *) + sizeof(uint8_t)));
   93|  38.2k|        if (bigalloc == NULL) return false;
  ------------------
  |  Branch (93:13): [True: 0, False: 38.2k]
  ------------------
   94|  38.2k|        new_ra->containers = (container_t **)bigalloc;
   95|  38.2k|        new_ra->keys = (uint16_t *)(new_ra->containers + cap);
   96|  38.2k|        new_ra->typecodes = (uint8_t *)(new_ra->keys + cap);
   97|       |        // Narrowing is safe because of above check
   98|  38.2k|        new_ra->allocation_size = (int32_t)cap;
   99|  38.2k|    }
  100|  74.2k|    return true;
  101|  74.2k|}
ra_shrink_to_fit:
  103|  79.0k|int ra_shrink_to_fit(roaring_array_t *ra) {
  104|  79.0k|    int savings = (ra->allocation_size - ra->size) *
  105|  79.0k|                  (sizeof(uint16_t) + sizeof(container_t *) + sizeof(uint8_t));
  106|  79.0k|    if (!realloc_array(ra, ra->size)) {
  ------------------
  |  Branch (106:9): [True: 0, False: 79.0k]
  ------------------
  107|      0|        return 0;
  108|      0|    }
  109|  79.0k|    ra->allocation_size = ra->size;
  110|  79.0k|    return savings;
  111|  79.0k|}
ra_init:
  113|  74.2k|void ra_init(roaring_array_t *new_ra) {
  114|  74.2k|    if (!new_ra) {
  ------------------
  |  Branch (114:9): [True: 0, False: 74.2k]
  ------------------
  115|      0|        return;
  116|      0|    }
  117|  74.2k|    new_ra->keys = NULL;
  118|  74.2k|    new_ra->containers = NULL;
  119|  74.2k|    new_ra->typecodes = NULL;
  120|       |
  121|  74.2k|    new_ra->allocation_size = 0;
  122|  74.2k|    new_ra->size = 0;
  123|  74.2k|    new_ra->flags = 0;
  124|  74.2k|}
ra_overwrite:
  127|  16.4k|                  bool copy_on_write) {
  128|  16.4k|    ra_clear_containers(dest);  // we are going to overwrite them
  129|  16.4k|    if (source->size == 0) {    // Note: can't call memcpy(NULL), even w/size
  ------------------
  |  Branch (129:9): [True: 16, False: 16.4k]
  ------------------
  130|     16|        dest->size = 0;         // <--- This is important.
  131|     16|        return true;            // output was just cleared, so they match
  132|     16|    }
  133|  16.4k|    if (dest->allocation_size < source->size) {
  ------------------
  |  Branch (133:9): [True: 14.3k, False: 2.05k]
  ------------------
  134|  14.3k|        if (!realloc_array(dest, source->size)) {
  ------------------
  |  Branch (134:13): [True: 0, False: 14.3k]
  ------------------
  135|      0|            return false;
  136|      0|        }
  137|  14.3k|    }
  138|  16.4k|    dest->size = source->size;
  139|  16.4k|    memcpy(dest->keys, source->keys, dest->size * sizeof(uint16_t));
  140|       |    // we go through the containers, turning them into shared containers...
  141|  16.4k|    if (copy_on_write) {
  ------------------
  |  Branch (141:9): [True: 0, False: 16.4k]
  ------------------
  142|      0|        for (int32_t i = 0; i < dest->size; ++i) {
  ------------------
  |  Branch (142:29): [True: 0, False: 0]
  ------------------
  143|      0|            source->containers[i] = get_copy_of_container(
  144|      0|                source->containers[i], &source->typecodes[i], copy_on_write);
  145|      0|        }
  146|       |        // we do a shallow copy to the other bitmap
  147|      0|        memcpy(dest->containers, source->containers,
  148|      0|               dest->size * sizeof(container_t *));
  149|      0|        memcpy(dest->typecodes, source->typecodes,
  150|      0|               dest->size * sizeof(uint8_t));
  151|  16.4k|    } else {
  152|  16.4k|        memcpy(dest->typecodes, source->typecodes,
  153|  16.4k|               dest->size * sizeof(uint8_t));
  154|   166k|        for (int32_t i = 0; i < dest->size; i++) {
  ------------------
  |  Branch (154:29): [True: 149k, False: 16.4k]
  ------------------
  155|   149k|            dest->containers[i] =
  156|   149k|                container_clone(source->containers[i], source->typecodes[i]);
  157|   149k|            if (dest->containers[i] == NULL) {
  ------------------
  |  Branch (157:17): [True: 0, False: 149k]
  ------------------
  158|      0|                for (int32_t j = 0; j < i; j++) {
  ------------------
  |  Branch (158:37): [True: 0, False: 0]
  ------------------
  159|      0|                    container_free(dest->containers[j], dest->typecodes[j]);
  160|      0|                }
  161|      0|                ra_clear_without_containers(dest);
  162|      0|                return false;
  163|      0|            }
  164|   149k|        }
  165|  16.4k|    }
  166|  16.4k|    return true;
  167|  16.4k|}
ra_clear_containers:
  169|  88.3k|void ra_clear_containers(roaring_array_t *ra) {
  170|   529k|    for (int32_t i = 0; i < ra->size; ++i) {
  ------------------
  |  Branch (170:25): [True: 441k, False: 88.3k]
  ------------------
  171|   441k|        container_free(ra->containers[i], ra->typecodes[i]);
  172|   441k|    }
  173|  88.3k|}
ra_reset:
  175|  71.8k|void ra_reset(roaring_array_t *ra) {
  176|  71.8k|    ra_clear_containers(ra);
  177|  71.8k|    ra->size = 0;
  178|  71.8k|    ra_shrink_to_fit(ra);
  179|  71.8k|}
ra_clear_without_containers:
  181|  2.36k|void ra_clear_without_containers(roaring_array_t *ra) {
  182|  2.36k|    roaring_free(
  183|  2.36k|        ra->containers);  // keys and typecodes are allocated with containers
  184|  2.36k|    ra->size = 0;
  185|  2.36k|    ra->allocation_size = 0;
  186|  2.36k|    ra->containers = NULL;
  187|  2.36k|    ra->keys = NULL;
  188|       |    ra->typecodes = NULL;
  189|  2.36k|}
ra_clear:
  191|     67|void ra_clear(roaring_array_t *ra) {
  192|     67|    ra_clear_containers(ra);
  193|     67|    ra_clear_without_containers(ra);
  194|     67|}
extend_array:
  196|  96.0k|bool extend_array(roaring_array_t *ra, int32_t k) {
  197|  96.0k|    int32_t desired_size = ra->size + k;
  198|  96.0k|    const int32_t max_containers = 65536;
  199|  96.0k|    assert(desired_size <= max_containers);
  200|  96.0k|    if (desired_size > ra->allocation_size) {
  ------------------
  |  Branch (200:9): [True: 19.3k, False: 76.7k]
  ------------------
  201|  19.3k|        int32_t new_capacity =
  202|  19.3k|            (ra->size < 1024) ? 2 * desired_size : 5 * desired_size / 4;
  ------------------
  |  Branch (202:13): [True: 19.3k, False: 0]
  ------------------
  203|  19.3k|        if (new_capacity > max_containers) {
  ------------------
  |  Branch (203:13): [True: 0, False: 19.3k]
  ------------------
  204|      0|            new_capacity = max_containers;
  205|      0|        }
  206|       |
  207|  19.3k|        return realloc_array(ra, new_capacity);
  208|  19.3k|    }
  209|  76.7k|    return true;
  210|  96.0k|}
ra_append:
  213|  29.9k|               uint8_t typecode) {
  214|  29.9k|    extend_array(ra, 1);
  215|  29.9k|    const int32_t pos = ra->size;
  216|       |
  217|  29.9k|    ra->keys[pos] = key;
  218|  29.9k|    ra->containers[pos] = c;
  219|  29.9k|    ra->typecodes[pos] = typecode;
  220|  29.9k|    ra->size++;
  221|  29.9k|}
ra_append_copy_range:
  254|  29.4k|                          bool copy_on_write) {
  255|  29.4k|    extend_array(ra, end_index - start_index);
  256|   194k|    for (int32_t i = start_index; i < end_index; ++i) {
  ------------------
  |  Branch (256:35): [True: 165k, False: 29.4k]
  ------------------
  257|   165k|        const int32_t pos = ra->size;
  258|   165k|        ra->keys[pos] = sa->keys[i];
  259|   165k|        if (copy_on_write) {
  ------------------
  |  Branch (259:13): [True: 0, False: 165k]
  ------------------
  260|      0|            sa->containers[i] = get_copy_of_container(
  261|      0|                sa->containers[i], &sa->typecodes[i], copy_on_write);
  262|      0|            ra->containers[pos] = sa->containers[i];
  263|      0|            ra->typecodes[pos] = sa->typecodes[i];
  264|   165k|        } else {
  265|   165k|            ra->containers[pos] =
  266|   165k|                container_clone(sa->containers[i], sa->typecodes[i]);
  267|   165k|            ra->typecodes[pos] = sa->typecodes[i];
  268|   165k|        }
  269|   165k|        ra->size++;
  270|   165k|    }
  271|  29.4k|}
ra_advance_until_freeing:
  340|     57|int32_t ra_advance_until_freeing(roaring_array_t *ra, uint16_t x, int32_t pos) {
  341|    114|    while (pos < ra->size && ra->keys[pos] < x) {
  ------------------
  |  Branch (341:12): [True: 114, False: 0]
  |  Branch (341:30): [True: 57, False: 57]
  ------------------
  342|     57|        container_free(ra->containers[pos], ra->typecodes[pos]);
  343|     57|        ++pos;
  344|     57|    }
  345|     57|    return pos;
  346|     57|}
ra_insert_new_key_value_at:
  349|  35.3k|                                container_t *c, uint8_t typecode) {
  350|  35.3k|    extend_array(ra, 1);
  351|       |    // May be an optimization opportunity with DIY memmove
  352|  35.3k|    memmove(&(ra->keys[i + 1]), &(ra->keys[i]),
  353|  35.3k|            sizeof(uint16_t) * (ra->size - i));
  354|  35.3k|    memmove(&(ra->containers[i + 1]), &(ra->containers[i]),
  355|  35.3k|            sizeof(container_t *) * (ra->size - i));
  356|  35.3k|    memmove(&(ra->typecodes[i + 1]), &(ra->typecodes[i]),
  357|  35.3k|            sizeof(uint8_t) * (ra->size - i));
  358|  35.3k|    ra->keys[i] = key;
  359|  35.3k|    ra->containers[i] = c;
  360|  35.3k|    ra->typecodes[i] = typecode;
  361|  35.3k|    ra->size++;
  362|  35.3k|}
ra_downsize:
  369|  13.9k|void ra_downsize(roaring_array_t *ra, int32_t new_length) {
  370|       |    assert(new_length <= ra->size);
  371|  13.9k|    ra->size = new_length;
  372|  13.9k|}
ra_remove_at_index:
  374|  6.21k|void ra_remove_at_index(roaring_array_t *ra, int32_t i) {
  375|  6.21k|    memmove(&(ra->containers[i]), &(ra->containers[i + 1]),
  376|  6.21k|            sizeof(container_t *) * (ra->size - i - 1));
  377|  6.21k|    memmove(&(ra->keys[i]), &(ra->keys[i + 1]),
  378|  6.21k|            sizeof(uint16_t) * (ra->size - i - 1));
  379|  6.21k|    memmove(&(ra->typecodes[i]), &(ra->typecodes[i + 1]),
  380|  6.21k|            sizeof(uint8_t) * (ra->size - i - 1));
  381|  6.21k|    ra->size--;
  382|  6.21k|}
ra_remove_at_index_and_free:
  384|     60|void ra_remove_at_index_and_free(roaring_array_t *ra, int32_t i) {
  385|     60|    container_free(ra->containers[i], ra->typecodes[i]);
  386|     60|    ra_remove_at_index(ra, i);
  387|     60|}
ra_copy_range:
  395|     24|                   uint32_t new_begin) {
  396|     24|    assert(begin <= end);
  397|     24|    assert(new_begin < begin);
  398|       |
  399|     24|    const int range = end - begin;
  400|       |
  401|       |    // We ensure to previously have freed overwritten containers
  402|       |    // that are not copied elsewhere
  403|       |
  404|     24|    memmove(&(ra->containers[new_begin]), &(ra->containers[begin]),
  405|     24|            sizeof(container_t *) * range);
  406|     24|    memmove(&(ra->keys[new_begin]), &(ra->keys[begin]),
  407|     24|            sizeof(uint16_t) * range);
  408|     24|    memmove(&(ra->typecodes[new_begin]), &(ra->typecodes[begin]),
  409|     24|            sizeof(uint8_t) * range);
  410|     24|}
ra_shift_tail:
  412|  1.87k|void ra_shift_tail(roaring_array_t *ra, int32_t count, int32_t distance) {
  413|  1.87k|    if (distance > 0) {
  ------------------
  |  Branch (413:9): [True: 1.23k, False: 643]
  ------------------
  414|  1.23k|        extend_array(ra, distance);
  415|  1.23k|    }
  416|  1.87k|    int32_t srcpos = ra->size - count;
  417|  1.87k|    int32_t dstpos = srcpos + distance;
  418|  1.87k|    memmove(&(ra->keys[dstpos]), &(ra->keys[srcpos]), sizeof(uint16_t) * count);
  419|  1.87k|    memmove(&(ra->containers[dstpos]), &(ra->containers[srcpos]),
  420|  1.87k|            sizeof(container_t *) * count);
  421|  1.87k|    memmove(&(ra->typecodes[dstpos]), &(ra->typecodes[srcpos]),
  422|  1.87k|            sizeof(uint8_t) * count);
  423|  1.87k|    ra->size += distance;
  424|  1.87k|}
ra_to_uint32_array:
  426|  7.18k|void ra_to_uint32_array(const roaring_array_t *ra, uint32_t *ans) {
  427|  7.18k|    size_t ctr = 0;
  428|  69.2k|    for (int32_t i = 0; i < ra->size; ++i) {
  ------------------
  |  Branch (428:25): [True: 62.1k, False: 7.18k]
  ------------------
  429|  62.1k|        int num_added = container_to_uint32_array(
  430|  62.1k|            ans + ctr, ra->containers[i], ra->typecodes[i],
  431|  62.1k|            ((uint32_t)ra->keys[i]) << 16);
  432|  62.1k|        ctr += num_added;
  433|  62.1k|    }
  434|  7.18k|}
ra_has_run_container:
  436|  21.5k|bool ra_has_run_container(const roaring_array_t *ra) {
  437|   174k|    for (int32_t k = 0; k < ra->size; ++k) {
  ------------------
  |  Branch (437:25): [True: 155k, False: 19.1k]
  ------------------
  438|   155k|        if (get_container_type(ra->containers[k], ra->typecodes[k]) ==
  ------------------
  |  Branch (438:13): [True: 2.41k, False: 152k]
  ------------------
  439|   155k|            RUN_CONTAINER_TYPE)
  ------------------
  |  |   50|   155k|#define RUN_CONTAINER_TYPE 3
  ------------------
  440|  2.41k|            return true;
  441|   155k|    }
  442|  19.1k|    return false;
  443|  21.5k|}
ra_portable_header_size:
  445|  14.3k|uint32_t ra_portable_header_size(const roaring_array_t *ra) {
  446|  14.3k|    if (ra_has_run_container(ra)) {
  ------------------
  |  Branch (446:9): [True: 2.41k, False: 11.9k]
  ------------------
  447|  2.41k|        if (ra->size <
  ------------------
  |  Branch (447:13): [True: 2.41k, False: 0]
  ------------------
  448|  2.41k|            NO_OFFSET_THRESHOLD) {  // for small bitmaps, we omit the offsets
  449|  2.41k|            return 4 + (ra->size + 7) / 8 + 4 * ra->size;
  450|  2.41k|        }
  451|      0|        return 4 + (ra->size + 7) / 8 +
  452|      0|               8 * ra->size;  // - 4 because we pack the size with the cookie
  453|  11.9k|    } else {
  454|  11.9k|        return 4 + 4 + 8 * ra->size;
  455|  11.9k|    }
  456|  14.3k|}
ra_portable_size_in_bytes:
  458|  14.3k|size_t ra_portable_size_in_bytes(const roaring_array_t *ra) {
  459|  14.3k|    size_t count = ra_portable_header_size(ra);
  460|       |
  461|  95.5k|    for (int32_t k = 0; k < ra->size; ++k) {
  ------------------
  |  Branch (461:25): [True: 81.1k, False: 14.3k]
  ------------------
  462|  81.1k|        count += container_size_in_bytes(ra->containers[k], ra->typecodes[k]);
  463|  81.1k|    }
  464|  14.3k|    return count;
  465|  14.3k|}
ra_portable_serialize:
  469|  7.18k|size_t ra_portable_serialize(const roaring_array_t *ra, char *buf) {
  470|  7.18k|    char *initbuf = buf;
  471|  7.18k|    uint32_t startOffset = 0;
  472|  7.18k|    bool hasrun = ra_has_run_container(ra);
  473|  7.18k|    if (hasrun) {
  ------------------
  |  Branch (473:9): [True: 0, False: 7.18k]
  ------------------
  474|      0|        uint32_t cookie = SERIAL_COOKIE | ((uint32_t)(ra->size - 1) << 16);
  475|      0|        uint32_t cookie_le = croaring_htole32(cookie);
  ------------------
  |  |  525|      0|#define croaring_htole32(x) (x)
  ------------------
  476|      0|        memcpy(buf, &cookie_le, sizeof(cookie_le));
  477|      0|        buf += sizeof(cookie_le);
  478|      0|        uint32_t s = (ra->size + 7) / 8;
  479|      0|        memset(buf, 0, s);
  480|      0|        for (int32_t i = 0; i < ra->size; ++i) {
  ------------------
  |  Branch (480:29): [True: 0, False: 0]
  ------------------
  481|      0|            if (get_container_type(ra->containers[i], ra->typecodes[i]) ==
  ------------------
  |  Branch (481:17): [True: 0, False: 0]
  ------------------
  482|      0|                RUN_CONTAINER_TYPE) {
  ------------------
  |  |   50|      0|#define RUN_CONTAINER_TYPE 3
  ------------------
  483|      0|                buf[i / 8] |= 1 << (i % 8);
  484|      0|            }
  485|      0|        }
  486|      0|        buf += s;
  487|      0|        if (ra->size < NO_OFFSET_THRESHOLD) {
  ------------------
  |  Branch (487:13): [True: 0, False: 0]
  ------------------
  488|      0|            startOffset = 4 + 4 * ra->size + s;
  489|      0|        } else {
  490|      0|            startOffset = 4 + 8 * ra->size + s;
  491|      0|        }
  492|  7.18k|    } else {  // backwards compatibility
  493|  7.18k|        uint32_t cookie = SERIAL_COOKIE_NO_RUNCONTAINER;
  494|  7.18k|        uint32_t cookie_le = croaring_htole32(cookie);
  ------------------
  |  |  525|  7.18k|#define croaring_htole32(x) (x)
  ------------------
  495|  7.18k|        memcpy(buf, &cookie_le, sizeof(cookie_le));
  496|  7.18k|        buf += sizeof(cookie_le);
  497|  7.18k|        uint32_t size_le = croaring_htole32((uint32_t)ra->size);
  ------------------
  |  |  525|  7.18k|#define croaring_htole32(x) (x)
  ------------------
  498|  7.18k|        memcpy(buf, &size_le, sizeof(size_le));
  499|  7.18k|        buf += sizeof(size_le);
  500|       |
  501|  7.18k|        startOffset = 4 + 4 + 4 * ra->size + 4 * ra->size;
  502|  7.18k|    }
  503|  81.1k|    for (int32_t k = 0; k < ra->size; ++k) {
  ------------------
  |  Branch (503:25): [True: 73.9k, False: 7.18k]
  ------------------
  504|  73.9k|        uint16_t key_le = croaring_htole16(ra->keys[k]);
  ------------------
  |  |  524|  73.9k|#define croaring_htole16(x) (x)
  ------------------
  505|  73.9k|        memcpy(buf, &key_le, sizeof(key_le));
  506|  73.9k|        buf += sizeof(key_le);
  507|       |        // get_cardinality returns a value in [1,1<<16], subtracting one
  508|       |        // we get [0,1<<16 - 1] which fits in 16 bits
  509|  73.9k|        uint16_t card = (uint16_t)(container_get_cardinality(ra->containers[k],
  510|  73.9k|                                                             ra->typecodes[k]) -
  511|  73.9k|                                   1);
  512|  73.9k|        uint16_t card_le = croaring_htole16(card);
  ------------------
  |  |  524|  73.9k|#define croaring_htole16(x) (x)
  ------------------
  513|  73.9k|        memcpy(buf, &card_le, sizeof(card_le));
  514|  73.9k|        buf += sizeof(card_le);
  515|  73.9k|    }
  516|  7.18k|    if ((!hasrun) || (ra->size >= NO_OFFSET_THRESHOLD)) {
  ------------------
  |  Branch (516:9): [True: 7.18k, False: 0]
  |  Branch (516:22): [True: 0, False: 0]
  ------------------
  517|       |        // writing the containers offsets
  518|  81.1k|        for (int32_t k = 0; k < ra->size; k++) {
  ------------------
  |  Branch (518:29): [True: 73.9k, False: 7.18k]
  ------------------
  519|  73.9k|            uint32_t off_le = croaring_htole32(startOffset);
  ------------------
  |  |  525|  73.9k|#define croaring_htole32(x) (x)
  ------------------
  520|  73.9k|            memcpy(buf, &off_le, sizeof(off_le));
  521|  73.9k|            buf += sizeof(off_le);
  522|  73.9k|            startOffset =
  523|  73.9k|                startOffset +
  524|  73.9k|                container_size_in_bytes(ra->containers[k], ra->typecodes[k]);
  525|  73.9k|        }
  526|  7.18k|    }
  527|  81.1k|    for (int32_t k = 0; k < ra->size; ++k) {
  ------------------
  |  Branch (527:25): [True: 73.9k, False: 7.18k]
  ------------------
  528|  73.9k|        buf += container_write(ra->containers[k], ra->typecodes[k], buf);
  529|  73.9k|    }
  530|  7.18k|    return buf - initbuf;
  531|  7.18k|}
ra_portable_deserialize:
  634|  14.3k|                             const size_t maxbytes, size_t *readbytes) {
  635|  14.3k|    *readbytes = sizeof(int32_t);  // for cookie
  636|  14.3k|    if (*readbytes > maxbytes) {
  ------------------
  |  Branch (636:9): [True: 6.82k, False: 7.55k]
  ------------------
  637|       |        // Ran out of bytes while reading first 4 bytes.
  638|  6.82k|        return false;
  639|  6.82k|    }
  640|  7.55k|    uint32_t cookie;
  641|  7.55k|    memcpy(&cookie, buf, sizeof(int32_t));
  642|  7.55k|    cookie = croaring_letoh32(cookie);
  ------------------
  |  |  531|  7.55k|#define croaring_letoh32(x) croaring_htole32(x)
  |  |  ------------------
  |  |  |  |  525|  7.55k|#define croaring_htole32(x) (x)
  |  |  ------------------
  ------------------
  643|  7.55k|    buf += sizeof(uint32_t);
  644|  7.55k|    if ((cookie & 0xFFFF) != SERIAL_COOKIE &&
  ------------------
  |  Branch (644:9): [True: 7.45k, False: 94]
  ------------------
  645|  7.45k|        cookie != SERIAL_COOKIE_NO_RUNCONTAINER) {
  ------------------
  |  Branch (645:9): [True: 226, False: 7.23k]
  ------------------
  646|       |        // "I failed to find one of the right cookies.
  647|    226|        return false;
  648|    226|    }
  649|  7.32k|    int32_t size;
  650|       |
  651|  7.32k|    if ((cookie & 0xFFFF) == SERIAL_COOKIE)
  ------------------
  |  Branch (651:9): [True: 94, False: 7.23k]
  ------------------
  652|     94|        size = (cookie >> 16) + 1;
  653|  7.23k|    else {
  654|  7.23k|        *readbytes += sizeof(int32_t);
  655|  7.23k|        if (*readbytes > maxbytes) {
  ------------------
  |  Branch (655:13): [True: 3, False: 7.22k]
  ------------------
  656|       |            // Ran out of bytes while reading second part of the cookie.
  657|      3|            return false;
  658|      3|        }
  659|  7.22k|        uint32_t size_le;
  660|  7.22k|        memcpy(&size_le, buf, sizeof(int32_t));
  661|  7.22k|        size = (int32_t)croaring_letoh32(size_le);
  ------------------
  |  |  531|  7.22k|#define croaring_letoh32(x) croaring_htole32(x)
  |  |  ------------------
  |  |  |  |  525|  7.22k|#define croaring_htole32(x) (x)
  |  |  ------------------
  ------------------
  662|  7.22k|        buf += sizeof(uint32_t);
  663|  7.22k|    }
  664|  7.32k|    if (size < 0) {
  ------------------
  |  Branch (664:9): [True: 17, False: 7.30k]
  ------------------
  665|       |        // You cannot have a negative number of containers, the data must be
  666|       |        // corrupted.
  667|     17|        return false;
  668|     17|    }
  669|  7.30k|    if (size > (1 << 16)) {
  ------------------
  |  Branch (669:9): [True: 15, False: 7.29k]
  ------------------
  670|       |        // You cannot have so many containers, the data must be corrupted.
  671|     15|        return false;
  672|     15|    }
  673|  7.29k|    const char *bitmapOfRunContainers = NULL;
  674|  7.29k|    bool hasrun = (cookie & 0xFFFF) == SERIAL_COOKIE;
  675|  7.29k|    if (hasrun) {
  ------------------
  |  Branch (675:9): [True: 94, False: 7.19k]
  ------------------
  676|     94|        int32_t s = (size + 7) / 8;
  677|     94|        *readbytes += s;
  678|     94|        if (*readbytes > maxbytes) {  // data is corrupted?
  ------------------
  |  Branch (678:13): [True: 14, False: 80]
  ------------------
  679|       |            // Ran out of bytes while reading run bitmap.
  680|     14|            return false;
  681|     14|        }
  682|     80|        bitmapOfRunContainers = buf;
  683|     80|        buf += s;
  684|     80|    }
  685|  7.27k|    const char *keyscards = buf;
  686|       |
  687|  7.27k|    *readbytes += size * 2 * sizeof(uint16_t);
  688|  7.27k|    if (*readbytes > maxbytes) {
  ------------------
  |  Branch (688:9): [True: 6, False: 7.27k]
  ------------------
  689|       |        // Ran out of bytes while reading key-cardinality array.
  690|      6|        return false;
  691|      6|    }
  692|  7.27k|    buf += size * 2 * sizeof(uint16_t);
  693|       |
  694|  7.27k|    bool is_ok = ra_init_with_capacity(answer, size);
  695|  7.27k|    if (!is_ok) {
  ------------------
  |  Branch (695:9): [True: 0, False: 7.27k]
  ------------------
  696|       |        // Failed to allocate memory for roaring array. Bailing out.
  697|      0|        return false;
  698|      0|    }
  699|       |
  700|  81.4k|    for (int32_t k = 0; k < size; ++k) {
  ------------------
  |  Branch (700:25): [True: 74.2k, False: 7.27k]
  ------------------
  701|  74.2k|        uint16_t tmp;
  702|  74.2k|        memcpy(&tmp, keyscards + 4 * k, sizeof(tmp));
  703|  74.2k|        answer->keys[k] = croaring_letoh16(tmp);
  ------------------
  |  |  530|  74.2k|#define croaring_letoh16(x) croaring_htole16(x)
  |  |  ------------------
  |  |  |  |  524|  74.2k|#define croaring_htole16(x) (x)
  |  |  ------------------
  ------------------
  704|  74.2k|    }
  705|  7.27k|    if ((!hasrun) || (size >= NO_OFFSET_THRESHOLD)) {
  ------------------
  |  Branch (705:9): [True: 7.19k, False: 79]
  |  Branch (705:22): [True: 30, False: 49]
  ------------------
  706|  7.22k|        *readbytes += size * 4;
  707|  7.22k|        if (*readbytes > maxbytes) {  // data is corrupted?
  ------------------
  |  Branch (707:13): [True: 6, False: 7.21k]
  ------------------
  708|       |            // Ran out of bytes while reading offsets.
  709|      6|            ra_clear(answer);  // we need to clear the containers already
  710|       |                               // allocated, and the roaring array
  711|      6|            return false;
  712|      6|        }
  713|       |
  714|       |        // skipping the offsets
  715|  7.21k|        buf += size * 4;
  716|  7.21k|    }
  717|       |    // Reading the containers
  718|  81.3k|    for (int32_t k = 0; k < size; ++k) {
  ------------------
  |  Branch (718:25): [True: 74.1k, False: 7.20k]
  ------------------
  719|  74.1k|        uint16_t tmp;
  720|  74.1k|        memcpy(&tmp, keyscards + 4 * k + 2, sizeof(tmp));
  721|  74.1k|        tmp = croaring_letoh16(tmp);
  ------------------
  |  |  530|  74.1k|#define croaring_letoh16(x) croaring_htole16(x)
  |  |  ------------------
  |  |  |  |  524|  74.1k|#define croaring_htole16(x) (x)
  |  |  ------------------
  ------------------
  722|  74.1k|        uint32_t thiscard = tmp + 1;
  723|  74.1k|        bool isbitmap = (thiscard > DEFAULT_MAX_SIZE);
  724|  74.1k|        bool isrun = false;
  725|  74.1k|        if (hasrun) {
  ------------------
  |  Branch (725:13): [True: 174, False: 73.9k]
  ------------------
  726|    174|            if ((bitmapOfRunContainers[k / 8] & (1 << (k % 8))) != 0) {
  ------------------
  |  Branch (726:17): [True: 112, False: 62]
  ------------------
  727|    112|                isbitmap = false;
  728|    112|                isrun = true;
  729|    112|            }
  730|    174|        }
  731|  74.1k|        if (isbitmap) {
  ------------------
  |  Branch (731:13): [True: 66.3k, False: 7.83k]
  ------------------
  732|       |            // we check that the read is allowed
  733|  66.3k|            size_t containersize =
  734|  66.3k|                BITSET_CONTAINER_SIZE_IN_WORDS * sizeof(uint64_t);
  735|  66.3k|            *readbytes += containersize;
  736|  66.3k|            if (*readbytes > maxbytes) {
  ------------------
  |  Branch (736:17): [True: 7, False: 66.2k]
  ------------------
  737|       |                // Running out of bytes while reading a bitset container.
  738|      7|                ra_clear(answer);  // we need to clear the containers already
  739|       |                                   // allocated, and the roaring array
  740|      7|                return false;
  741|      7|            }
  742|       |            // it is now safe to read
  743|  66.2k|            bitset_container_t *c = bitset_container_create_uninitialized();
  744|  66.2k|            if (c == NULL) {  // memory allocation failure
  ------------------
  |  Branch (744:17): [True: 0, False: 66.2k]
  ------------------
  745|       |                // Failed to allocate memory for a bitset container.
  746|      0|                ra_clear(answer);  // we need to clear the containers already
  747|       |                                   // allocated, and the roaring array
  748|      0|                return false;
  749|      0|            }
  750|  66.2k|            answer->size++;
  751|  66.2k|            buf += bitset_container_read(thiscard, c, buf);
  752|  66.2k|            answer->containers[k] = c;
  753|  66.2k|            answer->typecodes[k] = BITSET_CONTAINER_TYPE;
  ------------------
  |  |   48|  66.2k|#define BITSET_CONTAINER_TYPE 1
  ------------------
  754|  66.2k|        } else if (isrun) {
  ------------------
  |  Branch (754:20): [True: 112, False: 7.72k]
  ------------------
  755|       |            // we check that the read is allowed
  756|    112|            *readbytes += sizeof(uint16_t);
  757|    112|            if (*readbytes > maxbytes) {
  ------------------
  |  Branch (757:17): [True: 8, False: 104]
  ------------------
  758|       |                // Running out of bytes while reading a run container (header).
  759|      8|                ra_clear(answer);  // we need to clear the containers already
  760|       |                                   // allocated, and the roaring array
  761|      8|                return false;
  762|      8|            }
  763|    104|            uint16_t n_runs;
  764|    104|            memcpy(&n_runs, buf, sizeof(uint16_t));
  765|    104|            n_runs = croaring_letoh16(n_runs);
  ------------------
  |  |  530|    104|#define croaring_letoh16(x) croaring_htole16(x)
  |  |  ------------------
  |  |  |  |  524|    104|#define croaring_htole16(x) (x)
  |  |  ------------------
  ------------------
  766|    104|            size_t containersize = n_runs * sizeof(rle16_t);
  767|    104|            *readbytes += containersize;
  768|    104|            if (*readbytes > maxbytes) {  // data is corrupted?
  ------------------
  |  Branch (768:17): [True: 37, False: 67]
  ------------------
  769|       |                // Running out of bytes while reading a run container.
  770|     37|                ra_clear(answer);  // we need to clear the containers already
  771|       |                                   // allocated, and the roaring array
  772|     37|                return false;
  773|     37|            }
  774|       |            // it is now safe to read
  775|       |
  776|     67|            run_container_t *c = run_container_create();
  777|     67|            if (c == NULL) {  // memory allocation failure
  ------------------
  |  Branch (777:17): [True: 0, False: 67]
  ------------------
  778|       |                // Failed to allocate memory for a run container.
  779|      0|                ra_clear(answer);  // we need to clear the containers already
  780|       |                                   // allocated, and the roaring array
  781|      0|                return false;
  782|      0|            }
  783|     67|            answer->size++;
  784|     67|            buf += run_container_read(thiscard, c, buf);
  785|     67|            answer->containers[k] = c;
  786|     67|            answer->typecodes[k] = RUN_CONTAINER_TYPE;
  ------------------
  |  |   50|     67|#define RUN_CONTAINER_TYPE 3
  ------------------
  787|  7.72k|        } else {
  788|       |            // we check that the read is allowed
  789|  7.72k|            size_t containersize = thiscard * sizeof(uint16_t);
  790|  7.72k|            *readbytes += containersize;
  791|  7.72k|            if (*readbytes > maxbytes) {  // data is corrupted?
  ------------------
  |  Branch (791:17): [True: 9, False: 7.71k]
  ------------------
  792|       |                // Running out of bytes while reading an array container.
  793|      9|                ra_clear(answer);  // we need to clear the containers already
  794|       |                                   // allocated, and the roaring array
  795|      9|                return false;
  796|      9|            }
  797|       |            // it is now safe to read
  798|  7.71k|            array_container_t *c =
  799|  7.71k|                array_container_create_given_capacity(thiscard);
  800|  7.71k|            if (c == NULL) {  // memory allocation failure
  ------------------
  |  Branch (800:17): [True: 0, False: 7.71k]
  ------------------
  801|       |                // Failed to allocate memory for an array container.
  802|      0|                ra_clear(answer);  // we need to clear the containers already
  803|       |                                   // allocated, and the roaring array
  804|      0|                return false;
  805|      0|            }
  806|  7.71k|            answer->size++;
  807|  7.71k|            buf += array_container_read(thiscard, c, buf);
  808|  7.71k|            answer->containers[k] = c;
  809|  7.71k|            answer->typecodes[k] = ARRAY_CONTAINER_TYPE;
  ------------------
  |  |   49|  7.71k|#define ARRAY_CONTAINER_TYPE 2
  ------------------
  810|  7.71k|        }
  811|  74.1k|    }
  812|  7.20k|    return true;
  813|  7.26k|}
roaring_array.c:realloc_array:
   42|   112k|static bool realloc_array(roaring_array_t *ra, int32_t new_capacity) {
   43|       |    //
   44|       |    // Note: not implemented using C's realloc(), because the memory layout is
   45|       |    // Struct-of-Arrays vs. Array-of-Structs:
   46|       |    // https://github.com/RoaringBitmap/CRoaring/issues/256
   47|       |
   48|   112k|    if (new_capacity == 0) {
  ------------------
  |  Branch (48:9): [True: 71.8k, False: 40.8k]
  ------------------
   49|  71.8k|        roaring_free(ra->containers);
   50|  71.8k|        ra->containers = NULL;
   51|  71.8k|        ra->keys = NULL;
   52|  71.8k|        ra->typecodes = NULL;
   53|  71.8k|        ra->allocation_size = 0;
   54|  71.8k|        return true;
   55|  71.8k|    }
   56|  40.8k|    const size_t memoryneeded =
   57|  40.8k|        new_capacity *
   58|  40.8k|        (sizeof(uint16_t) + sizeof(container_t *) + sizeof(uint8_t));
   59|  40.8k|    void *bigalloc = roaring_malloc(memoryneeded);
   60|  40.8k|    if (!bigalloc) return false;
  ------------------
  |  Branch (60:9): [True: 0, False: 40.8k]
  ------------------
   61|  40.8k|    void *oldbigalloc = ra->containers;
   62|  40.8k|    container_t **newcontainers = (container_t **)bigalloc;
   63|  40.8k|    uint16_t *newkeys = (uint16_t *)(newcontainers + new_capacity);
   64|  40.8k|    uint8_t *newtypecodes = (uint8_t *)(newkeys + new_capacity);
   65|  40.8k|    assert((char *)(newtypecodes + new_capacity) ==
   66|  40.8k|           (char *)bigalloc + memoryneeded);
   67|  40.8k|    if (ra->size > 0) {
  ------------------
  |  Branch (67:9): [True: 12.1k, False: 28.7k]
  ------------------
   68|  12.1k|        memcpy(newcontainers, ra->containers, sizeof(container_t *) * ra->size);
   69|  12.1k|        memcpy(newkeys, ra->keys, sizeof(uint16_t) * ra->size);
   70|  12.1k|        memcpy(newtypecodes, ra->typecodes, sizeof(uint8_t) * ra->size);
   71|  12.1k|    }
   72|  40.8k|    ra->containers = newcontainers;
   73|  40.8k|    ra->keys = newkeys;
   74|  40.8k|    ra->typecodes = newtypecodes;
   75|  40.8k|    ra->allocation_size = new_capacity;
   76|  40.8k|    roaring_free(oldbigalloc);
   77|       |    return true;
   78|  40.8k|}

_Z17ConsumeVecInRangeR18FuzzedDataProvidermjj:
   24|  14.3k|                                        uint32_t max_value) {
   25|  14.3k|    std::vector<uint32_t> result = {0};
   26|  14.3k|    result.resize(length);
   27|  14.3k|    std::generate(result.begin(), result.end(), [&]() {
   28|  14.3k|        return fdp.ConsumeIntegralInRange<uint32_t>(min_value, max_value);
   29|  14.3k|    });
   30|  14.3k|    return result;
   31|  14.3k|}
LLVMFuzzerTestOneInput:
   33|  7.18k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   34|       |    /**
   35|       |     * A bitmap may contain up to 2**32 elements. Later this function will
   36|       |     * output the content to an array where each element uses 32 bits of
   37|       |     * storage. That would use 16 GB. Thus this function is bound to run out of
   38|       |     * memory.
   39|       |     *
   40|       |     * Even without the full serialization to a 32-bit array, a bitmap may still
   41|       |     * use over 512 MB in the normal course of operation: that is to be expected
   42|       |     * since it can represent all sets of integers in [0,2**32]. This function
   43|       |     * may hold several bitmaps in memory at once, so it can require gigabytes
   44|       |     * of memory (without bugs). Hence, unless it has a generous memory
   45|       |     * capacity, this function will run out of memory almost certainly.
   46|       |     *
   47|       |     * For sanity, we may limit the range to, say, 10,000,000 which will use 38
   48|       |     * MB or so. With such a limited range, if we run out of memory, then we can
   49|       |     * almost certain that it has to do with a genuine bug.
   50|       |     */
   51|       |
   52|  7.18k|    uint32_t range_start = 0;
   53|  7.18k|    uint32_t range_end = 10'000'000;
   54|       |
   55|       |    /**
   56|       |     * We are not solely dependent on the range [range_start, range_end) because
   57|       |     * ConsumeVecInRange below produce integers in a small range starting at 0.
   58|       |     */
   59|       |
   60|  7.18k|    FuzzedDataProvider fdp(data, size);
   61|       |    /**
   62|       |     * The next line was ConsumeVecInRange(fdp, 500, 0, 1000) but it would pick
   63|       |     * 500 values at random from 0, 1000, making almost certain that all of the
   64|       |     * values are picked. It seems more useful to pick 500 values in the range
   65|       |     * 0,1000.
   66|       |     */
   67|  7.18k|    std::vector<uint32_t> bitmap_data_a = ConsumeVecInRange(fdp, 500, 0, 1000);
   68|  7.18k|    roaring::Roaring a(bitmap_data_a.size(), bitmap_data_a.data());
   69|  7.18k|    a.runOptimize();
   70|  7.18k|    a.shrinkToFit();
   71|       |
   72|  7.18k|    std::vector<uint32_t> bitmap_data_b = ConsumeVecInRange(fdp, 500, 0, 1000);
   73|  7.18k|    roaring::Roaring b(bitmap_data_b.size(), bitmap_data_b.data());
   74|  7.18k|    b.runOptimize();
   75|  7.18k|    b.add(fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
   76|  7.18k|    b.addChecked(fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
   77|  7.18k|    b.addRange(fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end),
   78|  7.18k|               fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
   79|       |    // add half of a to b.
   80|  7.18k|    b.addMany(bitmap_data_a.size() / 2, bitmap_data_a.data());
   81|  7.18k|    b.remove(fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
   82|  7.18k|    b.removeChecked(
   83|  7.18k|        fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
   84|  7.18k|    b.removeRange(fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end),
   85|  7.18k|                  fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
   86|  7.18k|    b.removeRangeClosed(
   87|  7.18k|        fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end),
   88|  7.18k|        fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
   89|  7.18k|    b.maximum();
   90|  7.18k|    b.minimum();
   91|  7.18k|    b.contains(fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
   92|  7.18k|    b.containsRange(
   93|  7.18k|        fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end),
   94|  7.18k|        fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
   95|       |
   96|  7.18k|    uint32_t element = 0;
   97|  7.18k|    a.select(fdp.ConsumeIntegralInRange<uint32_t>(0, 1000), &element);
   98|  7.18k|    a.intersect(b);
   99|  7.18k|    a.jaccard_index(b);
  100|  7.18k|    a.or_cardinality(b);
  101|  7.18k|    a.andnot_cardinality(b);
  102|  7.18k|    a.xor_cardinality(b);
  103|  7.18k|    a.rank(fdp.ConsumeIntegralInRange<uint32_t>(0, 5000));
  104|  7.18k|    a.getSizeInBytes();
  105|       |
  106|  7.18k|    roaring::Roaring c = a & b;
  107|  7.18k|    roaring::Roaring d = a - b;
  108|  7.18k|    roaring::Roaring e = a | b;
  109|  7.18k|    roaring::Roaring f = a ^ b;
  110|  7.18k|    a |= e;
  111|  7.18k|    a &= b;
  112|  7.18k|    a -= c;
  113|  7.18k|    a ^= f;
  114|       |
  115|  7.18k|    volatile bool is_equal = (a == b);
  116|       |
  117|  7.18k|    std::vector<uint32_t> b_as_array = {0};
  118|  7.18k|    b_as_array.resize(b.cardinality());
  119|  7.18k|    b.isEmpty();
  120|  7.18k|    b.toUint32Array(b_as_array.data());
  121|       |
  122|  7.18k|    a.isSubset(b);
  123|  7.18k|    a.isStrictSubset(b);
  124|  7.18k|    b.flip(fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end),
  125|  7.18k|           fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
  126|  7.18k|    b.flipClosed(fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end),
  127|  7.18k|                 fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
  128|  7.18k|    b.removeRunCompression();
  129|       |
  130|       |    // Move/copy constructors
  131|  7.18k|    roaring::Roaring copied = b;
  132|  7.18k|    roaring::Roaring moved = std::move(b);
  133|       |
  134|       |    // Asignment operators
  135|  7.18k|    b = copied;
  136|  7.18k|    b = std::move(moved);
  137|       |
  138|       |    // Safe read from serialized
  139|  7.18k|    std::vector<char> read_buffer = fdp.ConsumeBytes<char>(100);
  140|  7.18k|    try {
  141|  7.18k|        roaring::Roaring read_safely =
  142|  7.18k|            roaring::Roaring::readSafe(read_buffer.data(), read_buffer.size());
  143|       |        // The above is guaranteed to be safe. However, read_safely is maybe
  144|       |        // in an improper state and it cannot be used safely (including for
  145|       |        // reserialization).
  146|  7.18k|    } catch (...) {
  147|  7.17k|    }
  148|       |
  149|       |    // The bitmap b can be serialized and re-read.
  150|  7.18k|    std::size_t expected_size_in_bytes = b.getSizeInBytes();
  151|  7.18k|    std::vector<char> buffer(expected_size_in_bytes);
  152|  7.18k|    std::size_t size_in_bytes = b.write(buffer.data());
  153|  7.18k|    assert(expected_size_in_bytes == size_in_bytes);
  ------------------
  |  Branch (153:5): [True: 7.18k, False: 0]
  ------------------
  154|  7.18k|    roaring::Roaring bread =
  155|  7.18k|        roaring::Roaring::readSafe(buffer.data(), size_in_bytes);
  156|  7.18k|    assert(bread == b);
  ------------------
  |  Branch (156:5): [True: 7.18k, False: 0]
  ------------------
  157|       |
  158|  7.18k|    f.toString();
  159|       |
  160|  7.18k|    volatile int unused = 0;
  161|       |
  162|   344k|    for (roaring::Roaring::const_iterator i = a.begin(); i != a.end(); i++) {
  ------------------
  |  Branch (162:58): [True: 337k, False: 7.18k]
  ------------------
  163|   337k|        unused++;
  164|   337k|    }
  165|       |
  166|  7.18k|    roaring::Roaring::const_iterator b_iter = b.begin();
  167|  7.18k|    b_iter.equalorlarger(
  168|  7.18k|        fdp.ConsumeIntegralInRange<uint32_t>(range_start, range_end));
  169|       |
  170|  7.18k|    return 0;
  171|  7.18k|}
croaring_fuzzer_cc.cc:_ZZ17ConsumeVecInRangeR18FuzzedDataProvidermjjENK3$_0clEv:
   27|  7.18M|    std::generate(result.begin(), result.end(), [&]() {
   28|  7.18M|        return fdp.ConsumeIntegralInRange<uint32_t>(min_value, max_value);
   29|  7.18M|    });

