Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
String.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Memory/Buffer.h"
5#include "../Strings/StringView.h"
6
7namespace SC
8{
9struct SC_COMPILER_EXPORT String;
10template <int N>
11struct SmallString;
12namespace Reflection
13{
14template <typename T>
15struct Reflect;
16}
17} // namespace SC
18
21
29{
32 String(StringEncoding encoding = StringEncoding::Utf8) : encoding(encoding) {}
33
38
41 String(Buffer&& otherData, StringEncoding encoding);
42
47 template <size_t N>
48 String(const char (&text)[N])
49 {
50 SC_ASSERT_RELEASE(assign(StringView({text, N - 1}, true, StringEncoding::Ascii)));
51 }
52
56 [[nodiscard]] bool owns(StringSpan view) const;
57
62 [[nodiscard]] bool assign(StringSpan sv);
63
66 [[nodiscard]] StringEncoding getEncoding() const { return encoding; }
67
70 [[nodiscard]] size_t sizeInBytesIncludingTerminator() const { return data.size(); }
71
74 [[nodiscard]] const char* bytesIncludingTerminator() const { return data.data(); }
75
78 [[nodiscard]] bool isEmpty() const { return data.isEmpty(); }
79
82 [[nodiscard]] StringView view() const SC_LANGUAGE_LIFETIME_BOUND;
83
87 [[nodiscard]] bool operator==(const String& other) const { return view() == (other.view()); }
88
92 [[nodiscard]] bool operator!=(const String& other) const { return not operator==(other); }
93
97 [[nodiscard]] bool operator==(const StringSpan other) const { return view() == (other); }
98
102 [[nodiscard]] bool operator!=(const StringSpan other) const { return not operator==(other); }
103
107 [[nodiscard]] bool operator<(const StringSpan other) const { return view() < other; }
108
113 template <size_t N>
114 [[nodiscard]] bool operator==(const char (&other)[N]) const
115 {
116 return view() == other;
117 }
122 template <size_t N>
123 [[nodiscard]] bool operator!=(const char (&other)[N]) const
124 {
125 return view() != other;
126 }
127
133 template <size_t N>
134 String& operator=(const char (&text)[N])
135 {
136 SC_ASSERT_RELEASE(assign(StringView({text, N - 1}, true, StringEncoding::Ascii)));
137 return *this;
138 }
139
143
144 protected:
145 // TODO: nativeWritableBytesIncludingTerminator should be removed
146 [[nodiscard]] native_char_t* nativeWritableBytesIncludingTerminator();
147
148 // All these friendships are made to leverage writing directly to the Buffer
149 // but while still keeping it an implementation detail
150 friend struct StringTest;
151 friend struct StringBuilder;
152 friend struct StringConverter;
153 friend struct File;
154 friend struct FileSystem;
155 template <typename T>
156 friend struct Reflection::Reflect;
157 template <typename T>
158 friend struct GrowableBuffer;
159 StringEncoding encoding;
160 Buffer data;
161
162 String(StringEncoding encoding, uint32_t inlineCapacity);
163 String(Buffer&& otherData, StringEncoding encoding, uint32_t inlineCapacity);
164};
165
168template <int N>
169struct SC::SmallString : public String
170{
171 // Unfortunately we have to repeat all these overloads to set inline capacity and hasInlineData flag
172 SmallString(StringEncoding encoding = StringEncoding::Utf8) : String(encoding, N) {}
173 SmallString(const SmallString& other) : SmallString(other.getEncoding()) { String::operator=(other); }
174 SmallString(SmallString&& other) : SmallString(other.getEncoding()) { String::operator=(move(other)); }
175 String& operator=(const SmallString& other) { return String::operator=(other); }
176 String& operator=(SmallString&& other) { return String::operator=(move(other)); }
177
178 SmallString(const String& other) : SmallString(other.getEncoding()) { String::operator=(other); }
179 SmallString(String&& other) : SmallString(other.getEncoding()) { String::operator=(move(other)); }
180 SmallString(StringSpan other) : SmallString(other.getEncoding()) { String::operator=(move(other)); }
181 SmallString(Buffer&& otherData, StringEncoding encoding) : String(move(otherData), encoding, N) {}
182 template <size_t Q>
183 SmallString(const char (&text)[Q]) : SmallString(StringView({text, Q - 1}, true, StringEncoding::Ascii))
184 {}
185
186 private:
187 uint64_t inlineCapacity = N;
188 char buffer[N];
189};
191
192namespace SC
193{
194template <int N>
195using StringNative = SmallString<N * sizeof(native_char_t)>;
196
197// Allows using this type across Plugin boundaries
198SC_COMPILER_EXTERN template struct SC_COMPILER_EXPORT SmallString<64>;
199SC_COMPILER_EXTERN template struct SC_COMPILER_EXPORT SmallString<128 * sizeof(native_char_t)>;
200SC_COMPILER_EXTERN template struct SC_COMPILER_EXPORT SmallString<255 * sizeof(native_char_t)>;
201SC_COMPILER_EXTERN template struct SC_COMPILER_EXPORT SmallString<512 * sizeof(native_char_t)>;
202SC_COMPILER_EXTERN template struct SC_COMPILER_EXPORT SmallString<1024 * sizeof(native_char_t)>;
203
204// Enables File library from reading data from file descriptor into a String
205template <>
206struct GrowableBuffer<String> : public IGrowableBuffer
207{
208 String& string;
209 size_t numZeroes;
210 GrowableBuffer(String& string) : string(string) { numZeroes = StringEncodingGetSize(string.getEncoding()); }
211
212 virtual ~GrowableBuffer() override
213 {
214 if (string.data.size() + numZeroes <= string.data.capacity())
215 {
216 // Add null-terminator
217 (void)string.data.resize(string.data.size() + numZeroes, 0);
218 }
219 }
220 virtual DirectAccess getDirectAccess() override final
221 {
222 return {string.data.size(), string.data.capacity(), string.data.data()};
223 }
224 virtual bool tryGrowTo(size_t newSize) override final
225 {
226 if (newSize > 0)
227 {
228 return string.data.reserve(newSize + numZeroes) and string.data.resizeWithoutInitializing(newSize);
229 }
230 else
231 {
232 string.data.clear();
233 return true;
234 }
235 }
236};
237
238} // namespace SC
#define SC_COMPILER_EXPORT
Macro for symbol visibility in non-MSVC compilers.
Definition Compiler.h:78
#define SC_COMPILER_EXTERN
Define compiler-specific export macros for DLL visibility.
Definition Compiler.h:74
#define SC_ASSERT_RELEASE(e)
Assert expression e to be true.
Definition Assert.h:66
constexpr T && move(T &value)
Converts an lvalue to an rvalue reference.
Definition Compiler.h:269
unsigned long long uint64_t
Platform independent (8) bytes unsigned int.
Definition PrimitiveTypes.h:42
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:38
char native_char_t
The native char for the platform (wchar_t (4 bytes) on Windows, char (1 byte) everywhere else )
Definition PrimitiveTypes.h:34
constexpr uint32_t StringEncodingGetSize(StringEncoding encoding)
Returns the number of bytes to represent an utf unit in the given encoding.
Definition StringIterator.h:29
An heap allocated byte buffer that can optionally use an inline buffer.
Definition Buffer.h:29
Execute fs operations { exists, copy, delete } for { files and directories }.
Definition FileSystem.h:62
String with compile time configurable inline storage (small string optimization)
Definition StringFormat.h:12
Builds String out of a sequence of StringView or formatting through StringFormat.
Definition StringBuilder.h:16
Converts String to a different encoding (UTF8, UTF16).
Definition StringConverter.h:24
An read-only view over a string (to avoid including Strings library when parsing is not needed).
Definition StringSpan.h:31
Non-owning view over a range of characters with UTF Encoding.
Definition StringView.h:48
A non-modifiable owning string with associated encoding.
Definition String.h:29
StringView view() const SC_LANGUAGE_LIFETIME_BOUND
Obtain a null-terminated StringView from current String.
StringEncoding getEncoding() const
Get StringView encoding.
Definition String.h:66
bool operator!=(const String &other) const
Check if current String is different from other String.
Definition String.h:92
bool operator==(const String &other) const
Check if current String is same as other String.
Definition String.h:87
bool operator<(const StringSpan other) const
Check if current String is smaller to another StringView (using StringView::compare)
Definition String.h:107
bool operator!=(const char(&other)[N]) const
Check if current String is different from the ascii string literal.
Definition String.h:123
String(const char(&text)[N])
Builds String with a null terminated char string literal.
Definition String.h:48
bool owns(StringSpan view) const
Checks if the memory pointed by the StringView is owned by this String.
size_t sizeInBytesIncludingTerminator() const
Get length of the string in bytes (including null terminator bytes)
Definition String.h:70
String(StringEncoding encoding=StringEncoding::Utf8)
Builds an empty String with a given Encoding.
Definition String.h:32
bool operator!=(const StringSpan other) const
Check if current String is different from other StringView.
Definition String.h:102
String & operator=(const char(&text)[N])
Assigns an ascii string literal to current String.
Definition String.h:134
bool assign(StringSpan sv)
Assigns a StringView to this String, replacing existing contents.
bool operator==(const StringSpan other) const
Check if current String is same as other StringView.
Definition String.h:97
String & operator=(StringSpan view)
Assigns (copy) contents of given StringView in current String.
bool isEmpty() const
Check if String is empty.
Definition String.h:78
const char * bytesIncludingTerminator() const
Access current string content as read-only null-terminated const char*
Definition String.h:74
String(Buffer &&otherData, StringEncoding encoding)
Builds a String from a buffer ensuring zero termination.
String(StringSpan sv)
Builds String from a StringView.
Definition String.h:37
bool operator==(const char(&other)[N]) const
Check if current String is equal to the ascii string literal.
Definition String.h:114