1 //////////////////////////////////////////////////////////////////////////////
4 // ADLib, Prop and their related set of tools and documentation are in the
5 // public domain. The author(s) of this software reserve no copyrights on
6 // the source code and any code generated using the tools. You are encouraged
7 // to use ADLib and Prop to develop software, in both academic and commercial
8 // settings, and are free to incorporate any part of ADLib and Prop into
11 // Although you are under no obligation to do so, we strongly recommend that
12 // you give away all software developed using our tools.
14 // We also ask that credit be given to us when ADLib and/or Prop are used in
15 // your programs, and that this notice be preserved intact in all the source
18 // This software is still under development and we welcome any suggestions
19 // and help from the users.
23 //////////////////////////////////////////////////////////////////////////////
30 #include <AD/strings/str.h>
31 #include <AD/strings/regexp.h>
33 ///////////////////////////////////////////////////////////////////////////////
34 // Allocator for the string objects
35 ///////////////////////////////////////////////////////////////////////////////
36 void * StringImpl::operator new(size_t, const char * s
, size_t len
, size_t cap
)
40 ///////////////////////////////////////////////////////////////////////////////
41 // Deallocator for the string objects
42 ///////////////////////////////////////////////////////////////////////////////
43 void StringImpl::operator delete (void * s
)
47 ///////////////////////////////////////////////////////////////////////////////
48 // Constructors and destructor
49 ///////////////////////////////////////////////////////////////////////////////
51 : impl(empty_string
? empty_string
: make_empty_string()) {}
53 String:: String(size_t initial_capacity
)
54 : impl(new StringImpl(initial_capacity
, 0)) {}
56 String:: String(char c
, size_t times
)
57 : impl(new StringImpl(times
+1,times
))
58 { memset(impl
->string
,c
,times
); impl
->string
[times
] = '\0'; }
60 String:: String(const char * s
, int len
)
61 : impl(new StringImpl(len
+1,len
))
62 { memcpy(impl
->string
,s
,len
); impl
->string
[len
] = '\0'; }
64 ///////////////////////////////////////////////////////////////////////////////
66 ///////////////////////////////////////////////////////////////////////////////
67 String
& String::operator = (const char * s
)
70 impl
= new StringImpl(len
+1,len
);
71 strcpy(impl
->string
,s
);
75 ///////////////////////////////////////////////////////////////////////////////
77 ///////////////////////////////////////////////////////////////////////////////
78 String
& String::splice(int location
, int len
, const char * s
, int size
)
82 String
& String::splice(int location
, int len
, char c
, int size
)
86 String
& String::splice(int location
, int len
, const String
& s
)
90 ///////////////////////////////////////////////////////////////////////////////
91 // Substring extraction
92 ///////////////////////////////////////////////////////////////////////////////
93 String
String::at(int left
, int length
) const
97 String
String::left(int length
) const
101 String
String::right(int length
) const
105 ///////////////////////////////////////////////////////////////////////////////
107 ///////////////////////////////////////////////////////////////////////////////
108 String
operator + (const String
& a
, const String
& b
)
109 { size_t new_len
= a
.impl
->len
+ b
.impl
->len
;
110 StringImpl s
= new StringImpl(new_len
+1,new_len
);
111 memcpy(s
->string
,a
.impl
->string
,a
.impl
->len
);
112 memcpy(s
->string
+ a
.impl
->len
, b
.impl
->string
, b
.impl
->len
);
113 s
->string
[new_len
] = '\0';
117 String
operator + (const String
& a
, const char * b
)
118 { size_t b_len
= strlen(b
);
119 size_t new_len
= a
.impl
->len
+ len
;
120 StringImpl s
= new StringImpl(new_len
+1,new_len
);
121 memcpy(s
->string
,a
.impl
->string
,a
.impl
->len
);
122 memcpy(s
->string
+ a
.impl
->len
, b
, b_len
);
123 s
->string
[new_len
] = '\0';
127 String
operator + (const char * a
, const String
& b
)
128 { size_t a_len
= strlen(a
);
129 size_t new_len
= a_len
+ b
.impl
->len
;
130 StringImpl s
= new StringImpl(new_len
+1,new_len
);
131 memcpy(s
->string
,a
,a_len
);
132 memcpy(s
->string
+ a_len
, b
.impl
->string
, b
.impl
->len
);
133 s
->string
[new_len
] = '\0';
137 ///////////////////////////////////////////////////////////////////////////////
139 ///////////////////////////////////////////////////////////////////////////////
140 String
String::operator * (int times
) const
141 { size_t my_length
= length();
142 size_t new_length
= my_length
* times
;
143 StringImpl
* s
= new StringImpl(new_length
+1,new_length
);
147 for (i
= times
- 1, p
= impl
->string
; i
>= 0; i
--)
148 { for (q
= p
+ my_length
, r
= impl
->string
; p
< q
; p
++, r
++)
155 ///////////////////////////////////////////////////////////////////////////////
157 ///////////////////////////////////////////////////////////////////////////////
158 String
& String::operator += (const String
& s
)
159 { copy_on_write (s
.impl
->len
);
160 memcpy(impl
->string
+ impl
->len
, s
->impl
->string
, s
.impl
->len
);
161 impl
->len
+= s
.impl
->len
;
162 impl
->string
[impl
->len
] = '\0';
166 String
& String::operator += (char c
)
167 { copy_on_write (s
.impl
->len
);
168 impl
->string
[impl
->len
++] = c
;
169 impl
->string
[impl
->len
] = '\0';
173 String
& String::operator += (const char * s
)
174 { size_t len
= strlen(s
);
176 memcpy(impl
->string
+ len
, s
->impl
->string
, len
);
178 impl
->string
[impl
->len
] = '\0';
182 ///////////////////////////////////////////////////////////////////////////////
184 ///////////////////////////////////////////////////////////////////////////////
185 int String::compare (const String
& s
) const
189 int String::compare (const char * s
, int len
) const
193 ///////////////////////////////////////////////////////////////////////////////
195 ///////////////////////////////////////////////////////////////////////////////
196 ostream
& operator << (ostream
& f
, const String
& s
)
197 { f
.write(s
.impl
->string
, s
.impl
->len
);
201 istream
& operator >> (ostream
& f
, String
& s
)