2017-06-27 18:01:05 -04:00
|
|
|
#ifndef OSRM_UTIL_BIT_RANGE_HPP
|
|
|
|
#define OSRM_UTIL_BIT_RANGE_HPP
|
|
|
|
|
|
|
|
#include "util/msb.hpp"
|
2024-09-28 14:34:39 -04:00
|
|
|
#include <bit>
|
2017-06-27 18:01:05 -04:00
|
|
|
#include <boost/iterator/iterator_facade.hpp>
|
|
|
|
#include <boost/range/iterator_range.hpp>
|
|
|
|
|
2022-12-11 04:10:26 -05:00
|
|
|
namespace osrm::util
|
2017-06-27 18:01:05 -04:00
|
|
|
{
|
|
|
|
|
|
|
|
// Investigate if we can replace this with
|
|
|
|
// http://www.boost.org/doc/libs/1_64_0/libs/dynamic_bitset/dynamic_bitset.html
|
|
|
|
template <typename DataT>
|
|
|
|
class BitIterator : public boost::iterator_facade<BitIterator<DataT>,
|
|
|
|
const std::size_t,
|
|
|
|
boost::forward_traversal_tag,
|
|
|
|
const std::size_t>
|
|
|
|
{
|
2022-12-10 10:08:22 -05:00
|
|
|
using base_t = boost::iterator_facade<BitIterator<DataT>,
|
|
|
|
const std::size_t,
|
|
|
|
boost::forward_traversal_tag,
|
|
|
|
const std::size_t>;
|
2017-06-27 18:01:05 -04:00
|
|
|
|
|
|
|
public:
|
2022-11-06 07:21:45 -05:00
|
|
|
using value_type = typename base_t::value_type;
|
|
|
|
using difference_type = typename base_t::difference_type;
|
|
|
|
using reference = typename base_t::reference;
|
|
|
|
using iterator_category = std::random_access_iterator_tag;
|
2017-06-27 18:01:05 -04:00
|
|
|
|
|
|
|
explicit BitIterator() : m_value(0) {}
|
|
|
|
explicit BitIterator(const DataT x) : m_value(std::move(x)) {}
|
|
|
|
|
|
|
|
private:
|
|
|
|
void increment()
|
|
|
|
{
|
|
|
|
auto index = msb(m_value);
|
|
|
|
m_value = m_value & ~(DataT{1} << index);
|
|
|
|
}
|
|
|
|
|
|
|
|
difference_type distance_to(const BitIterator &other) const
|
|
|
|
{
|
2024-09-28 14:34:39 -04:00
|
|
|
return std::popcount(m_value) - std::popcount(other.m_value);
|
2017-06-27 18:01:05 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
bool equal(const BitIterator &other) const { return m_value == other.m_value; }
|
|
|
|
|
|
|
|
reference dereference() const
|
|
|
|
{
|
|
|
|
BOOST_ASSERT(m_value > 0);
|
|
|
|
return msb(m_value);
|
|
|
|
}
|
|
|
|
|
|
|
|
friend class ::boost::iterator_core_access;
|
|
|
|
DataT m_value;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Returns range over all 1 bits of value
|
|
|
|
template <typename T> auto makeBitRange(const T value)
|
|
|
|
{
|
|
|
|
return boost::make_iterator_range(BitIterator<T>{value}, BitIterator<T>{});
|
|
|
|
}
|
2022-12-20 12:00:11 -05:00
|
|
|
} // namespace osrm::util
|
2017-06-27 18:01:05 -04:00
|
|
|
|
|
|
|
#endif
|