16 #include "jasl/jasl_internal/jasl_feature_test_macro.hpp" 17 #include "jasl/jasl_internal/jasl_string_view_bridge.hpp" 32 template <
typename CharT,
33 typename Traits = std::char_traits<CharT>,
34 typename AllocatorT = std::allocator<CharT>>
41 typedef AllocatorT allocator_type;
44 typedef std::allocator_traits<AllocatorT> alloc_traits;
47 constexpr
static bool is_noexcept_assign_rvalue =
48 alloc_traits::propagate_on_container_move_assignment::value &&
49 std::is_nothrow_move_assignable<AllocatorT>::value &&
53 allocator_type _alloc;
65 # define JASL_TEMP_CONSTEXPR_FOR_PW 67 # define JASL_TEMP_CONSTEXPR_FOR_PW constexpr 69 JASL_TEMP_CONSTEXPR_FOR_PW CStr(
const CharT* p) noexcept
70 : size(Traits::length(p)), ptr(p) {}
71 #undef JASL_TEMP_CONSTEXPR_FOR_PW 74 inline void init(
const CharT* ptr,
size_t size) {
75 JASL_ASSERT(_cap == 0,
"_cap == 0");
77 std::is_standard_layout<CharT>::value && std::is_trivial<CharT>::value,
80 bridge_type::set(
nullptr, 0);
83 std::unique_ptr<CharT, std::function<void(CharT*)>> begin(
84 alloc_traits::allocate(_alloc, size), [&](CharT * ptd) noexcept {
85 alloc_traits::deallocate(_alloc, ptd, size);
87 bridge_type::set(begin.get(), size);
89 auto raw_begin = begin.release();
90 Traits::copy(raw_begin, ptr, size);
93 inline void dispose() noexcept {
95 const auto begin =
const_cast<CharT*
>(bridge_type::data());
96 alloc_traits::deallocate(_alloc, begin, _cap);
103 init(other.data(), other.size());
109 alloc_traits::deallocate(_alloc, const_cast<CharT*>(bridge_type::data()),
115 std::is_nothrow_constructible<bridge_type>::value&&
116 std::is_nothrow_default_constructible<AllocatorT>::value)
120 std::is_nothrow_constructible<bridge_type>::value&&
121 std::is_nothrow_copy_constructible<AllocatorT>::value)
124 basic_string(
const CStr& cstr,
const AllocatorT& alloc = AllocatorT())
126 JASL_ASSERT(cstr.ptr !=
nullptr,
"cstr != nullptr");
127 init(cstr.ptr, cstr.size);
132 const AllocatorT& alloc = AllocatorT())
134 JASL_ASSERT(ptr !=
nullptr,
"ptr != nullptr");
140 std::is_nothrow_constructible<bridge_type, const CharT*, size_t>::value&&
141 std::is_nothrow_default_constructible<AllocatorT>::value)
142 :
bridge_type(str, str[N - 1] == 0 ? N - 1 : N), _alloc(), _cap(0) {}
145 basic_string(
const CharT (&str)[N],
const AllocatorT& alloc) noexcept(
146 std::is_nothrow_constructible<bridge_type, const CharT*, size_t>::value&&
147 std::is_nothrow_copy_constructible<AllocatorT>::value)
148 :
bridge_type(str, str[N - 1] == 0 ? N - 1 : N), _alloc(alloc), _cap(0) {}
153 alloc_traits::select_on_container_copy_construction(other._alloc)) {
158 if (other._cap > 0) {
159 init(other.data(), other.size());
164 std::is_nothrow_move_constructible<bridge_type>::value&&
165 std::is_nothrow_move_constructible<AllocatorT>::value)
167 _alloc(std::move(other._alloc)),
174 if (_alloc == other._alloc) {
175 bridge_type::set(other.data(), other.size());
176 std::swap(_cap, other._cap);
178 init(other.data(), other.size());
183 std::is_nothrow_constructible<bridge_type, const CharT*, size_t>::value&&
184 std::is_nothrow_default_constructible<AllocatorT>::value)
185 :
bridge_type(ss.data(), ss.size()), _alloc(), _cap(0) {}
190 alloc) noexcept(std::is_nothrow_constructible<
bridge_type,
192 size_t>::value&&
std::
193 is_nothrow_copy_constructible<AllocatorT>::value)
194 :
bridge_type(ss.data(), ss.size()), _alloc(alloc), _cap(0) {}
196 #if defined(JASL_SUPPORT_STD_TO_JASL) 197 # if defined(JASL_cpp_lib_string_view) 200 typename =
typename std::enable_if<
201 std::is_convertible<
const T&,
202 std::basic_string_view<CharT, Traits>>::value &&
203 !std::is_convertible<const T&, const CharT*>::value>::type>
204 explicit basic_string(
const T& s,
const AllocatorT& alloc = AllocatorT())
206 std::basic_string_view<CharT, Traits> sv(s);
207 init(sv.data(), sv.size());
212 typename =
typename std::enable_if<
213 std::is_convertible<
const T&,
214 std::basic_string_view<CharT, Traits>>::value &&
215 !std::is_convertible<const T&, const CharT*>::value>::type>
218 std::basic_string_view<CharT, Traits> sv(s);
219 init(sv.data(), sv.size());
225 typename =
typename std::enable_if<std::is_same<
227 const std::basic_string<CharT, Traits, AllocatorT>&>::value>::type>
228 explicit basic_string(
const T& s,
const AllocatorT& alloc = AllocatorT())
230 init(s.data(), s.size());
235 typename =
typename std::enable_if<std::is_same<
237 const std::basic_string<CharT, Traits, AllocatorT>&>::value>::type>
240 init(s.data(), s.size());
246 #if defined(JASL_SUPPORT_JASL_TO_STD) 247 # if defined(JASL_cpp_lib_string_view) 248 operator std::basic_string_view<CharT, Traits>()
const noexcept(
249 std::is_nothrow_constructible<std::basic_string_view<CharT, Traits>,
252 return std::basic_string_view<CharT, Traits>(bridge_type::data(),
253 bridge_type::size());
256 operator std::basic_string<CharT, Traits, AllocatorT>()
const 257 noexcept(std::is_nothrow_constructible<
258 std::basic_string<CharT, Traits, AllocatorT>,
261 return std::basic_string<CharT, Traits, AllocatorT>(bridge_type::data(),
262 bridge_type::size());
269 bridge_type::is_nothrow_settable) {
271 bridge_type::set(str, str[N - 1] == 0 ? N - 1 : N);
277 init(cstr.ptr, cstr.size);
282 if (
this == &other) {
295 if (alloc_traits::propagate_on_container_copy_assignment::value ||
296 _alloc != other._alloc) {
297 _alloc = other._alloc;
299 if (other._cap == 0) {
300 bridge_type::operator=(other);
302 init(other.data(), other.size());
308 is_noexcept_assign_rvalue) {
309 if (
this == &other) {
321 if (alloc_traits::propagate_on_container_move_assignment::value) {
322 _alloc = std::move(other._alloc);
323 }
else if (_alloc != other._alloc) {
324 init(other.data(), other.size());
327 bridge_type::swap(other);
328 std::swap(_cap, other._cap);
333 bridge_type::is_nothrow_settable) {
335 bridge_type::set(ss.data(), ss.size());
340 basic_string& operator=(
const CharT (&str)[N]) noexcept {
341 return assign<N>(str);
347 is_noexcept_assign_rvalue) {
348 return assign(std::move(other));
353 bridge_type::is_nothrow_settable) {
354 return assign(other);
357 constexpr
bool is_static()
const noexcept {
return _cap == 0; }
358 AllocatorT get_alloc()
const 359 noexcept(std::is_nothrow_copy_constructible<AllocatorT>::value) {
364 (!alloc_traits::propagate_on_container_swap::value ||
365 JASL_is_nothrow_swappable_value(AllocatorT)) &&
374 if (alloc_traits::propagate_on_container_swap::value) {
375 swap(_alloc, other._alloc);
376 }
else if (_alloc != other._alloc) {
377 JASL_ASSERT(
false,
"Undefined behaviour");
380 bridge_type::swap(other);
381 swap(_cap, other._cap);
384 basic_string substr(
typename bridge_type::size_type pos)
const {
387 cpy.bridge_type::operator=(bridge_type::substr(pos));
394 basic_string substr(
typename bridge_type::size_type pos,
395 typename bridge_type::size_type count)
const {
398 cpy.bridge_type::operator=(bridge_type::substr(pos, count));
401 return basic_string(bridge_type::substr(pos, count), _alloc);
406 template <
typename CharT,
typename Traits>
412 typedef basic_string<char> string;
413 typedef basic_string<wchar_t> wstring;
414 typedef basic_string<char16_t> u16string;
415 typedef basic_string<char32_t> u32string;
Definition: jasl_static_string.hpp:18
Definition: jasl_string_view_bridge.hpp:17
Definition: jasl_string_view.hpp:401
Definition: jasl_string.hpp:35
Definition: jasl_static_string.hpp:36
Definition: jasl_string_view.hpp:24