Ticket #9352: dynamic_bitset.patch

File dynamic_bitset.patch, 2.5 KB (added by ssp.mryau@…, 9 years ago)

patch for dynamic_bitset with added methods find_last() and find_prev()

  • dynamic_bitset.hpp

    diff -dur d:/1/dynamic_bitset.hpp d:/2/dynamic_bitset.hpp
    old new  
    295295    // lookup
    296296    size_type find_first() const;
    297297    size_type find_next(size_type pos) const;
     298    size_type find_last() const;
     299    size_type find_prev(size_type pos) const;
    298300
    299301
    300302#if !defined BOOST_DYNAMIC_BITSET_DONT_USE_FRIENDS
     
    336338    bool m_check_invariants() const;
    337339
    338340    size_type m_do_find_from(size_type first_block) const;
     341    size_type m_do_find_downto(size_type last_block) const;
    339342
    340343    block_width_type count_extra_bits() const { return bit_index(size()); }
    341344    static size_type block_index(size_type pos) { return pos / bits_per_block; }
     
    12341237
    12351238}
    12361239
     1240// look for the nearest bit "on", starting
     1241// from the block with index last_block downto first block
     1242//
     1243template <typename Block, typename Allocator>
     1244typename dynamic_bitset<Block, Allocator>::size_type
     1245dynamic_bitset<Block, Allocator>::m_do_find_downto(size_type last_block) const
     1246{
     1247    size_type i = last_block;
     1248
     1249    // skip null blocks
     1250    while (i >= 0 && i != npos && m_bits[i] == 0)
     1251        --i;
     1252
     1253    if (i < 0 || i == npos)
     1254        return npos; // not found
     1255
     1256    return i * bits_per_block + boost::integer_log2(m_bits[i]);
     1257
     1258}
     1259
    12371260
    12381261template <typename Block, typename Allocator>
    12391262typename dynamic_bitset<Block, Allocator>::size_type
     
    12671290
    12681291}
    12691292
     1293template <typename Block, typename Allocator>
     1294typename dynamic_bitset<Block, Allocator>::size_type
     1295dynamic_bitset<Block, Allocator>::find_last() const
     1296{
     1297    return m_do_find_downto(num_blocks()-1);
     1298}
     1299
     1300template <typename Block, typename Allocator>
     1301typename dynamic_bitset<Block, Allocator>::size_type
     1302dynamic_bitset<Block, Allocator>::find_prev(size_type pos) const
     1303{
     1304
     1305    const size_type sz = size();
     1306    if (pos <= 0 || pos == npos || pos >= sz || sz == 0)
     1307        return npos;
     1308
     1309    --pos;
     1310
     1311    const size_type blk = block_index(pos);
     1312    const block_width_type ind = bit_index(pos);
     1313    const size_type mask =  ind == 0 ? 1 : (1 << ind) | ((1 << ind)-1);
     1314    // mask out bits after pos
     1315    const Block fore = m_bits[blk] & mask;
     1316
     1317    return fore?
     1318        blk * bits_per_block + boost::integer_log2(fore)
     1319        :
     1320        m_do_find_downto(blk - 1);
     1321
     1322}
    12701323
    12711324
    12721325//-----------------------------------------------------------------------------