1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4#pragma once
5#include <string_view>
6#include "slint_string_internal.h"
7
8namespace slint {
9
10/// A string type used by the Slint run-time.
11///
12/// SharedString uses implicit data sharing to make it efficient to pass around copies. When
13/// copying, a reference to the data is cloned, not the data itself.
14///
15/// The class provides constructors from std::string_view as well as the automatic conversion to
16/// a std::string_view.
17///
18/// For convenience, it's also possible to convert a number to a string using
19/// SharedString::from_number(double).
20///
21/// Under the hood the string data is UTF-8 encoded and it is always terminated with a null
22/// character.
23struct SharedString
24{
25 /// Creates an empty default constructed string.
26 SharedString() { cbindgen_private::slint_shared_string_from_bytes(out: this, bytes: "", len: 0); }
27 /// Creates a new SharedString from the string view \a s. The underlying string data
28 /// is copied.
29 SharedString(std::string_view s)
30 {
31 cbindgen_private::slint_shared_string_from_bytes(out: this, bytes: s.data(), len: s.size());
32 }
33 /// Creates a new SharedString from the null-terminated string pointer \a s. The underlying
34 /// string data is copied. It is assumed that the string is UTF-8 encoded.
35 SharedString(const char *s) : SharedString(std::string_view(s)) { }
36 /// Creates a new SharedString from the null-terminated string pointer \a s. The underlying
37 /// string data is copied.
38 SharedString(const char8_t *s) : SharedString(reinterpret_cast<const char *>(s)) { }
39 /// Creates a new SharedString from the string view \a s. The underlying string data is copied.
40 SharedString(std::u8string_view s)
41 {
42 cbindgen_private::slint_shared_string_from_bytes(
43 out: this, bytes: reinterpret_cast<const char *>(s.data()), len: s.size());
44 }
45 /// Creates a new SharedString from \a other.
46 SharedString(const SharedString &other)
47 {
48 cbindgen_private::slint_shared_string_clone(out: this, ss: &other);
49 }
50 /// Destroys this SharedString and frees the memory if this is the last instance
51 /// referencing it.
52 ~SharedString() { cbindgen_private::slint_shared_string_drop(ss: this); }
53 /// Assigns \a other to this string and returns a reference to this string.
54 SharedString &operator=(const SharedString &other)
55 {
56 cbindgen_private::slint_shared_string_drop(ss: this);
57 cbindgen_private::slint_shared_string_clone(out: this, ss: &other);
58 return *this;
59 }
60 /// Assigns the string view \a s to this string and returns a reference to this string.
61 /// The underlying string data is copied. It is assumed that the string is UTF-8 encoded.
62 SharedString &operator=(std::string_view s)
63 {
64 cbindgen_private::slint_shared_string_drop(ss: this);
65 cbindgen_private::slint_shared_string_from_bytes(out: this, bytes: s.data(), len: s.size());
66 return *this;
67 }
68 /// Assigns null-terminated string pointer \a s to this string and returns a reference
69 /// to this string. The underlying string data is copied. It is assumed that the string
70 /// is UTF-8 encoded.
71 SharedString &operator=(const char *s) { return *this = std::string_view(s); }
72
73 /// Move-assigns \a other to this SharedString instance.
74 SharedString &operator=(SharedString &&other)
75 {
76 std::swap(a&: inner, b&: other.inner);
77 return *this;
78 }
79
80 /// Provides a view to the string data. The returned view is only valid as long as at
81 /// least this SharedString exists.
82 operator std::string_view() const { return cbindgen_private::slint_shared_string_bytes(ss: this); }
83 /// Provides a raw pointer to the string data. The returned pointer is only valid as long as at
84 /// least this SharedString exists.
85 auto data() const -> const char * { return cbindgen_private::slint_shared_string_bytes(ss: this); }
86 /// Size of the string, in bytes. This excludes the terminating null character.
87 std::size_t size() const { return std::string_view(*this).size(); }
88
89 /// Returns a pointer to the first character. It is only safe to dereference the pointer if the
90 /// string contains at least one character.
91 const char *begin() const { return data(); }
92 /// Returns a point past the last character of the string. It is not safe to dereference the
93 /// pointer, but it is suitable for comparison.
94 const char *end() const
95 {
96 std::string_view view(*this);
97 return view.data() + view.size();
98 }
99
100 /// \return true if the string contains no characters; false otherwise.
101 bool empty() const { return std::string_view(*this).empty(); }
102
103 /// \return true if the string starts with the specified prefix string; false otherwise
104 bool starts_with(std::string_view prefix) const
105 {
106 return std::string_view(*this).substr(pos: 0, n: prefix.size()) == prefix;
107 }
108
109 /// \return true if the string ends with the specified prefix string; false otherwise
110 bool ends_with(std::string_view prefix) const
111 {
112 std::string_view self_view(*this);
113 return self_view.size() >= prefix.size()
114 && self_view.compare(pos1: self_view.size() - prefix.size(), n1: std::string_view::npos,
115 str: prefix)
116 == 0;
117 }
118
119 /// Creates a new SharedString from the given number \a n. The string representation of the
120 /// number uses a minimal formatting scheme: If \a n has no fractional part, the number will be
121 /// formatted as an integer.
122 ///
123 /// For example:
124 /// \code
125 /// auto str = slint::SharedString::from_number(42); // creates "42"
126 /// auto str2 = slint::SharedString::from_number(100.5) // creates "100.5"
127 /// \endcode
128 static SharedString from_number(double n) { return SharedString(n); }
129
130 /// Returns the lowercase equivalent of this string, as a new SharedString.
131 ///
132 /// For example:
133 /// \code
134 /// auto str = slint::SharedString("Hello");
135 /// auto str2 = str.to_lowercase(); // creates "hello"
136 /// \endcode
137 SharedString to_lowercase() const
138 {
139 auto out = SharedString();
140 cbindgen_private::slint_shared_string_to_lowercase(out: &out, ss: this);
141 return out;
142 }
143
144 /// Returns the uppercase equivalent of this string, as a new SharedString.
145 ///
146 /// For example:
147 /// \code
148 /// auto str = slint::SharedString("Hello");
149 /// auto str2 = str.to_uppercase(); // creates "HELLO"
150 /// \endcode
151 SharedString to_uppercase() const
152 {
153 auto out = SharedString();
154 cbindgen_private::slint_shared_string_to_uppercase(out: &out, ss: this);
155 return out;
156 }
157
158 /// Returns true if \a a is equal to \a b; otherwise returns false.
159 friend bool operator==(const SharedString &a, const SharedString &b)
160 {
161 return std::string_view(a) == std::string_view(b);
162 }
163 /// Returns true if \a a is not equal to \a b; otherwise returns false.
164 friend bool operator!=(const SharedString &a, const SharedString &b)
165 {
166 return std::string_view(a) != std::string_view(b);
167 }
168
169 /// Returns true if \a a is lexicographically less than \a b; false otherwise.
170 friend bool operator<(const SharedString &a, const SharedString &b)
171 {
172 return std::string_view(a) < std::string_view(b);
173 }
174 /// Returns true if \a a is lexicographically less or equal than \a b; false otherwise.
175 friend bool operator<=(const SharedString &a, const SharedString &b)
176 {
177 return std::string_view(a) <= std::string_view(b);
178 }
179 /// Returns true if \a a is lexicographically greater than \a b; false otherwise.
180 friend bool operator>(const SharedString &a, const SharedString &b)
181 {
182 return std::string_view(a) > std::string_view(b);
183 }
184 /// Returns true if \a a is lexicographically greater or equal than \a b; false otherwise.
185 friend bool operator>=(const SharedString &a, const SharedString &b)
186 {
187 return std::string_view(a) >= std::string_view(b);
188 }
189
190 /// Writes the \a shared_string to the specified \a stream and returns a reference to the
191 /// stream.
192 friend std::ostream &operator<<(std::ostream &stream, const SharedString &shared_string)
193 {
194 return stream << std::string_view(shared_string);
195 }
196
197 /// Concatenates \a a and \a and returns the result as a new SharedString.
198 friend SharedString operator+(const SharedString &a, std::string_view b)
199 {
200 SharedString a2 = a;
201 return a2 += b;
202 }
203 /// Move-concatenates \a b to \a and returns a reference to \a a.
204 friend SharedString operator+(SharedString &&a, std::string_view b)
205 {
206 a += b;
207 return a;
208 }
209 /// Appends \a other to this string and returns a reference to this.
210 SharedString &operator+=(std::string_view other)
211 {
212 cbindgen_private::slint_shared_string_append(self_: this, bytes: other.data(), len: other.size());
213 return *this;
214 }
215
216private:
217 /// Use SharedString::from_number
218 explicit SharedString(double n) { cbindgen_private::slint_shared_string_from_number(out: this, n); }
219 void *inner; // opaque
220};
221
222namespace private_api {
223inline cbindgen_private::Slice<uint8_t> string_to_slice(std::string_view str)
224{
225 return cbindgen_private::Slice<uint8_t> {
226 const_cast<unsigned char *>(reinterpret_cast<const unsigned char *>(str.data())), str.size()
227 };
228}
229}
230
231}
232

source code of slint/api/cpp/include/slint_string.h