Skip to content

Commit 5202773

Browse files
committed
Day 63 my own string lib implementation
1 parent 282e92a commit 5202773

File tree

6 files changed

+543
-0
lines changed

6 files changed

+543
-0
lines changed

CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ set(CMAKE_CXX_FLAGS "-Wall -std=c++11 -g -pedantic")
1313

1414
foreach( sourcefile ${SOURCES} )
1515
get_filename_component( demo_name ${sourcefile} NAME_WE )
16+
if (${demo_name} STREQUAL "pstring")
17+
add_library(pstring ${sourcefile})
18+
continue()
19+
endif()
20+
if (${demo_name} STREQUAL "pUnitTest")
21+
add_library(pUnitTest ${sourcefile})
22+
continue()
23+
endif()
1624
add_executable( ${demo_name} ${sourcefile} )
25+
if (${demo_name} STREQUAL "pstring_test")
26+
target_link_libraries (${demo_name} pstring pUnitTest)
27+
endif()
28+
continue()
29+
endif()
1730
endforeach( sourcefile ${SOURCES} )
1831

include/pUnitTest.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Unit Test
2+
// A simple unit test class
3+
// by Ravi Mandliya
4+
//
5+
#include "pUnitTest.h"
6+
7+
UTest::UTest( const char * _test_str ) {
8+
init(_test_str);
9+
}
10+
11+
void UTest::init( const char * _tstr ) {
12+
_test_str = _tstr;
13+
_pass_count = _fail_count = 0;
14+
}
15+
16+
void UTest::test ( const char * description, const int flag ) {
17+
const char * pf = nullptr;
18+
if (flag) {
19+
pf = __ut_pstr;
20+
++_pass_count;
21+
} else {
22+
pf = __ut_fstr;
23+
++_fail_count;
24+
}
25+
if(!_summary_flag) printf("%s: %s -> %s\n", _test_str, description, pf);
26+
}
27+
28+
void UTest::report() const {
29+
printf("%s: pass: %ld, fail: %ld\n", _test_str, pass_count(), fail_count());
30+
fflush(stdout);
31+
}

include/pUnitTest.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// pUnitTest.h
2+
// A simple unit test class
3+
4+
#ifndef __PSTRING_UTEST__
5+
#define __PSTRING_UTEST__
6+
7+
#include <cstdio>
8+
9+
#define _UTest_VERSION "1.0.0"
10+
11+
const static char * __ut_pstr = "pass";
12+
const static char * __ut_fstr = "fail";
13+
14+
class UTest {
15+
unsigned long int _pass_count = 0;
16+
unsigned long int _fail_count = 0;
17+
bool _summary_flag = false;
18+
19+
const char * _test_str = nullptr;
20+
21+
UTest( UTest & ); // no copy constructor
22+
UTest operator = ( UTest & ); // no assignment operator
23+
UTest(){} // no default constructor
24+
public:
25+
static const char * version() { return _UTest_VERSION; }
26+
27+
UTest( const char * );
28+
void init ( const char * );
29+
bool summary ( bool flag ) { return _summary_flag = flag; }
30+
bool summary ( ) { return _summary_flag; }
31+
unsigned long int pass_count() const { return _pass_count; }
32+
unsigned long int fail_count() const { return _fail_count; }
33+
void test ( const char * description, const int flag );
34+
void report() const;
35+
};
36+
37+
#endif /* defined(__PSTRING_UTEST__) */

