#ifndef SHSTR_H #define SHSTR_H #include #include #include #include #ifdef WANT_STRLEN # define WANT_STRLEN 1 #else # define WANT_STRLEN 0 #endif #if WANT_STRLEN # define SHSTRLEN(str) strlen (str) #else # define SHSTRLEN(str) 0 #endif struct shentry { shentry (char const *str, const size_t hash) : m_refcnt (0), m_str (str), m_len (SHSTRLEN (str)), m_hash (hash) { } void *operator new (size_t n) { return g_slice_alloc (n); } void operator delete (void *ptr, size_t n) { g_slice_free1 (n, ptr); } size_t m_refcnt; char const * const m_str; size_t m_len; size_t m_hash; }; class shstr { public: static char const *insert (char const *str, size_t *size); static void erase (char const *str); static size_t refs (char const *str); static size_t strcnt (); static size_t memused (); protected: static size_t m_cnt; static size_t m_bucketcnt; typedef std::vector pairs; static pairs *m_buckets; static shentry *prepare (char const *str); static bool unref (char const *str); static const shentry *get (char const *str); static pairs::iterator find (char const *str, size_t n); static size_t hash (char const *str); public: void *operator new (size_t n) { return g_slice_alloc (n); } void operator delete (void *ptr, size_t n) { g_slice_free1 (n, ptr); } typedef size_t size_type; shstr (char const *str = ""); shstr (const shstr &rhs); ~shstr (); char const *c_str () const; size_type length () const; shstr &operator = (char const *rhs); shstr &operator = (const shstr &rhs); bool operator == (const shstr &rhs) const; bool operator != (const shstr &rhs) const; friend std::ostream &operator << (std::ostream &os, const shstr &str) { os << str.m_str; return os; } protected: char const *m_str; size_type m_len; void erase () { erase (m_str); m_str = NULL; } void insert (char const *newstr) { m_str = insert (newstr, &m_len); } }; #endif // SHSTR_H