* flat_map and btree_map).
*/
-template<typename T, typename Map = std::map<T,T>>
+template<typename T, template<typename, typename, typename ...> class C = std::map>
class interval_set {
public:
+ using Map = C<T, T>;
using value_type = typename Map::value_type;
using offset_type = T;
using length_type = T;
class const_iterator;
- class iterator : public std::iterator <std::forward_iterator_tag, T>
+ class iterator
{
public:
+ using difference_type = ssize_t;
+ using value_type = typename Map::value_type;
+ using pointer = typename Map::value_type*;
+ using reference = typename Map::value_type&;
+ using iterator_category = std::forward_iterator_tag;
+
explicit iterator(typename Map::iterator iter)
: _iter(iter)
{ }
friend class interval_set;
};
- class const_iterator : public std::iterator <std::forward_iterator_tag, T>
+ class const_iterator
{
public:
+ using difference_type = ssize_t;
+ using value_type = const typename Map::value_type;
+ using pointer = const typename Map::value_type*;
+ using reference = const typename Map::value_type&;
+ using iterator_category = std::forward_iterator_tag;
+
explicit const_iterator(typename Map::const_iterator iter)
: _iter(iter)
{ }
}
// Dereference this iterator to get a pair.
- const_reference operator*() const {
+ reference operator*() const {
return *_iter;
}
}
offset_type range_end() const {
ceph_assert(!empty());
- auto p = m.end();
- p--;
- return p->first+p->second;
+ auto p = m.rbegin();
+ return p->first + p->second;
}
// interval start after p (where p not in set)
std::swap(_size, other._size);
}
- void erase(iterator &i) {
+ void erase(const iterator &i) {
_size -= i.get_len();
- ceph_assert(_size >= 0);
m.erase(i._iter);
}
auto p = find_inc_m(start);
_size -= len;
- ceph_assert(_size >= 0);
ceph_assert(p != m.end());
ceph_assert(p->first <= start);
// declare traits explicitly because (1) it's templatized, and (2) we
// want to include _nohead variants.
-template<typename T, typename Map>
-struct denc_traits<interval_set<T,Map>> {
+template<typename T, template<typename, typename, typename ...> class C>
+struct denc_traits<interval_set<T, C>> {
+private:
+ using container_t = interval_set<T, C>;
+public:
static constexpr bool supported = true;
static constexpr bool bounded = false;
static constexpr bool featured = false;
- static constexpr bool need_contiguous = denc_traits<T,Map>::need_contiguous;
- static void bound_encode(const interval_set<T,Map>& v, size_t& p) {
+ static constexpr bool need_contiguous = denc_traits<T, C<T,T>>::need_contiguous;
+ static void bound_encode(const container_t& v, size_t& p) {
v.bound_encode(p);
}
- static void encode(const interval_set<T,Map>& v,
+ static void encode(const container_t& v,
ceph::buffer::list::contiguous_appender& p) {
v.encode(p);
}
- static void decode(interval_set<T,Map>& v, ceph::buffer::ptr::const_iterator& p) {
+ static void decode(container_t& v, ceph::buffer::ptr::const_iterator& p) {
v.decode(p);
}
template<typename U=T>
static typename std::enable_if<sizeof(U) && !need_contiguous>::type
- decode(interval_set<T,Map>& v, ceph::buffer::list::iterator& p) {
+ decode(container_t& v, ceph::buffer::list::iterator& p) {
v.decode(p);
}
- static void encode_nohead(const interval_set<T,Map>& v,
+ static void encode_nohead(const container_t& v,
ceph::buffer::list::contiguous_appender& p) {
v.encode_nohead(p);
}
- static void decode_nohead(size_t n, interval_set<T,Map>& v,
+ static void decode_nohead(size_t n, container_t& v,
ceph::buffer::ptr::const_iterator& p) {
v.decode_nohead(n, p);
}
};
-template<class T, typename Map>
-inline std::ostream& operator<<(std::ostream& out, const interval_set<T,Map> &s) {
+template<typename T, template<typename, typename, typename ...> class C>
+inline std::ostream& operator<<(std::ostream& out, const interval_set<T,C> &s) {
out << "[";
bool first = true;
for (const auto& [start, len] : s) {