这是我现在使用的(看看
struct vset_adaptor
)
#ifndef HEADER___VECTSET___BE8EB41D7B3971E1
#define HEADER___VECTSET___BE8EB41D7B3971E1
#include <vector>
//############################################################### ptrvect
template <class T, class base = std::vector<T*> >
class ptrvect: public base {
public:
class iterator: public base::iterator {
friend class ptrvect;
private:
iterator(const typename base::const_iterator& it):
base::iterator(const_cast<T**>(&*it)) {
return; }
public:
iterator(const typename base::iterator& it):
base::iterator(it) {
return; }
T* operator->() const {
return **this; }};
class const_iterator: public base::const_iterator {
public:
const_iterator(const typename base::const_iterator& it):
base::const_iterator(it) {
return; }
const_iterator(const typename base::iterator& it):
base::const_iterator(it) {
return; }
T* operator->() const {
return **this; }};
template <class It = iterator>
class condpair: public std::pair<It,bool> {
public:
condpair(It it, bool second):
std::pair<It,bool>(it, second) {
return; }
T* operator->() const {
return *std::pair<It,bool>::first; }};
public:
iterator begin() {
return iterator(base::begin()); }
iterator end() {
return iterator(base::end()); }
const_iterator begin() const {
return const_iterator(base::begin()); }
const_iterator end() const {
return const_iterator(base::end()); }
public: // workarounds for pre-C++11 / bad C++11 implementation (should allow const_iterator)
iterator insert(const_iterator pos, T* value) {
return base::insert(iterator(pos), value); }
iterator erase(const_iterator pos) {
return base::erase(iterator(pos)); }
public: // addons
iterator find (T* key) {
return std::find(begin(), end(), key); }
const_iterator find (T* key) const {
return std::find(begin(), end(), key); }
bool contains (T* key) const {
return find(key) != end(); }
T* remove(T* key) {
auto it = find(key);
if (it == end()) return null;
T* val = *it;
base::erase(it);
return val; }
T* add(T* val) {
base::push_back(val);
return val; }
void release() {
for (T* it : *this) delete it;
base::clear(); }};
//########################################################## vset adaptor
template <class T, class K>
struct vset_adaptor {
K operator()(T* it) const {
return (K)(*it); }
bool operator()(K lhs, K rhs) const {
return lhs < rhs; }};
template <class T>
struct vset_adaptor<T,T*> {
T* operator()(T* it) const {
return it; }
bool operator()(T* lhs, T* rhs) const {
return lhs < rhs; }};
//================================================================== vset
template <class T, class K=T*, class F = vset_adaptor<T,K> >
class vset {
private:
ptrvect<T> impl;
struct Comp {
F f;
K operator()(T* it) const {
return f(it); }
bool operator()(K lhs, K rhs) const {
return f(lhs, rhs); }
bool operator()(T* lhs, K rhs) const {
return f(f(lhs), rhs); }
bool operator()(K lhs, T* rhs) const {
return f(lhs, f(rhs)); }
bool operator()(T* lhs, T* rhs) const {
return f(f(lhs), f(rhs)); }};
Comp comp;
public:
typedef typename ptrvect<T>::const_iterator iterator, const_iterator;
typedef unsigned size_type;
typedef T *value_type;
typedef K key_type;
typedef typename ptrvect<T>::template condpair<iterator> condpair;
public:
iterator begin() const {
return iterator(impl.begin()); }
iterator end() const {
return iterator(impl.end()); }
size_type size() const {
return impl.size(); }
bool empty() const {
return impl.empty(); }
public:
iterator lower_bound(K key) const {
return std::lower_bound(impl.begin(), impl.end(), key, comp); }
iterator upper_bound(K key) const {
return std::upper_bound(impl.begin(), impl.end(), key, comp); }
std::pair<iterator, iterator> equal_range(K key) const {
return std::equal_range(impl.begin(), impl.end(), key, comp); }
iterator find(K key) const {
iterator it = lower_bound(key);
return it == end() || comp(key, *it) ? end() : it; }
bool contains(K key) const {
iterator it = lower_bound(key);
return it != end() && !comp(key, *it); }
public:
typename std::enable_if<!std::is_same<T*,K>::value,
iterator>::type lower_bound(T* key) const {
return std::lower_bound(impl.begin(), impl.end(), comp(key), comp); }
typename std::enable_if<!std::is_same<T*,K>::value,
iterator>::type upper_bound(T* key) const {
return std::upper_bound(impl.begin(), impl.end(), comp(key), comp); }
typename std::enable_if<!std::is_same<T*,K>::value,
std::pair<iterator, iterator> >::type equal_range(T* key) const {
return std::equal_range(impl.begin(), impl.end(), comp(key), comp); }
typename std::enable_if<!std::is_same<T*,K>::value,
iterator>::type find(T* key) const {
iterator it = lower_bound(comp(key));
return it == end() || comp(key, *it) ? end() : it; }
public:
template<class... Args>
condpair emplace(K key, Args&& ...args) {
iterator it = lower_bound(key);
if (it == end() || comp(key, *it)) {
return condpair(impl.insert(it,
new T(key, std::forward<Args>(args)...)), true); }
return condpair(it, false); }
iterator erase(iterator at) {
return impl.erase(at); }
public:
T* add(T* value) {
iterator it = lower_bound(value);
if (it == end() || comp(comp(value), *it)) {
impl.insert(it, value);
return value; }
return nullptr; }
template<class... Args>
T* add(K key, Args&& ...args) {
iterator it = lower_bound(key);
if (it == end() || comp(key, *it)) {
T* value = new T(key, std::forward<Args>(args)...);
impl.insert(it, value);
return value; }
return nullptr; }
T* get(K key) const {
iterator it = find(key);
return it == impl.end() ? nullptr : *it; }
T* operator[](K key) const {
return *emplace(key).first; }
T* remove(K key) {
iterator it = find(key);
if (it == impl.end()) return nullptr;
T* value = *it;
impl.erase(it);
return value; }
typename std::enable_if<!std::is_same<T*,K>::value,
T*>::type remove(T* key) {
return remove(comp(key)); }
void release() {
for (T* it : *this) {
delete it; }
impl.clear(); }
void clear() {
impl.clear(); }};
#endif
如果你想知道代码样式,它是我自己的预处理器的输出。这是真实的代码:
#include <vector>
//############################################################### ptrvect
template <class T, class base = std::vector<T*> >
class ptrvect: public base
public:
class iterator: public base::iterator
friend class ptrvect
private:
iterator(const typename base::const_iterator& it):
base::iterator(const_cast<T**>(&*it))
return
public:
iterator(const typename base::iterator& it):
base::iterator(it)
return
T* operator->() const
return **this
class const_iterator: public base::const_iterator
public:
const_iterator(const typename base::const_iterator& it):
base::const_iterator(it)
return
const_iterator(const typename base::iterator& it):
base::const_iterator(it)
return
T* operator->() const
return **this
template <class It = iterator>
class condpair: public std::pair<It,bool>
public:
condpair(It it, bool second):
std::pair<It,bool>(it, second)
return
T* operator->() const
return *std::pair<It,bool>::first
public:
iterator begin()
return iterator(base::begin())
iterator end()
return iterator(base::end())
const_iterator begin() const
return const_iterator(base::begin())
const_iterator end() const
return const_iterator(base::end())
public: // workarounds for pre-C++11 / bad C++11 implementation (should allow const_iterator)
iterator insert(const_iterator pos, T* value)
return base::insert(iterator(pos), value)
iterator erase(const_iterator pos)
return base::erase(iterator(pos))
public: // addons
iterator find (T* key)
return std::find(begin(), end(), key)
const_iterator find (T* key) const
return std::find(begin(), end(), key)
bool contains (T* key) const
return find(key) != end()
T* remove(T* key)
auto it = find(key)
if it == end(); return null
T* val = *it
base::erase(it)
return val
T* add(T* val)
base::push_back(val)
return val
void release()
for T* it : *this; delete it
base::clear()
//########################################################## vset adaptor
template <class T, class K>
struct vset_adaptor
K operator()(T* it) const
return (K)(*it)
bool operator()(K lhs, K rhs) const
return lhs < rhs
template <class T>
struct vset_adaptor<T,T*>
T* operator()(T* it) const
return it
bool operator()(T* lhs, T* rhs) const
return lhs < rhs
//================================================================== vset
template <class T, class K=T*, class F = vset_adaptor<T,K> >
class vset
private:
ptrvect<T> impl
struct Comp
F f
K operator()(T* it) const
return f(it)
bool operator()(K lhs, K rhs) const
return f(lhs, rhs)
bool operator()(T* lhs, K rhs) const
return f(f(lhs), rhs)
bool operator()(K lhs, T* rhs) const
return f(lhs, f(rhs))
bool operator()(T* lhs, T* rhs) const
return f(f(lhs), f(rhs))
Comp comp
public:
typedef typename ptrvect<T>::const_iterator iterator, const_iterator
typedef unsigned size_type
typedef T *value_type
typedef K key_type
typedef typename ptrvect<T>::template condpair<iterator> condpair
public:
iterator begin() const
return iterator(impl.begin())
iterator end() const
return iterator(impl.end())
size_type size() const
return impl.size()
bool empty() const
return impl.empty()
public:
iterator lower_bound(K key) const
return std::lower_bound(impl.begin(), impl.end(), key, comp)
iterator upper_bound(K key) const
return std::upper_bound(impl.begin(), impl.end(), key, comp)
std::pair<iterator, iterator> equal_range(K key) const
return std::equal_range(impl.begin(), impl.end(), key, comp)
iterator find(K key) const
iterator it = lower_bound(key)
return it == end() || comp(key, *it) ? end() : it
bool contains(K key) const
iterator it = lower_bound(key)
return it != end() && !comp(key, *it)
public:
typename std::enable_if<!std::is_same<T*,K>::value,
iterator>::type lower_bound(T* key) const
return std::lower_bound(impl.begin(), impl.end(), comp(key), comp)
typename std::enable_if<!std::is_same<T*,K>::value,
iterator>::type upper_bound(T* key) const
return std::upper_bound(impl.begin(), impl.end(), comp(key), comp)
typename std::enable_if<!std::is_same<T*,K>::value,
std::pair<iterator, iterator> >::type equal_range(T* key) const
return std::equal_range(impl.begin(), impl.end(), comp(key), comp)
typename std::enable_if<!std::is_same<T*,K>::value,
iterator>::type find(T* key) const
iterator it = lower_bound(comp(key))
return it == end() || comp(key, *it) ? end() : it
public:
template<class... Args>
condpair emplace(K key, Args&& ...args)
iterator it = lower_bound(key)
if it == end() || comp(key, *it)
return condpair(impl.insert(it,
new T(key, std::forward<Args>(args)...)), true)
return condpair(it, false)
iterator erase(iterator at)
return impl.erase(at)
public:
T* add(T* value)
iterator it = lower_bound(value)
if it == end() || comp(comp(value), *it)
impl.insert(it, value)
return value
return nullptr
template<class... Args>
T* add(K key, Args&& ...args)
iterator it = lower_bound(key)
if it == end() || comp(key, *it)
T* value = new T(key, std::forward<Args>(args)...)
impl.insert(it, value)
return value
return nullptr
T* get(K key) const
iterator it = find(key)
return it == impl.end() ? nullptr : *it
T* operator[](K key) const
return *emplace(key).first
T* remove(K key)
iterator it = find(key)
if it == impl.end(); return nullptr
T* value = *it
impl.erase(it)
return value
typename std::enable_if<!std::is_same<T*,K>::value,
T*>::type remove(T* key)
return remove(comp(key))
void release()
for T* it : *this
delete it
impl.clear()
void clear()
impl.clear()