Sane C++ Libraries
C++ Platform Abstraction Libraries
String.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Foundation/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 {
51 }
52
56 [[nodiscard]] bool owns(StringView view) const;
57
62 [[nodiscard]] bool assign(StringView 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 StringView other) const { return view() == (other); }
98
102 [[nodiscard]] bool operator!=(const StringView other) const { return not operator==(other); }
103
107 [[nodiscard]] bool operator<(const StringView 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 {
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 StringEncoding encoding;
158 Buffer data;
159
160 String(StringEncoding encoding, SegmentHeader& header, uint32_t inlineCapacity);
161 String(Buffer&& otherData, StringEncoding encoding, SegmentHeader& header, uint32_t inlineCapacity);
162};
163
166template <int N>
167struct SC::SmallString : public String
168{
169 // Unfortunately we have to repeat all these overloads.
170 // 'using String::operator=' or 'using String::String' would invoke default memberwise copy
171 // constructors also for SmallString::header and buffer, that would cause a disaster.
172
173 SmallString(StringEncoding encoding = StringEncoding::Utf8) : String(encoding, header, N) {}
174 SmallString(const SmallString& other) : SmallString(other.getEncoding()) { String::operator=(other); }
176 String& operator=(const SmallString& other) { return String::operator=(other); }
177 String& operator=(SmallString&& other) { return String::operator=(move(other)); }
178 String& operator=(const String& other) { return String::operator=(other); }
179 String& operator=(String&& other) { return String::operator=(move(other)); }
180 SmallString(const String& other) : SmallString(other.getEncoding()) { String::operator=(other); }
181 SmallString(String&& other) : SmallString(other.getEncoding()) { String::operator=(move(other)); }
183 String& operator=(StringView view) { return String::operator=(view); }
184
185 SmallString(Buffer&& otherData, StringEncoding encoding) : String(move(otherData), encoding, header, N) {}
186
187 template <size_t Q>
188 SmallString(const char (&text)[Q]) : SmallString(StringView({text, Q - 1}, true, StringEncoding::Ascii))
189 {}
190
191 template <size_t Q>
192 String& operator=(const char (&text)[Q])
193 {
194 return String::operator=(text);
195 }
196
197 private:
198 SegmentHeader header;
199 char buffer[N];
200};
202
203namespace SC
204{
205template <int N>
206using StringNative = SmallString<N * sizeof(native_char_t)>;
207
208// Allows using this type across Plugin boundaries
213SC_COMPILER_EXTERN template struct SC_COMPILER_EXPORT SmallString<1024 * sizeof(native_char_t)>;
214} // 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
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
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition: PrimitiveTypes.h:38
StringEncoding
String Encoding (Ascii, Utf8, Utf16)
Definition: StringIterator.h:17
@ Ascii
Encoding is ASCII.
@ Utf8
Encoding is UTF8.
An heap allocated byte buffer that can optionally use an inline buffer.
Definition: Buffer.h:25
Wraps a SC::FileDescriptor to open it and use strings / buffers.
Definition: File.h:19
Execute fs operations { exists, copy, delete } for { files and directories }.
Definition: FileSystem.h:26
Basic class template that must be partially specialized for each type.
Definition: Reflection.h:195
Definition: Segment.h:11
size_t size() const
Returns current size.
Definition: Segment.h:150
bool isEmpty() const
Check if is empty (size() == 0)
Definition: Segment.h:141
const T * data() const SC_LANGUAGE_LIFETIME_BOUND
Access data owned by the segment or nullptr if segment is empty.
Definition: Segment.h:112
String with compile time configurable inline storage (small string optimization)
Definition: String.h:168
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
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 StringView other) const
Check if current String is same as other StringView.
Definition: String.h:97
bool operator!=(const String &other) const
Check if current String is different from other String.
Definition: String.h:92
bool operator<(const StringView other) const
Check if current String is smaller to another StringView (using StringView::compare)
Definition: String.h:107
bool assign(StringView sv)
Assigns a StringView to this String, replacing existing contents.
bool operator==(const String &other) const
Check if current String is same as other String.
Definition: String.h:87
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
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
String & operator=(StringView view)
Assigns (copy) contents of given StringView in current String.
String(StringView sv)
Builds String from a StringView.
Definition: String.h:37
String & operator=(const char(&text)[N])
Assigns an ascii string literal to current String.
Definition: String.h:134
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.
bool operator!=(const StringView other) const
Check if current String is different from other StringView.
Definition: String.h:102
bool owns(StringView view) const
Checks if the memory pointed by the StringView is owned by this String.
bool operator==(const char(&other)[N]) const
Check if current String is equal to the ascii string literal.
Definition: String.h:114
Non-owning view over a range of characters with UTF Encoding.
Definition: StringView.h:47