-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcppstr.hpp
More file actions
106 lines (85 loc) · 3.69 KB
/
cppstr.hpp
File metadata and controls
106 lines (85 loc) · 3.69 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
/*
* Copyright (c) 2023 Alex <uni@vrsal.xyz>
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <string>
#include <functional>
#define SLICE(s) (cppstr::slice { true ? s, false ? s})
class cppstr {
std::string m_string;
public:
using size = std::string::size_type;
cppstr(const char* str) : m_string(str) {}
cppstr(std::string const& str) : m_string(str) {}
cppstr(cppstr const& str) : m_string(str.m_string) {}
class index {
friend struct cppstr;
friend struct slice;
bool initialized = false;
int value = 0;
public:
index() = default;
index(int v) { value = v; initialized = true;}
operator int() const{ return value;}
bool operator==(int const& i) const { return value == i;}
bool operator>(int const& i) const { return value > i;}
bool operator<(int const& i) const { return value < i;}
bool operator>=(int const& i) const { return value >= i;}
bool operator<=(int const& i) const { return value <= i;}
};
struct slice {
index start{}, end{};
slice(index s, index e) : start(s), end(e){ }
slice(index s) : start(s){ }
slice() = default;
};
operator std::string&() { return m_string;}
operator std::string const&() const{ return m_string;}
char operator[](index const& idx) const {
if (idx >= 0)
return m_string[idx];
return m_string[m_string.length() + idx];
}
cppstr operator[](slice const& idx) const {
if (!idx.start.initialized && !idx.end.initialized)
return m_string;
if (idx.start == 0 && !idx.end.initialized)
return m_string;
if (idx.start == 0 && idx.end == 0)
return "";
int end = idx.end.value;
int start = idx.start.value;
if (!idx.end.initialized)
end = int(m_string.length());
if (!idx.start.initialized)
start = 0;
if (start < 0)
start = int(m_string.length()) + start;
if (end < 0)
end = int(m_string.length()) + end;
if (end <= start || start + (end - start) > m_string.length())
return "";
return m_string.substr(start, end - start);
}
size find(const char c, size start = 0) const { return m_string.find(c, start); }
size find(std::string const& str, size start = 0) const { return m_string.find(str, start); }
size rfind(const char c, size start = 0) const { return m_string.rfind(c, start); }
size rfind(std::string const& str, size start = 0) const { return m_string.rfind(str, start); }
bool empty() const { return m_string.empty();}
bool endswith(std::string const& str) const { return (*this)[{-int(str.length()), {}}] == str; }
bool startswith(std::string const& str) const { return (*this)[{0, int(str.length())}] == str; }
const char* c_str() const { return m_string.c_str();}
const char* data() const { return m_string.data();}
std::string const& str() const { return m_string;}
std::string& str() { return m_string;}
size length() const { return m_string.length(); }
bool operator==(const char* str) const { return m_string == str;}
bool operator==(std::string const& str) const { return m_string == str;}
bool operator==(cppstr const& str) const { return m_string == str.m_string;}
bool operator!=(const char* str) const { return m_string != str;}
bool operator!=(std::string const& str) const { return m_string != str;}
bool operator!=(cppstr const& str) const { return m_string != str.m_string;}
std::string::iterator begin() { return m_string.begin(); }
std::string::iterator end() { return m_string.end(); }
};