• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef RUNTIME_INCLUDE_TAIHE_STRING_HPP_
16 #define RUNTIME_INCLUDE_TAIHE_STRING_HPP_
17 // NOLINTBEGIN
18 
19 #include <taihe/string.abi.h>
20 #include <taihe/common.hpp>
21 
22 #include <algorithm>
23 #include <charconv>
24 #include <cstddef>
25 #include <cstdint>
26 #include <cstring>
27 #include <iostream>
28 #include <stdexcept>
29 #include <string>
30 #include <string_view>
31 #include <utility>
32 
33 namespace taihe {
34 struct string_view;
35 struct string;
36 
37 struct string_view {
38     using value_type = char;
39     using size_type = std::size_t;
40     using const_reference = value_type const &;
41     using const_pointer = value_type const *;
42     using const_iterator = const_pointer;
43     using const_reverse_iterator = std::reverse_iterator<const_iterator>;
44 
string_viewtaihe::string_view45     explicit string_view(struct TString handle) : m_handle(handle) {}
46 
string_viewtaihe::string_view47     string_view(char const *value TH_NONNULL) : string_view(tstr_new_ref(value, std::strlen(value))) {}
48 
string_viewtaihe::string_view49     string_view(char const *value TH_NONNULL, size_type size) : string_view(tstr_new_ref(value, size)) {}
50 
string_viewtaihe::string_view51     string_view(std::initializer_list<char> value) : string_view(value.begin(), value.size()) {}
52 
string_viewtaihe::string_view53     string_view(std::string_view value) : string_view(value.data(), value.size()) {}
54 
string_viewtaihe::string_view55     string_view(std::string const &value) : string_view(value.data(), value.size()) {}
56 
operator std::string_viewtaihe::string_view57     operator std::string_view() const noexcept
58     {
59         return {tstr_buf(m_handle), tstr_len(m_handle)};
60     }
61 
62     // methods
operator []taihe::string_view63     const_reference operator[](size_type pos) const
64     {
65         if (pos >= size()) {
66             TH_THROW(std::out_of_range, "Index out of range");
67         }
68         return tstr_buf(m_handle)[pos];
69     }
70 
emptytaihe::string_view71     bool empty() const noexcept
72     {
73         return tstr_len(m_handle) == 0;
74     }
75 
sizetaihe::string_view76     size_type size() const noexcept
77     {
78         return tstr_len(m_handle);
79     }
80 
fronttaihe::string_view81     const_reference front() const
82     {
83         if (empty()) {
84             TH_THROW(std::out_of_range, "Empty string");
85         }
86         return tstr_buf(m_handle)[0];
87     }
88 
backtaihe::string_view89     const_reference back() const
90     {
91         if (empty()) {
92             TH_THROW(std::out_of_range, "Empty string");
93         }
94         return tstr_buf(m_handle)[size() - 1];
95     }
96 
c_strtaihe::string_view97     const_pointer c_str() const noexcept
98     {
99         return tstr_buf(m_handle);
100     }
101 
datataihe::string_view102     const_pointer data() const noexcept
103     {
104         return tstr_buf(m_handle);
105     }
106 
begintaihe::string_view107     const_iterator begin() const noexcept
108     {
109         return tstr_buf(m_handle);
110     }
111 
cbegintaihe::string_view112     const_iterator cbegin() const noexcept
113     {
114         return begin();
115     }
116 
endtaihe::string_view117     const_iterator end() const noexcept
118     {
119         return tstr_buf(m_handle) + tstr_len(m_handle);
120     }
121 
cendtaihe::string_view122     const_iterator cend() const noexcept
123     {
124         return end();
125     }
126 
rbegintaihe::string_view127     const_reverse_iterator rbegin() const noexcept
128     {
129         return const_reverse_iterator(end());
130     }
131 
crbegintaihe::string_view132     const_reverse_iterator crbegin() const noexcept
133     {
134         return rbegin();
135     }
136 
rendtaihe::string_view137     const_reverse_iterator rend() const noexcept
138     {
139         return const_reverse_iterator(begin());
140     }
141 
crendtaihe::string_view142     const_reverse_iterator crend() const noexcept
143     {
144         return rend();
145     }
146 
147     friend struct string;
148 
149     friend string concat(std::initializer_list<string_view> sv_list);
150     friend string_view substr(string_view sv, std::size_t pos, std::size_t len);
151     friend string operator+(string_view left, string_view right);
152     string_view substr(std::size_t pos, std::size_t len) const;
153 
154 protected:
155     struct TString m_handle;
156 };
157 
158 struct string : public string_view {
stringtaihe::string159     explicit string(struct TString handle) : string_view(handle) {}
160 
stringtaihe::string161     string(char const *value TH_NONNULL) : string(tstr_new(value, std::strlen(value))) {}
162 
stringtaihe::string163     string(char const *value TH_NONNULL, size_type size) : string(tstr_new(value, size)) {}
164 
stringtaihe::string165     string(std::initializer_list<char> value) : string(value.begin(), value.size()) {}
166 
stringtaihe::string167     string(std::string_view value) : string(value.data(), value.size()) {}
168 
stringtaihe::string169     string(std::string const &value) : string(value.data(), value.size()) {}
170 
171     // constructors
stringtaihe::string172     string(string_view const &other) : string(tstr_dup(other.m_handle)) {}
173 
stringtaihe::string174     string(string const &other) : string(tstr_dup(other.m_handle)) {}
175 
stringtaihe::string176     string(string &&other) noexcept : string(other.m_handle)
177     {
178         other.m_handle.ptr = NULL;
179     }
180 
181     // assignment
operator =taihe::string182     string &operator=(string other)
183     {
184         std::swap(this->m_handle, other.m_handle);
185         return *this;
186     }
187 
188     // destructor
~stringtaihe::string189     ~string()
190     {
191         if (m_handle.ptr != NULL) {
192             tstr_drop(m_handle);
193         }
194     }
195 
196     string &operator+=(string_view other);
197 };
198 
concat(std::initializer_list<string_view> sv_list)199 inline string concat(std::initializer_list<string_view> sv_list)
200 {
201     static_assert(alignof(string_view) == alignof(struct TString));
202     return string(tstr_concat(sv_list.size(), reinterpret_cast<struct TString const *>(sv_list.begin())));
203 }
204 
operator +(string_view left,string_view right)205 inline string operator+(string_view left, string_view right)
206 {
207     return concat({left, right});
208 }
209 
operator +=(string_view other)210 inline string &string::operator+=(string_view other)
211 {
212     return *this = *this + other;
213 }
214 
substr(string_view sv,std::size_t pos,std::size_t len)215 inline string_view substr(string_view sv, std::size_t pos, std::size_t len)
216 {
217     return string_view(tstr_substr(sv.m_handle, pos, len));
218 }
219 
substr(std::size_t pos,std::size_t len) const220 inline string_view string_view::substr(std::size_t pos, std::size_t len) const
221 {
222     return string_view(tstr_substr(this->m_handle, pos, len));
223 }
224 
operator ==(string_view lhs,string_view rhs)225 inline bool operator==(string_view lhs, string_view rhs)
226 {
227     return std::string_view(lhs) == std::string_view(rhs);
228 }
229 
operator !=(string_view lhs,string_view rhs)230 inline bool operator!=(string_view lhs, string_view rhs)
231 {
232     return std::string_view(lhs) != std::string_view(rhs);
233 }
234 
operator <(string_view lhs,string_view rhs)235 inline bool operator<(string_view lhs, string_view rhs)
236 {
237     return std::string_view(lhs) < std::string_view(rhs);
238 }
239 
operator >(string_view lhs,string_view rhs)240 inline bool operator>(string_view lhs, string_view rhs)
241 {
242     return std::string_view(lhs) > std::string_view(rhs);
243 }
244 
operator <=(string_view lhs,string_view rhs)245 inline bool operator<=(string_view lhs, string_view rhs)
246 {
247     return std::string_view(lhs) <= std::string_view(rhs);
248 }
249 
operator >=(string_view lhs,string_view rhs)250 inline bool operator>=(string_view lhs, string_view rhs)
251 {
252     return std::string_view(lhs) >= std::string_view(rhs);
253 }
254 
operator <<(std::ostream & os,string_view sv)255 inline std::ostream &operator<<(std::ostream &os, string_view sv)
256 {
257     return os << std::string_view(sv);
258 }
259 
260 template <typename T, std::enable_if_t<std::is_integral_v<T>, int> = 0>
to_string(T value)261 inline string to_string(T value)
262 {
263     char buffer[32];
264     std::to_chars_result result = std::to_chars(std::begin(buffer), std::end(buffer), value);
265     if (result.ec != std::errc {}) {
266         TH_THROW(std::runtime_error, "Conversion to char failed");
267     }
268     // buffer automatcally
269     return string {buffer, static_cast<std::size_t>(result.ptr - buffer)};
270 }
271 
272 template <typename T, std::enable_if_t<std::is_floating_point_v<T>, int> = 0>
to_string(T value)273 inline string to_string(T value)
274 {
275     char buffer[32];
276     std::to_chars_result result =
277         std::to_chars(std::begin(buffer), std::end(buffer), value, std::chars_format::general);
278     if (result.ec != std::errc {}) {
279         TH_THROW(std::runtime_error, "Conversion to char failed");
280     }
281     // buffer automatcally
282     return string {buffer, static_cast<std::size_t>(result.ptr - buffer)};
283 }
284 
285 template <typename T, std::enable_if_t<std::is_same_v<T, bool>, int> = 0>
to_string(T value)286 string to_string(T value)
287 {
288     if (value) {
289         return string {"true", 4};
290     } else {
291         return string {"false", 5};
292     }
293 }
294 
295 template <>
296 struct as_abi<string_view> {
297     using type = TString;
298 };
299 
300 template <>
301 struct as_abi<string> {
302     using type = TString;
303 };
304 
305 template <>
306 struct as_param<string> {
307     using type = string_view;
308 };
309 }  // namespace taihe
310 
311 template <>
312 struct std::hash<taihe::string> {
operator ()std::hash313     std::size_t operator()(taihe::string_view sv) const noexcept
314     {
315         return std::hash<std::string_view>()(std::string_view(sv));
316     }
317 };
318 // NOLINTEND
319 #endif  // RUNTIME_INCLUDE_TAIHE_STRING_HPP_