added missing files
authorspog <spog>
Tue, 28 Feb 2006 19:19:16 +0000 (19:19 +0000)
committerspog <spog>
Tue, 28 Feb 2006 19:19:16 +0000 (19:19 +0000)
git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@28 8a3a26a2-13c4-0310-b231-cf6edde360e5

libs/string/pooledstring.cpp [new file with mode: 0644]
libs/string/pooledstring.h [new file with mode: 0644]

diff --git a/libs/string/pooledstring.cpp b/libs/string/pooledstring.cpp
new file mode 100644 (file)
index 0000000..1eb8d51
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include "pooledstring.h"
+#include "generic/static.h"
+
+#if defined(_DEBUG)
+
+namespace ExamplePooledString
+{
+  void testStuff()
+  {
+    PooledString< LazyStatic<StringPool> > a, b;
+    a = "monkey";
+    b = "monkey";
+    a = "";
+  }
+
+  struct Always
+  {
+    Always()
+    {
+      testStuff();
+    }
+  } always;
+}
+
+#endif
\ No newline at end of file
diff --git a/libs/string/pooledstring.h b/libs/string/pooledstring.h
new file mode 100644 (file)
index 0000000..4ff2d61
--- /dev/null
@@ -0,0 +1,108 @@
+
+#if !defined(INCLUDED_POOLEDSTRING_H)
+#define INCLUDED_POOLEDSTRING_H
+
+#include <map>
+#include "generic/static.h"
+#include "string/string.h"
+#include "container/hashtable.h"
+#include "container/hashfunc.h"
+
+/// \brief The string pool class.
+class StringPool : public HashTable<char*, std::size_t, RawStringHash, RawStringEqual>
+{
+};
+
+inline void StringPool_analyse(StringPool& pool)
+{
+  typedef std::multimap<std::size_t, const char*> Ordered;
+  Ordered ordered;
+  std::size_t total = 0;
+  std::size_t pooled = 0;
+  for(StringPool::iterator i = pool.begin(); i != pool.end(); ++i)
+  {
+    std::size_t size =  string_length((*i).key) + 1;
+    total += size * (*i).value;
+    pooled += size + 20;
+    ordered.insert(Ordered::value_type((*i).value, (*i).key));
+  }
+  globalOutputStream() << "total: " << Unsigned(total) << " pooled:" << Unsigned(pooled) << "\n";
+  for(Ordered::iterator i = ordered.begin(); i != ordered.end(); ++i)
+  {
+    globalOutputStream() << (*i).second << " " << Unsigned((*i).first) << "\n";
+  }
+}
+
+
+/// \brief A string which can be copied with zero memory cost and minimal runtime cost.
+///
+/// \param PoolContext The string pool context to use.
+template<typename PoolContext>
+class PooledString
+{
+  StringPool::iterator m_i;
+  static StringPool::iterator increment(StringPool::iterator i)
+  {
+    ++(*i).value;
+    return i;
+  }
+  static StringPool::iterator insert(const char* string)
+  {
+    StringPool::iterator i = PoolContext::instance().find(const_cast<char*>(string));
+    if(i == PoolContext::instance().end())
+    {
+      return PoolContext::instance().insert(string_clone(string), 1);
+    }
+    return increment(i);
+  }
+  static void erase(StringPool::iterator i)
+  {
+    if(--(*i).value == 0)
+    {
+      char* string = (*i).key;
+      PoolContext::instance().erase(i);
+      string_release(string, string_length(string));
+    }
+  }
+public:
+  PooledString() : m_i(insert(""))
+  {
+  }
+  PooledString(const PooledString& other) : m_i(increment(other.m_i))
+  {
+  }
+  PooledString(const char* string) : m_i(insert(string))
+  {
+  }
+  ~PooledString()
+  {
+    erase(m_i);
+  }
+  PooledString& operator=(const PooledString& other)
+  {
+    PooledString tmp(other);
+    tmp.swap(*this);
+    return *this;
+  }
+  PooledString& operator=(const char* string)
+  {
+    PooledString tmp(string);
+    tmp.swap(*this);
+    return *this;
+  }
+  void swap(PooledString& other)
+  {
+    std::swap(m_i, other.m_i);
+  }
+  bool operator==(const PooledString& other) const
+  {
+    return m_i == other.m_i;
+  }
+  const char* c_str() const
+  {
+    return (*m_i).key;
+  }
+};
+
+
+#endif