Author: cjhopman
Date: Fri May 29 19:12:21 2009
New Revision: 35933

URL: http://svn.gna.org/viewcvs/wesnoth?rev=35933&view=rev
Log:
add shared_object.hpp, the base for shared string and tstring

Added:
    trunk/src/shared_object.hpp
Modified:
    trunk/projectfiles/CodeBlocks-SCons/wesnoth.cbp
    trunk/projectfiles/CodeBlocks/wesnoth.cbp
    trunk/projectfiles/VC9/wesnoth.vcproj

Modified: trunk/projectfiles/CodeBlocks-SCons/wesnoth.cbp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/projectfiles/CodeBlocks-SCons/wesnoth.cbp?rev=35933&r1=35932&r2=35933&view=diff
==============================================================================
--- trunk/projectfiles/CodeBlocks-SCons/wesnoth.cbp (original)
+++ trunk/projectfiles/CodeBlocks-SCons/wesnoth.cbp Fri May 29 19:12:21 2009
@@ -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" />

Modified: trunk/projectfiles/CodeBlocks/wesnoth.cbp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/projectfiles/CodeBlocks/wesnoth.cbp?rev=35933&r1=35932&r2=35933&view=diff
==============================================================================
--- trunk/projectfiles/CodeBlocks/wesnoth.cbp (original)
+++ trunk/projectfiles/CodeBlocks/wesnoth.cbp Fri May 29 19:12:21 2009
@@ -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" />

Modified: trunk/projectfiles/VC9/wesnoth.vcproj
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/projectfiles/VC9/wesnoth.vcproj?rev=35933&r1=35932&r2=35933&view=diff
==============================================================================
--- trunk/projectfiles/VC9/wesnoth.vcproj (original)
+++ trunk/projectfiles/VC9/wesnoth.vcproj Fri May 29 19:12:21 2009
@@ -675,6 +675,10 @@
                                >
                        </File>
                        <File
+                               RelativePath="..\..\src\shared_object.hpp"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\..\src\team.cpp"
                                >
                        </File>

Added: trunk/src/shared_object.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/shared_object.hpp?rev=35933&view=auto
==============================================================================
--- trunk/src/shared_object.hpp (added)
+++ trunk/src/shared_object.hpp Fri May 29 19:12:21 2009
@@ -1,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;
+}
+


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to