include/pstring.cpp

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
/**
2+
* A string library for practice
3+
* Ravi Mandliya
4+
*/
5+
6+
#include "pstring.h"
7+
8+
using String = algo::String;
9+
10+
String::String( ) {
11+
_reset();
12+
}
13+
14+
String::String( const char * s ) {
15+
_copy_str(s);
16+
}
17+
18+
String::String( const String & str ) {
19+
_copy_str(str);
20+
}
21+
22+
String::String( String && other ) noexcept {
23+
_reset();
24+
_str = other._str;
25+
_str_len = other._str_len;
26+
other._str = nullptr;
27+
other._str_len = 0;
28+
other._reset();
29+
}
30+
31+
String::~String() {
32+
_reset();
33+
}
34+
35+
void String::_alloc_cstr(size_t sz) {
36+
if ( _str ) {
37+
_reset();
38+
}
39+
_str_len = ( sz > algo::_PSTRING_MAX_LEN ) ? algo::_PSTRING_MAX_LEN : sz;
40+
_str = new char[_str_len + 1]();
41+
}
42+
43+
void String::_reset() {
44+
if ( _str ) {
45+
delete [] _str;
46+
}
47+
_str = nullptr;
48+
_str_len = 0;
49+
}
50+
51+
void String::_swap( String & other ) {
52+
std::swap( _str, other._str );
53+
std::swap( _str_len, other._str_len );
54+
}
55+
56+
const char * String::c_str() const {
57+
return _str;
58+
}
59+
60+
void String::_copy_str( const char * s ) {
61+
if ( s ) {
62+
size_t sz = strnlen( s, algo::_PSTRING_MAX_LEN );
63+
_alloc_cstr( sz );
64+
strncpy( _str, s, sz );
65+
}
66+
}
67+
68+
bool String::_have_value() const {
69+
if ( _str ) {
70+
return true;
71+
}
72+
return false;
73+
}
74+
75+
size_t String::_char_find( const char & match, size_t pos ) const {
76+
if ( pos >= _str_len ) {
77+
return algo::npos;
78+
}
79+
for ( size_t i = 0; _str[i + pos]; ++i ) {
80+
if ( _str[i] == match ) {
81+
return i;
82+
}
83+
}
84+
return algo::npos;
85+
}
86+
87+
void String::_char_replace( const char & match_char,
88+
const char & replace_char) {
89+
for ( size_t i = 0; _str[i]; ++i ) {
90+
if ( _str[i] == match_char ) {
91+
_str[i] = replace_char;
92+
return;
93+
}
94+
}
95+
}
96+
97+
String & String::operator = ( String other ) {
98+
_swap(other);
99+
return *this;
100+
}
101+
102+
String & String::operator += ( const char * s ) {
103+
if ( s ) {
104+
size_t len1 = strlen(s);
105+
if ( len1 < 1 ) {
106+
return *this;
107+
}
108+
size_t new_len = len1 + _str_len;
109+
new_len = (new_len > algo::_PSTRING_MAX_LEN ) ? algo::_PSTRING_MAX_LEN : new_len;
110+
char * buf = new char[new_len + 1];
111+
if (_str_len && _str ) {
112+
memcpy(buf, _str, _str_len);
113+
}
114+
memcpy(buf + _str_len, s, len1);
115+
_copy_str( buf );
116+
delete[] buf;
117+
}
118+
return * this;
119+
}
120+
121+
String & String::operator += ( const String & s ) {
122+
operator+=( s.c_str() );
123+
return * this;
124+
}
125+
126+
const char String::operator [] (const size_t index) const {
127+
if ( index >= this->length() ) return 0;
128+
return _str[index];
129+
}
130+
131+
bool String::operator == ( const String & s ) const {
132+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) == 0 ) {
133+
return true;
134+
}
135+
else return false;
136+
}
137+
138+
bool String::operator != ( const String & s ) const {
139+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) != 0 ) {
140+
return true;
141+
}
142+
else return false;
143+
}
144+
145+
bool String::operator >= ( const String & s ) const {
146+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) >= 0 ) {
147+
return true;
148+
}
149+
else return false;
150+
}
151+
152+
bool String::operator <= ( const String & s ) const {
153+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) <= 0 ) {
154+
return true;
155+
}
156+
else return false;
157+
}
158+
159+
bool String::operator < ( const String & s ) const {
160+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) < 0 ) {
161+
return true;
162+
}
163+
else return false;
164+
}
165+
166+
bool String::operator > ( const String & s ) const {
167+
if ( std::strncmp(this->c_str(), s.c_str(), algo::_PSTRING_MAX_LEN ) > 0 ) {
168+
return true;
169+
}
170+
else return false;
171+
}
172+
173+
String::operator const char * () const {
174+
return this->c_str();
175+
}
176+
177+
String String::lower() const {
178+
String rs = *this;
179+
for ( size_t i = 0; rs._str[i]; ++i ) {
180+
rs._str[i] = tolower(rs._str[i]);
181+
}
182+
return rs;
183+
}
184+
185+
String String::upper() const {
186+
String rs = *this;
187+
for ( size_t i = 0; rs._str[i]; ++i ) {
188+
rs._str[i] = toupper(rs._str[i]);
189+
}
190+
return rs;
191+
}
192+
193+
const char & String::front() const {
194+
return _str[0];
195+
}
196+
197+
const char & String::back() const {
198+
return _str[_str_len - 1];
199+
}
200+
201+
String String::substr( size_t pos, size_t len ) const {
202+
String rs;
203+
char * buf;
204+
if ( len + 1 > algo::_PSTRING_MAX_LEN ||
205+
( pos + len ) > algo::_PSTRING_MAX_LEN ) {
206+
return rs;
207+
}
208+
if ( _str_len - pos < len ) {
209+
return rs;
210+
}
211+
if (!_str) {
212+
return rs;
213+
}
214+
buf = new char[ len + 1 ]();
215+
memcpy( buf, _str + pos, len );
216+
rs = buf;
217+
delete[] buf;
218+
return rs;
219+
}
220+
221+
size_t String::find( const char * s, size_t pos ) const {
222+
size_t index = algo::npos;
223+
if ( pos >= _str_len ) {
224+
return index;
225+
}
226+
char * sub = strstr( _str + pos, s );
227+
if ( sub ) {
228+
return ( sub - _str );
229+
}
230+
return algo::npos;
231+
}
232+
233+
size_t String::find( const String & match, size_t pos ) const {
234+
return find( match.c_str(), pos);
235+
}
236+
237+
size_t String::find( char c, size_t pos ) const {
238+
return _char_find(c, pos);
239+
}
240+
241+
String String::replace( size_t pos, size_t len, const char * str ) {
242+
String res;
243+
if ( ( pos >= _str_len ) || ( pos + len >= _str_len ) ) {
244+
return res;
245+
}
246+
String s1 = pos > 0 ? substr( 0, pos ) : "" ;
247+
String s2 = str;
248+
String s3 = substr( pos + len, _str_len - (pos+len));
249+
String s4 = s1 + s2 + s3;
250+
return s4;
251+
}
252+
253+
String String::replace( size_t pos, size_t len, const String & str) {
254+
return replace(pos, len, str.c_str());
255+
}
256+
257+
int String::compare( const char * str ) const {
258+
return strncmp( this->c_str(), str, algo::_PSTRING_MAX_LEN );
259+
}
260+
261+
int String::compare( const String & str ) const noexcept {
262+
return strncmp( this->c_str(), str.c_str(), algo::_PSTRING_MAX_LEN );
263+
}
264+
265+
String algo::operator + ( const String & lhs, const String & rhs ) {
266+
String ans = lhs;
267+
ans += rhs;
268+
return ans;
269+
}
270+
271+
String algo::operator + ( const String & lhs, const char * rhs ) {
272+
String ans = lhs;
273+
ans += rhs;
274+
return ans;
275+
}

0 commit comments

Comments
 (0)