add shared_object.hpp, the base for shared string and tstring

This commit is contained in:
Chris Hopman 2009-05-29 17:12:21 +00:00
parent d6454595ee
commit 6457ce1b90
4 changed files with 153 additions and 1 deletions

View file

@ -420,7 +420,8 @@
<Unit filename="..\..\src\gui\dialogs\..\..\settings.hpp" />
<Unit filename="..\..\src\sha1.cpp" />
<Unit filename="..\..\src\sha1.hpp" />
<Unit filename="..\..\src\show_dialog.cpp" />
<Unit filename="..\..\src\shared_object.hpp" />
<Unit filename="..\..\src\show_dialog.cpp" />
<Unit filename="..\..\src\show_dialog.hpp" />
<Unit filename="..\..\src\sound.cpp" />
<Unit filename="..\..\src\sound.hpp" />

View file

@ -451,6 +451,7 @@
<Unit filename="..\..\src\gui\dialogs\..\..\settings.hpp" />
<Unit filename="..\..\src\sha1.cpp" />
<Unit filename="..\..\src\sha1.hpp" />
<Unit filename="..\..\src\shared_object.hpp" />
<Unit filename="..\..\src\show_dialog.cpp" />
<Unit filename="..\..\src\show_dialog.hpp" />
<Unit filename="..\..\src\sound.cpp" />

View file

@ -674,6 +674,10 @@
RelativePath="..\..\src\statistics_dialog.cpp"
>
</File>
<File
RelativePath="..\..\src\shared_object.hpp"
>
</File>
<File
RelativePath="..\..\src\team.cpp"
>

146
src/shared_object.hpp Normal file
View file

@ -0,0 +1,146 @@
#include <climits>
#include <cassert>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
template <typename T>
struct shared_node {
T val;
unsigned long count;
shared_node() : val(), count(0) { }
shared_node(const T& o) : val(o), count(0) { }
static const unsigned long max_count = ULONG_MAX;
};
struct increment_count {
template <typename T>
void operator()(T& o) {
++o.count;
}
};
struct decrement_count {
template <typename T>
void operator()(T& o) {
--o.count;
}
};
template <typename T>
struct hasher {
size_t operator()(const T& o) {
return hash_value(o.val);
}
};
template <typename T, typename node = shared_node<T> >
class shared_object {
public:
typedef T type;
shared_object() : val_(0) { set(T()); }
template <typename U>
shared_object(const U& o) : val_(0) { set(o); }
shared_object(const shared_object& o) : val_(o.val_) {
assert(valid());
index().modify(index().iterator_to(*val_), increment_count());
}
operator T() const {
assert(valid());
return val_->val;
}
shared_object& operator=(const shared_object& o) {
if (val_ == o.val_) return *this;
shared_object tmp(o);
swap(tmp);
return *this;
}
~shared_object() { clear(); }
void set(const T& o) {
if (val_ && o == get()) return;
clear();
val_ = &*index().insert(node(o)).first;
index().modify(index().iterator_to(*val_), increment_count());
assert((val_->count) < (node::max_count));
}
const T& get() const {
assert(valid());
return val_->val;
}
void swap(shared_object& o) {
std::swap(val_, o.val_);
}
bool valid() const {
return val_;
}
const node* ptr() const {
return val_;
}
protected:
typedef boost::multi_index_container<
node,
boost::multi_index::indexed_by<
boost::multi_index::hashed_unique<
BOOST_MULTI_INDEX_MEMBER(node, T, val)
>
>
> hash_map;
typedef typename hash_map::template nth_index<0>::type hash_index;
static hash_map& map() { static hash_map* map = new hash_map; return *map; }
static hash_index& index() { return map().template get<0>(); }
const node* val_;
void clear() {
if (!val_) return;
index().modify(index().iterator_to(*val_), decrement_count());
if (val_->count == 0) index().erase(index().iterator_to(*val_));
val_ = 0;
}
};
template <typename T>
bool operator==(const shared_object<T>& a, const shared_object<T>& b) {
return a.ptr() == b.ptr() ? true : a.get() == b.get();
}
template <typename T>
bool operator<(const shared_object<T>& a, const shared_object<T>& b) {
assert(a.valid());
assert(b.valid());
return a.get() < b.get();
}
template <typename T>
std::ostream& operator<<(std::ostream& stream, const shared_object<T>& o) {
assert(o.valid());
return stream << o.get();
}
template <typename T>
std::istream& operator>>(std::istream& stream, shared_object<T>& o) {
T t;
std::istream& ret = stream >> t;
o.set(t);
return ret;
}