2001-03-06 14:07:14 +00:00
|
|
|
|
// -*- C++ -*-
|
|
|
|
|
|
|
|
|
|
#ifndef SHARECONTAINER_H
|
|
|
|
|
#define SHARECONTAINER_H
|
|
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <algorithm>
|
2001-03-06 19:29:58 +00:00
|
|
|
|
#include <functional>
|
2001-03-06 14:07:14 +00:00
|
|
|
|
#include <boost/utility.hpp>
|
|
|
|
|
#include <boost/smart_ptr.hpp>
|
|
|
|
|
|
2001-03-12 01:43:12 +00:00
|
|
|
|
/// Share objects between several users.
|
|
|
|
|
/**
|
|
|
|
|
This class can be used to reduce memory consuption when you have a lot
|
2001-03-20 01:22:46 +00:00
|
|
|
|
of equal objects used all over your code.
|
2001-03-12 01:43:12 +00:00
|
|
|
|
|
|
|
|
|
\author Lars Gullik Bj<EFBFBD>nnes
|
|
|
|
|
*/
|
2001-03-06 14:07:14 +00:00
|
|
|
|
template<class Share>
|
2001-03-15 16:04:46 +00:00
|
|
|
|
class ShareContainer : public boost::noncopyable {
|
2001-03-06 14:07:14 +00:00
|
|
|
|
public:
|
|
|
|
|
///
|
|
|
|
|
typedef std::vector<boost::shared_ptr<Share> > Params;
|
|
|
|
|
///
|
2001-03-06 17:18:06 +00:00
|
|
|
|
typedef typename Params::value_type value_type;
|
2001-03-12 01:43:12 +00:00
|
|
|
|
/// Return a shared_ptr that points to a element equal to ps.
|
2001-03-06 17:18:06 +00:00
|
|
|
|
value_type
|
2001-03-06 14:07:14 +00:00
|
|
|
|
get(Share const & ps) const {
|
|
|
|
|
// First see if we already have this ps in the container
|
2001-03-07 11:22:05 +00:00
|
|
|
|
Params::iterator it = std::find_if(params.begin(),
|
2001-03-11 00:21:13 +00:00
|
|
|
|
params.end(),
|
|
|
|
|
isEqual(ps));
|
2001-03-06 17:18:06 +00:00
|
|
|
|
value_type tmp;
|
2001-03-06 19:29:58 +00:00
|
|
|
|
if (it == params.end()) {
|
2001-03-06 14:07:14 +00:00
|
|
|
|
// ok we don't have it so we should
|
|
|
|
|
// insert it.
|
|
|
|
|
tmp.reset(new Share(ps));
|
|
|
|
|
params.push_back(tmp);
|
|
|
|
|
// We clean here. This can cause us to have
|
|
|
|
|
// some (one) unique elemements some times
|
|
|
|
|
// but we should gain a lot in speed.
|
|
|
|
|
clean();
|
|
|
|
|
} else {
|
|
|
|
|
// yes we have it already
|
|
|
|
|
tmp = *it;
|
2001-03-12 01:43:12 +00:00
|
|
|
|
// move it forward - optimization
|
|
|
|
|
// makes the next find faster.
|
2001-03-11 00:21:13 +00:00
|
|
|
|
if (it != params.begin())
|
2001-03-12 08:52:37 +00:00
|
|
|
|
std::swap(*it, *(it - 1));
|
2001-03-06 14:07:14 +00:00
|
|
|
|
}
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
private:
|
2001-03-12 01:43:12 +00:00
|
|
|
|
/// A functor returning true if the elements are equal.
|
2001-03-06 19:29:58 +00:00
|
|
|
|
struct isEqual {
|
|
|
|
|
isEqual(Share const & s) : p_(s) {}
|
|
|
|
|
bool operator()(value_type const & p1) const {
|
|
|
|
|
return *p1.get() == p_;
|
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
Share const & p_;
|
|
|
|
|
};
|
2001-03-20 01:22:46 +00:00
|
|
|
|
/// A functor returning true if the element is unique.
|
2001-03-06 14:07:14 +00:00
|
|
|
|
struct isUnique {
|
2001-03-06 17:18:06 +00:00
|
|
|
|
bool operator()(value_type const & p) const {
|
2001-03-06 14:07:14 +00:00
|
|
|
|
return p.unique();
|
|
|
|
|
}
|
|
|
|
|
};
|
2001-03-11 00:21:13 +00:00
|
|
|
|
|
2001-03-12 01:43:12 +00:00
|
|
|
|
/** Remove all unique items.
|
|
|
|
|
This removes all elements from params that is only referenced
|
|
|
|
|
from the private container. This can be considered a memory
|
|
|
|
|
optimizaton.
|
|
|
|
|
*/
|
2001-03-06 14:07:14 +00:00
|
|
|
|
void clean() const {
|
|
|
|
|
Params::iterator it = std::remove_if(params.begin(),
|
|
|
|
|
params.end(),
|
|
|
|
|
isUnique());
|
|
|
|
|
params.erase(it, params.end());
|
|
|
|
|
}
|
|
|
|
|
|
2001-03-12 01:43:12 +00:00
|
|
|
|
/// The actual container.
|
2001-03-06 14:07:14 +00:00
|
|
|
|
mutable Params params;
|
|
|
|
|
};
|
|
|
|
|
#endif
|