File: ConstString.h

package info (click to toggle)
abyss 2.3.10-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,284 kB
  • sloc: cpp: 78,182; ansic: 6,512; makefile: 2,252; perl: 672; sh: 509; haskell: 412; python: 4
file content (115 lines) | stat: -rw-r--r-- 2,683 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#ifndef CONSTSTRING_H
#define CONSTSTRING_H 1

#include "Common/Hash.h"
#include "Common/HashFunction.h"
#include <cassert>
#include <cstring>
#include <ostream>
#include <string>

/** An immutable string that does not allocate resources. */
class cstring {
  public:
	cstring(const char* p) : m_p(p) { }
	cstring(const std::string& s) : m_p(s.c_str()) { }

	/** Return the size of this string. */
	size_t size() const { return strlen(m_p); }

	/** Return a null-terminated sequence of characters. */
	const char* c_str() const { return m_p; }

	operator const char*() const { return m_p; }

	bool operator==(const cstring& o) const
	{
		return m_p == o.m_p || strcmp(m_p, o.m_p) == 0;
	}

	bool operator<(const cstring& o) const
	{
		return m_p != o.m_p && strcmp(m_p, o.m_p) < 0;
	}

	friend std::ostream& operator<<(std::ostream& out,
			const cstring& o)
	{
		return out << o.m_p;
	}

  protected:
	const char* m_p;
};

/** An immutable string. */
class const_string : public cstring {
  public:
	const_string(const std::string& s)
		: cstring(strcpy(new char[s.size() + 1], s.c_str())) { }

#if __GXX_EXPERIMENTAL_CXX0X__
	const_string(const_string&& s) : cstring(s.m_p) { s.m_p = NULL; }
#endif

#if 0
	/* Should be like this, but... */
	const_string(const const_string& s)
		: cstring(strcpy(new char[s.size() + 1], s.c_str())) { }
#else
	/** Copy constructor.
	 * When a vector grows, libstdc++ calls the copy constructor for
	 * each element of the vector, which would invalidate any cstring
	 * that point to this const_string. To work around this issue, the
	 * new const_string gets the original data, and the old
	 * const_string gets the copy, which will probably be destructed
	 * soon. Making the copy is wasteful, but the C++ standard does
	 * not help us out here.
	 */
	const_string(const const_string& s) : cstring(s.c_str())
	{
		const_cast<const_string&>(s).m_p
			= strcpy(new char[s.size() + 1], s.c_str());
	}
#endif

	~const_string() { delete[] m_p; }

	const_string& operator=(const const_string& s)
	{
		assert(false);
		if (this == &s)
			return *this;
		assert(m_p != s.m_p);
		delete[] m_p;
		m_p = strcpy(new char[s.size() + 1], s.c_str());
		return *this;
	}

	void swap(const_string& s) { std::swap(m_p, s.m_p); }

  private:
	const_string();
	const_string(const char* s);
	const_string(const cstring&);
	bool operator==(const const_string& s);
};

namespace std {
	template <>
	inline void swap(const_string& a, const_string& b)
	{
		a.swap(b);
	}
}

NAMESPACE_STD_HASH_BEGIN
	template <> struct hash<cstring> {
		size_t operator()(const cstring& s) const
		{
			return hashmem(s.c_str(), strlen(s.c_str()));
		}
	};
NAMESPACE_STD_HASH_END

#endif