File: cl_string.h

package info (click to toggle)
cln 0.98-7.1
  • links: PTS
  • area: main
  • in suites: slink
  • size: 12,188 kB
  • ctags: 15,282
  • sloc: cpp: 71,545; ansic: 12,015; asm: 8,431; sh: 3,159; makefile: 886; lisp: 64
file content (168 lines) | stat: -rw-r--r-- 5,461 bytes parent folder | download
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Strings.

#ifndef _CL_STRING_H
#define _CL_STRING_H

#include "cl_object.h"
#include "cl_io.h"
#include "cl_abort.h"
#include <string.h>

// General, reference counted and garbage collected strings.
struct cl_heap_string : public cl_heap {
private:
	unsigned long length;	// length (in characters)
	char data[1];		// the characters, plus a '\0' at the end
	// Standard allocation disabled.
	void* operator new (size_t size) { (void)size; cl_abort(); return NULL; }
	// Standard deallocation disabled.
	void operator delete (void* ptr) { (void)ptr; cl_abort(); }
	// No default constructor.
	cl_heap_string ();
private:
// Friend declarations. They are for the compiler. Just ignore them.
	friend class cl_string;
	friend cl_heap_string* cl_make_heap_string (unsigned long len);
	friend cl_heap_string* cl_make_heap_string (const char * s);
	friend cl_heap_string* cl_make_heap_string (const char * ptr, unsigned long len);
	friend cl_string operator+ (const cl_string& str1, const cl_string& str2);
	friend cl_string operator+ (const char* str1, const cl_string& str2);
	friend cl_string operator+ (const cl_string& str1, const char* str2);
};

struct cl_string : public cl_gcpointer {
public:
	// Conversion to simple string.
	// NOTE! The resulting pointer is valid only as long as the string
	// is live, i.e. you must keep the string in a variable until you
	// are done with the pointer to the characters.
	const char * asciz () const
	{
		return &((cl_heap_string*)pointer)->data[0];
	}
	// Return the length (number of characters).
	unsigned long length () const
	{
		return ((cl_heap_string*)pointer)->length;
	}
	// Return a specific character.
	char operator[] (unsigned long i) const
	{
		if (!(i < length())) cl_abort(); // Range check.
		return ((cl_heap_string*)pointer)->data[i];
	}
	// New ANSI C++ compilers also want the following.
	char operator[] (unsigned int i) const
		{ return operator[]((unsigned long)i); }
	char operator[] (long i) const
		{ return operator[]((unsigned long)i); }
	char operator[] (int i) const
		{ return operator[]((unsigned long)i); }
	// Constructors.
	cl_string ();
	cl_string (const cl_string&);
	cl_string (const char * s);
	cl_string (const char * ptr, unsigned long len);
	// Assignment operators.
	cl_string& operator= (const cl_string&);
	cl_string& operator= (const char *);
	// Private pointer manipulations.
	operator cl_heap_string* () const;
	cl_string (cl_heap_string* str) { pointer = str; }
	cl_string (cl_private_thing p) : cl_gcpointer (p) {}
};
CL_DEFINE_COPY_CONSTRUCTOR2(cl_string,cl_gcpointer)
CL_DEFINE_ASSIGNMENT_OPERATOR(cl_string,cl_string)
inline cl_string::cl_string (const char * s)
{
	pointer = cl_make_heap_string(s);
}
inline cl_string& cl_string::operator= (const char * s)
{
	cl_heap_string* tmp = cl_make_heap_string(s);
	cl_dec_refcount(*this);
	pointer = tmp;
	return *this;
}

// Length.
inline unsigned long strlen (const cl_string& str)
{
	return str.length();
}
// Conversion to `const char *'.
inline const char * asciz (const char * s) { return s; }
inline const char * asciz (const cl_string& s) { return s.asciz(); }

// Comparison.
inline bool equal (const cl_string& str1, const cl_string& str2)
{
    return str1.length() == str2.length()
           && !strcmp(str1.asciz(), str2.asciz());
}
inline bool equal (const char * str1, const cl_string& str2)
{
    return !strcmp(str1, str2.asciz());
}
inline bool equal (const cl_string& str1, const char * str2)
{
    return !strcmp(str1.asciz(), str2);
}

// Private pointer manipulations. Never throw away a `struct cl_heap_string *'!
inline cl_string::operator cl_heap_string* () const
{
	cl_heap_string* hpointer = (cl_heap_string*)pointer;
	cl_inc_refcount(*this);
	return hpointer;
}
inline cl_string::cl_string ()
{
	extern cl_string cl_null_string;
	pointer = (cl_heap_string*) cl_null_string;
}
CL_REQUIRE(cl_st_null)

// Hash code.
extern unsigned long hashcode (const cl_string& str);

// Output.
extern void fprint (cl_ostream stream, const cl_string& str);
CL_DEFINE_PRINT_OPERATOR(cl_string)

// Input.

#ifdef CL_IO_IOSTREAM

// Reads a line. Up to delim. The delimiter character is not placed in the
// resulting string. The delimiter character is kept in the input stream.
// If EOF is encountered, the stream's eofbit is set.
extern cl_string cl_fget (cl_istream stream, char delim = '\n');

// Reads a line. Up to delim. The delimiter character is not placed in the
// resulting string. The delimiter character is extracted from the input stream.
// If EOF is encountered, the stream's eofbit is set.
extern cl_string cl_fgetline (cl_istream stream, char delim = '\n');

// Like above, but only up to n-1 characters. If n-1 characters were read
// before the delimiter character was seen, the stream's failbit is set.
extern cl_string cl_fget (cl_istream stream, int n, char delim = '\n');
extern cl_string cl_fgetline (cl_istream stream, int n, char delim = '\n');

// Skips whitespace and then reads a non-whitespace string.
// If stream.width() is greater than 0, at most stream.width()-1 non-whitespace
// characters are read. When done, stream.width(0) is called.
// If EOF is encountered, the stream's eofbit is set.
extern cl_istream operator>> (cl_istream stream, cl_string& str);

#endif

// Debugging support.
#ifdef CL_DEBUG
extern int cl_string_debug_module;
static void* cl_string_debug_dummy[] = { &cl_string_debug_dummy,
	&cl_string_debug_module
};
#endif

#endif /* _CL_STRING_H */