-
Notifications
You must be signed in to change notification settings - Fork 4
/
string.h
101 lines (81 loc) · 2.82 KB
/
string.h
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
#pragma once
#include "global.h" // stdlib.h is enough, but I want to ensure the malloc seatbelt is enabled.
#include "array.h" // some functions return array<string>
#include <string.h> // memcpy
#include <ctype.h> // tolower
class string;
typedef const string & cstring;
typedef array<string> stringlist;
//static inline size_t strlen(cstring str);
class string {
private:
char * data;
static char* clone(const char * str) { return strdup(str ? str : ""); }
string(char * str, int) { this->data = str; }
public:
string() { this->data = clone(NULL); }
string(const char * str) { this->data = strdup(str); }
string(const string& other) { this->data = strdup(other.data); }
#ifdef HAVE_MOVE
string(string&& other) { this->data = other.data; other.data = NULL; }
#endif
static string take(char* str) { return string(str, 0); }
~string() { free(this->data); }
string& operator=(const char * str) { free(this->data); this->data=clone(str); return *this; }
string& operator=(string other) // copying as the argument can sometimes avoid copying entirely
{
free(this->data);
this->data = other.data;
other.data = NULL;
return *this;
}
string& operator+=(const char * str)
{
if (!str) return *this;
char* newstr = malloc(strlen(this->data)+strlen(str)+1);
strcpy(newstr, this->data); strcat(newstr, str);
free(this->data);
this->data = newstr;
return *this;
}
string& operator+=(char * str) { return this->operator+=((const char*)str); }
string& operator+=(cstring other) { return this->operator+=((const char*)other); }
string operator+(const char * other) const { string ret(*this); ret+=other; return ret; }
string operator+(char * other) const { string ret(*this); ret+=other; return ret; }
string operator+(cstring other) const { string ret(*this); ret+=other; return ret; }
bool operator==(const char * other) const { return (!strcmp(this->data, other)); }
bool operator==(const string& other) const { return (!strcmp(this->data, other.data)); }
char& operator[](size_t index) const { return this->data[index]; }
operator char * () const { return this->data; }
size_t len() const { return strlen(this->data); }
operator bool() const { return (*this->data); }
size_t hash() const
{
const char * str = data;
size_t ret = 0;
while (*str)
{
ret *= 101;
ret += *str;
str++;
}
return ret;
}
string lower() const
{
string ret = *this;
for (size_t i=0;ret[i];i++) { ret[i]=tolower(ret[i]); }
return ret;
}
};
static inline void strlen(cstring){}//don't do this - use .len()
//I can't force use to give an error, but strlen() is expected to return a value, and using a void will throw.
#define S (string)
inline string to_string(int n)
{
char out[16];
sprintf(out, "%i", n);
return out;
}
inline string to_string(const char * str) { return str; }
#define string(x) to_string(x)