ZeroErr
Loading...
Searching...
No Matches
string.h
Go to the documentation of this file.
1#pragma once
2
3// libc++ offers compatibility-only transitive includes through C++20.
4// Suppress those while loading our explicit dependencies, then restore the
5// caller's setting. This does not change standard-library types or ABI.
6#pragma push_macro("_LIBCPP_REMOVE_TRANSITIVE_INCLUDES")
7#ifndef _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
8#define _LIBCPP_REMOVE_TRANSITIVE_INCLUDES
9#endif
10
11
12#include <cstddef>
13#include <functional>
14#include <type_traits>
15#include <utility>
16
17namespace zeroerr {
18class StringBuffer;
19namespace detail {
20template <class T>
21struct StringLike {
22 template <class U>
23 static auto test(int)
24 -> decltype(static_cast<const char*>(std::declval<const U&>().data()),
25 static_cast<std::size_t>(std::declval<const U&>().size()), std::true_type{});
26 template <class>
27 static std::false_type test(...);
28 static constexpr bool value = decltype(test<T>(0))::value;
29 template <class U>
30 static auto own(int)
31 -> decltype(std::declval<U&>().append(static_cast<const char*>(nullptr), std::size_t{}),
32 std::true_type{});
33 template <class>
34 static std::false_type own(...);
35 static constexpr bool owning = value && decltype(own<T>(0))::value;
36};
37} // namespace detail
38
39
40// Owning diagnostic text, independent of the standard string and stream headers.
41class String {
42public:
43 using size_type = std::size_t;
44 using value_type = char;
45 using iterator = char*;
46 using const_iterator = const char*;
47 static constexpr size_type npos = static_cast<size_type>(-1);
48
49 String() noexcept;
50 String(const char* text);
51 String(const char* text, size_type size);
52 String(size_type count, char value);
53 template <class T,
54 typename std::enable_if<
55 detail::StringLike<T>::value && !std::is_same<T, String>::value, int>::type = 0>
56 String(const T& text) : String(text.data(), text.size()) {}
57 template <class T,
58 typename std::enable_if<
59 detail::StringLike<T>::owning && !std::is_same<T, String>::value, int>::type = 0>
60 operator T() const {
61 return T(data_, size_);
62 }
63 template <class Iterator,
64 typename std::enable_if<!std::is_integral<Iterator>::value, int>::type = 0>
65 String(Iterator first, Iterator last) : String() {
66 for (; first != last; ++first) push_back(*first);
67 }
68 String(const String& other);
69 String(String&& other) noexcept;
70 ~String();
71 String& operator=(const String& other);
72 String& operator=(String&& other) noexcept;
73 String& operator=(const char* text);
74
75 const char* c_str() const noexcept { return data_; }
76 const char* data() const noexcept { return data_; }
77 char* data() noexcept { return data_; }
78 size_type size() const noexcept { return size_; }
79 size_type length() const noexcept { return size_; }
80 bool empty() const noexcept { return size_ == 0; }
81 size_type capacity() const noexcept { return capacity_; }
82 iterator begin() noexcept { return data_; }
83 iterator end() noexcept { return data_ + size_; }
84 const_iterator begin() const noexcept { return data_; }
85 const_iterator end() const noexcept { return data_ + size_; }
86 char& operator[](size_type i) noexcept { return data_[i]; }
87 const char& operator[](size_type i) const noexcept { return data_[i]; }
88 char& back() noexcept { return data_[size_ - 1]; }
89 const char& back() const noexcept { return data_[size_ - 1]; }
90
91 void clear() noexcept;
93 void resize(size_type size, char value = '\0');
94 String& append(const char* text, size_type size);
95 String& append(const char* text);
96 String& append(const String& text);
97 void push_back(char value);
98 String& operator+=(const String& text) { return append(text); }
99 String& operator+=(const char* text) { return append(text); }
100 String& operator+=(char value) {
101 push_back(value);
102 return *this;
103 }
104 int compare(const String& other) const noexcept;
105 size_type find(const String& text, size_type pos = 0) const noexcept;
106 size_type find(char value, size_type pos = 0) const noexcept;
107 size_type find_first_of(char value, size_type pos = 0) const noexcept {
108 return find(value, pos);
109 }
110 size_type find_last_of(char value, size_type pos = npos) const noexcept;
111 size_type rfind(const String& text, size_type pos = npos) const noexcept;
112 String substr(size_type pos = 0, size_type count = npos) const;
113 String& replace(size_type pos, size_type count, const String& text);
114
115private:
116 char local_[24];
117 char* data_;
118 size_type size_;
119 size_type capacity_;
120};
121
122inline bool operator==(const String& a, const String& b) noexcept { return a.compare(b) == 0; }
123inline bool operator!=(const String& a, const String& b) noexcept { return a.compare(b) != 0; }
124inline bool operator<(const String& a, const String& b) noexcept { return a.compare(b) < 0; }
125inline bool operator>(const String& a, const String& b) noexcept { return a.compare(b) > 0; }
126inline bool operator<=(const String& a, const String& b) noexcept { return a.compare(b) <= 0; }
127inline bool operator>=(const String& a, const String& b) noexcept { return a.compare(b) >= 0; }
128String operator+(const String& a, const String& b);
129
130template <class Stream, class T,
131 typename std::enable_if<std::is_same<typename std::decay<T>::type, String>::value &&
132 !std::is_same<Stream, StringBuffer>::value,
133 int>::type = 0>
134auto operator<<(Stream& stream, T&& text) -> decltype(stream.write(text.data(), text.size())) {
135 return stream.write(text.data(), text.size());
136}
137template <class Stream>
138Stream& operator>>(Stream& stream, String& text) {
139 text.clear();
140 int c = stream.peek();
141 while (c != -1 && (c == ' ' || c == '\t' || c == '\n' || c == '\r')) {
142 stream.get();
143 c = stream.peek();
144 }
145 while (c != -1 && c != ' ' && c != '\t' && c != '\n' && c != '\r') {
146 text.push_back(static_cast<char>(stream.get()));
147 c = stream.peek();
148 }
149 if (text.empty()) stream.setstate(Stream::failbit);
150 return stream;
151}
152template <class Stream>
153bool getline(Stream& stream, String& text) {
154 text.clear();
155 char c;
156 while (stream.get(c)) {
157 if (c == '\n') return true;
158 text.push_back(c);
159 }
160 return !text.empty();
161}
162} // namespace zeroerr
163namespace std {
164template <>
165struct hash<zeroerr::String> {
166 size_t operator()(const zeroerr::String& value) const noexcept {
167 size_t result = 2166136261u;
168 for (char c : value) result = (result ^ static_cast<unsigned char>(c)) * 16777619u;
169 return result;
170 }
171};
172} // namespace std
173
174#pragma pop_macro("_LIBCPP_REMOVE_TRANSITIVE_INCLUDES")
StringBuffer & write(const char *data, std::size_t size)
Definition buffer.cpp:5
Definition string.h:41
void resize(size_type size, char value='\0')
Definition string.cpp:63
char * iterator
Definition string.h:45
size_type find_first_of(char value, size_type pos=0) const noexcept
Definition string.h:107
char * data() noexcept
Definition string.h:77
const char & back() const noexcept
Definition string.h:89
String & operator+=(char value)
Definition string.h:100
const char * data() const noexcept
Definition string.h:76
size_type rfind(const String &text, size_type pos=npos) const noexcept
Definition string.cpp:117
size_type find_last_of(char value, size_type pos=npos) const noexcept
Definition string.cpp:109
~String()
Definition string.cpp:18
String substr(size_type pos=0, size_type count=npos) const
Definition string.cpp:127
const_iterator end() const noexcept
Definition string.h:85
const_iterator begin() const noexcept
Definition string.h:84
size_type length() const noexcept
Definition string.h:79
const char * c_str() const noexcept
Definition string.h:75
iterator end() noexcept
Definition string.h:83
iterator begin() noexcept
Definition string.h:82
char & back() noexcept
Definition string.h:88
String & operator+=(const char *text)
Definition string.h:99
void clear() noexcept
Definition string.cpp:50
const char * const_iterator
Definition string.h:46
size_type capacity() const noexcept
Definition string.h:81
String(Iterator first, Iterator last)
Definition string.h:65
String & append(const char *text, size_type size)
Definition string.cpp:69
size_type size() const noexcept
Definition string.h:78
void push_back(char value)
Definition string.cpp:92
void reserve(size_type capacity)
Definition string.cpp:54
bool empty() const noexcept
Definition string.h:80
char value_type
Definition string.h:44
char & operator[](size_type i) noexcept
Definition string.h:86
int compare(const String &other) const noexcept
Definition string.cpp:93
std::size_t size_type
Definition string.h:43
const char & operator[](size_type i) const noexcept
Definition string.h:87
String & replace(size_type pos, size_type count, const String &text)
Definition string.cpp:132
String() noexcept
Definition string.cpp:10
static constexpr size_type npos
Definition string.h:47
size_type find(const String &text, size_type pos=0) const noexcept
Definition string.cpp:98
String & operator=(const String &other)
Definition string.cpp:39
STL namespace.
Definition assert_text.cpp:5
bool operator!=(const String &a, const String &b) noexcept
Definition string.h:123
StringBuffer & operator<<(StringBuffer &buffer, const Printer &printer)
Definition print.h:331
String operator+(const String &a, const String &b)
Definition string.cpp:141
bool operator==(const String &a, const String &b) noexcept
Definition string.h:122
bool operator>=(const String &a, const String &b) noexcept
Definition string.h:127
Stream & operator>>(Stream &stream, String &text)
Definition string.h:138
bool getline(Stream &stream, String &text)
Definition string.h:153
bool operator<(const String &a, const String &b) noexcept
Definition string.h:124
bool operator>(const String &a, const String &b) noexcept
Definition string.h:125
bool operator<=(const String &a, const String &b) noexcept
Definition string.h:126
Definition string.h:21
static auto test(int) -> decltype(static_cast< const char * >(std::declval< const U & >().data()), static_cast< std::size_t >(std::declval< const U & >().size()), std::true_type{})
static constexpr bool value
Definition string.h:28
static std::false_type test(...)
static auto own(int) -> decltype(std::declval< U & >().append(static_cast< const char * >(nullptr), std::size_t{}), std::true_type{})
static constexpr bool owning
Definition string.h:35
static std::false_type own(...)
Definition dbg.h:21