工具类库系列(十六)-rangmap

时间:2022-03-05 06:22:57

rangmap是一个对map的简单封装,用于实现对若干个互不重叠的闭区间的 增删改查


我们通常会有这样的需求,比如:

若干个IP地址的闭区间:127.0.0.50 -127.0.0.100,127.0.0.101-127.0.0.149,127.0.0.200-127.0.0.249,这个不同的ip区间可能是对应了3个不同的房间中的机器,每个区间对应一个房间

现在需要搜索 某一个具体ip,是属于哪个房间的。


于是,就存在一个区间的搜索的问题。我们需要一颗允许进行区间查找的树,这棵树的key是一种区间类型。


这个区间类型,封装2个值:begin,end,分别表示闭区间的两端。

我们用模板 rang<K>,来表示这个区间类型,K应该是支持 < (小于) 这个比较运算符的一种数据类型


因为是互不重叠的闭区间,所以这个区间类型的比较函数:

bool operator<(const rang<K>& other) const
{
if (m_begin < other.m_begin && m_end < other.m_begin)
{
return true;
}
else
{
return false;
}
}

因此如果出现重叠的区间,将会被视为同一个区间,因此使用的时候需要注意

其他的就是一些对map常用功能的封装:迭代,find,erase,下标运算符,等


给出具体代码

rangmap.h

#ifndef __RangMap_h__
#define __RangMap_h__

#include <map>

namespace common {
namespace tool {

template <class K, class V>
class rangmap
{
public:
template <class K>
class rang
{
public:
rang()
{

}
rang(const K& begin, const K& end)
{
m_begin = begin;
m_end = end;
}
rang(const rang<K>& other)
{
*this = other;
}
~rang()
{

}
rang<K>& operator=(const rang<K>& other)
{
m_begin = other.m_begin;
m_end = other.m_end;
return *this;
}

bool operator<(const rang<K>& other) const
{
if (m_begin < other.m_begin && m_end < other.m_begin)
{
return true;
}
else
{
return false;
}
}

const K& begin() const
{
return m_begin;
}
const K& end() const
{
return m_end;
}

private:
K m_begin;
K m_end;
};

template <class K, class V>
using rangmap_it = typename std::map<rang<K>, V>::iterator;
template <class K, class V>
using rangmap_cit = typename std::map<rang<K>, V>::const_iterator;
template <class K, class V>
using rangmap_rit = typename std::map<rang<K>, V>::reverse_iterator;
template <class K, class V>
using rangmap_crit = typename std::map<rang<K>, V>::const_reverse_iterator;

public:
V& operator[](const K& key)
{
return m_map[rang<K>(key, key)];
}
V& operator[](const rang<K>& key)
{
return m_map[key];
}

rangmap_it<K, V> begin()
{
return m_map.begin();
}
rangmap_it<K, V> end()
{
return m_map.end();
}
rangmap_cit<K, V> begin() const
{
return m_map.begin();
}
rangmap_cit<K, V> end() const
{
return m_map.end();
}

rangmap_rit<K, V> rbegin()
{
return m_map.rbegin();
}
rangmap_rit<K, V> rend()
{
return m_map.rend();
}
rangmap_crit<K, V> rbegin() const
{
return m_map.rbegin();
}
rangmap_crit<K, V> rend() const
{
return m_map.rend();
}

rangmap_it<K, V> find(const K& key)
{
return m_map.find(rang<K>(key, key));
}
rangmap_it<K, V> find(const rang<K>& key)
{
return m_map.find(key);
}
rangmap_cit<K, V> find(const K& key) const
{
return m_map.find(rang<K>(key, key));
}
rangmap_cit<K, V> find(const rang<K>& key) const
{
return m_map.find(key);
}

rangmap_it<K, V> erase(rangmap_cit<K, V> it)
{
return m_map.erase(it);
}
rangmap_it<K, V> erase(rangmap_cit<K, V> begin, rangmap_cit<K, V> end)
{
return m_map.erase(begin, end);
}
size_t erase(const K& key)
{
return m_map.erase(rang<K>(key, key));
}
size_t erase(const rang<K>& key)
{
return m_map.erase(key);
}

size_t size() const
{
return m_map.size();
}
bool empty() const
{
return (size() == 0);
}
void clear()
{
m_map.clear();
}

private:
std::map<rang<K>, V> m_map;
};
}
}

#endif