Repository navigation
Expand file tree
/
Copy pathConstString.h
More file actions
113 lines (94 loc) 路 2.57 KB
/
Copy pathConstString.h
File metadata and controls
113 lines (94 loc) 路 2.57 KB
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
#ifndef CONSTSTRING_H
#define CONSTSTRING_H 1
#include "Common/HashFunction.h"
#include <cassert>
#include <cstring>
#include <functional>
#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);
}
template <> struct hash<cstring> {
size_t operator()(const cstring& s) const
{
return hashmem(s.c_str(), strlen(s.c_str()));
}
};
}
#endif