Sane C++ Libraries
C++ Platform Abstraction Libraries
Loading...
Searching...
No Matches
StringSpan.h
1// Copyright (c) Stefano Cristiano
2// SPDX-License-Identifier: MIT
3#pragma once
4#include "../Foundation/Result.h"
5#include "../Foundation/Span.h"
6
7namespace SC
8{
9#if SC_PLATFORM_WINDOWS
10#define SC_NATIVE_STR(str) L##str
11#else
12#define SC_NATIVE_STR(str) str
13#endif
14
16enum class StringEncoding : uint8_t
17{
18 Ascii = 0,
19 Utf8 = 1,
20 Utf16 = 2,
21#if SC_PLATFORM_WINDOWS
22 Native = Utf16,
23#else
24 Native = Utf8
25#endif
26};
27
31constexpr uint32_t StringEncodingGetSize(StringEncoding encoding) { return encoding == StringEncoding::Utf16 ? 2 : 1; }
32
36struct SC_COMPILER_EXPORT StringSpan
37{
38 // clang-format off
39
41 constexpr StringSpan(StringEncoding encoding = StringEncoding::Ascii) : text(nullptr), textSizeInBytes(0), encoding(static_cast<uint8_t>(encoding)), hasNullTerm(0) {}
42
47 constexpr StringSpan(Span<const char> text, bool nullTerm, StringEncoding encoding) : text(text.data()), textSizeInBytes(text.sizeInBytes()), encoding(static_cast<uint8_t>(encoding)), hasNullTerm(nullTerm ? 1 : 0) {}
48
50 template <size_t N>
51 constexpr StringSpan(const char (&str)[N]) : text(str), textSizeInBytes(N - 1), encoding(static_cast<uint8_t>(StringEncoding::Ascii)), hasNullTerm(true) {}
52
54 static constexpr StringSpan fromNullTerminated(const char* text, StringEncoding encoding) { return text == nullptr ? StringSpan(encoding) : StringSpan({text, ::strlen(text)}, true, encoding); }
55
56#if SC_PLATFORM_WINDOWS
57 constexpr StringSpan(Span<const wchar_t> textSpan, bool nullTerm, StringEncoding encoding = StringEncoding::Native) : textWide(textSpan.data()), textSizeInBytes(textSpan.sizeInBytes()), encoding(static_cast<uint8_t>(encoding)), hasNullTerm(nullTerm ? 1 : 0) {}
58
59 template <size_t N>
60 constexpr StringSpan(const wchar_t (&str)[N]) : textWide(str), textSizeInBytes((N - 1)* sizeof(wchar_t)), encoding(static_cast<uint8_t>(StringEncoding::Native)), hasNullTerm(true) {}
61 static constexpr StringSpan fromNullTerminated(const wchar_t* text, StringEncoding encoding) { return text == nullptr ? StringSpan(encoding) : StringSpan({text, ::wcslen(text)}, true); }
62#endif
63
64 // clang-format on
65
67 enum class Comparison
68 {
69 Smaller = -1,
70 Equals = 0,
71 Bigger = 1
72 };
73
75 [[nodiscard]] Comparison compare(StringSpan other) const;
76
77 [[nodiscard]] bool operator==(const StringSpan other) const { return compare(other) == Comparison::Equals; }
78 [[nodiscard]] bool operator!=(const StringSpan other) const { return compare(other) != Comparison::Equals; }
79 [[nodiscard]] bool operator<(const StringSpan other) const { return compare(other) == Comparison::Smaller; }
80
82 [[nodiscard]] Span<const char> toCharSpan() const { return {text, textSizeInBytes}; }
83
85 [[nodiscard]] constexpr bool isEmpty() const { return text == nullptr or textSizeInBytes == 0; }
86
88 [[nodiscard]] constexpr bool isNullTerminated() const { return hasNullTerm; }
89
91 [[nodiscard]] constexpr size_t sizeInBytes() const { return textSizeInBytes; }
92
95 [[nodiscard]] size_t sizeInBytesIncludingTerminator() const;
96
98 [[nodiscard]] constexpr StringEncoding getEncoding() const { return static_cast<StringEncoding>(encoding); }
99
101 [[nodiscard]] constexpr const char* bytesWithoutTerminator() const { return text; }
102
105 [[nodiscard]] const char* bytesIncludingTerminator() const;
106
110#if SC_PLATFORM_WINDOWS
111 [[nodiscard]] const wchar_t* getNullTerminatedNative() const { return textWide; }
112#else
113 [[nodiscard]] const char* getNullTerminatedNative() const { return text; }
114#endif
115
117 {
118 Span<native_char_t> writableSpan;
119 size_t length = 0;
120
121 StringSpan view() const { return {{writableSpan.data(), length}, true, StringEncoding::Native}; }
122 };
123
127
131 Result appendNullTerminatedTo(NativeWritable& string, bool removePreviousNullTerminator = true) const;
132
135 static uint32_t advanceUTF8(const char*& it, const char* end);
136
139 static uint32_t advanceUTF16(const char*& it, const char* end);
140
141 protected:
142 friend struct StringView;
143 union
144 {
145 const char* text;
146#if SC_PLATFORM_WINDOWS
147 const wchar_t* textWide;
148#endif
149 };
150
151 static constexpr size_t NumOptionBits = 3;
152 static constexpr size_t MaxLength = (~static_cast<size_t>(0)) >> NumOptionBits;
153
154 size_t textSizeInBytes : sizeof(size_t) * 8 - NumOptionBits;
155 size_t encoding : 2;
156 size_t hasNullTerm : 1;
157};
158
159} // namespace SC
unsigned char uint8_t
Platform independent (1) byte unsigned int.
Definition PrimitiveTypes.h:36
unsigned long size_t
Platform independent unsigned size type.
Definition PrimitiveTypes.h:56
unsigned int uint32_t
Platform independent (4) bytes unsigned int.
Definition PrimitiveTypes.h:38
An ascii string used as boolean result. SC_TRY macro forwards errors to caller.
Definition Result.h:12
View over a contiguous sequence of items (pointer + size in elements).
Definition Span.h:29
Definition StringSpan.h:117
An read-only view over a string (to avoid including Strings library when parsing is not needed).
Definition StringSpan.h:37
Comparison compare(StringSpan other) const
Ordering comparison between non-normalized StringView (operates on code points, not on utf graphemes)
constexpr StringSpan(const char(&str)[N])
Constructs a StringView with a null terminated string terminal.
Definition StringSpan.h:51
constexpr size_t sizeInBytes() const
Get size of the StringView in bytes.
Definition StringSpan.h:91
static constexpr StringSpan fromNullTerminated(const char *text, StringEncoding encoding)
Constructs a StringView from a null terminated string.
Definition StringSpan.h:54
Span< const char > toCharSpan() const
Obtain a const char Span from this StringView.
Definition StringSpan.h:82
const char * getNullTerminatedNative() const
Directly access the memory of this null terminated-StringView:
Definition StringSpan.h:113
const char * bytesIncludingTerminator() const
Directly access the memory of this null terminated-StringView.
constexpr StringEncoding getEncoding() const
Get encoding of this StringView.
Definition StringSpan.h:98
constexpr bool isEmpty() const
Return true if StringView is empty.
Definition StringSpan.h:85
constexpr StringSpan(Span< const char > text, bool nullTerm, StringEncoding encoding)
Construct a StringView from a Span of bytes.
Definition StringSpan.h:47
constexpr StringSpan(StringEncoding encoding=StringEncoding::Ascii)
Construct an empty StringView.
Definition StringSpan.h:41
Comparison
Result of ordering comparison done by StringSpan::compare.
Definition StringSpan.h:68
static uint32_t advanceUTF16(const char *&it, const char *end)
Decode a single UTF16 code point and advance the iterator.
constexpr bool isNullTerminated() const
Check if StringView is immediately followed by a null termination character.
Definition StringSpan.h:88
constexpr const char * bytesWithoutTerminator() const
Directly access the memory of this StringView.
Definition StringSpan.h:101
size_t sizeInBytesIncludingTerminator() const
Get size of the StringView in bytes, including null terminator (2 bytes on UTF16)
static uint32_t advanceUTF8(const char *&it, const char *end)
Decode a single UTF8 code point and advance the iterator.
Result writeNullTerminatedTo(NativeWritable &string) const
Writes this Span to a destination Span, using native encoding and null-terminating it.
Result appendNullTerminatedTo(NativeWritable &string, bool removePreviousNullTerminator=true) const
Appends this Span to a destination Span, using native encoding and null-terminating it.
Non-owning view over a range of characters with UTF Encoding.
Definition StringView.h:46