@@ -32,6 +32,7 @@ namespace sysstr
32
32
} && (T::enable_view || !T::enable_view) && (T::enable_borrowed_range || !T::enable_borrowed_range);
33
33
34
34
template <utf_encoding Enc, class Container , utf_access_traits_t <Container> Traits = utf_access_traits<Container>>
35
+ requires (std::ranges::input_range<std::remove_reference_t <decltype(Traits::access(std::declval<typename Traits::stored_reference>()))>>)
35
36
class utf_view ;
36
37
37
38
namespace util
@@ -77,7 +78,7 @@ namespace sysstr
77
78
}
78
79
79
80
template <std::input_iterator OtherIt, std::sentinel_for<OtherIt> OtherEndIt>
80
- requires (Direction == iter_direction::forward && reverse_iterator_of<OtherIt, It>)
81
+ requires (Direction == iter_direction::forward && ranges:: reverse_iterator_of<OtherIt, It>)
81
82
utf_iterator (const utf_iterator<OutputEnc, OtherIt, OtherEndIt, iter_direction::backward> & rev,
82
83
EndIt last):
83
84
m_current (rev.storage_next().base()),
@@ -91,7 +92,7 @@ namespace sysstr
91
92
}
92
93
93
94
template <std::input_iterator OtherIt, std::sentinel_for<OtherIt> OtherEndIt>
94
- requires (Direction == iter_direction::backward && reverse_iterator_of<It, OtherIt>)
95
+ requires (Direction == iter_direction::backward && ranges:: reverse_iterator_of<It, OtherIt>)
95
96
utf_iterator (const utf_iterator<OutputEnc, OtherIt, OtherEndIt, iter_direction::forward> & fwd,
96
97
EndIt last):
97
98
m_current (fwd.storage_next()),
@@ -221,14 +222,14 @@ namespace sysstr
221
222
}
222
223
223
224
template <std::input_iterator OtherIt, std::sentinel_for<OtherIt> OtherEndIt>
224
- requires (Direction == iter_direction::forward && reverse_iterator_of<OtherIt, It>)
225
+ requires (Direction == iter_direction::forward && ranges:: reverse_iterator_of<OtherIt, It>)
225
226
utf_iterator (const utf_iterator<utf32, OtherIt, OtherEndIt, iter_direction::backward> & rev,
226
227
EndIt last):
227
228
utf_iterator (rev.storage_current().base(), last)
228
229
{}
229
230
230
231
template <std::input_iterator OtherIt, std::sentinel_for<OtherIt> OtherEndIt>
231
- requires (Direction == iter_direction::backward && reverse_iterator_of<It, OtherIt>)
232
+ requires (Direction == iter_direction::backward && ranges:: reverse_iterator_of<It, OtherIt>)
232
233
utf_iterator (const utf_iterator<utf32, OtherIt, OtherEndIt, iter_direction::forward> & fwd,
233
234
EndIt last):
234
235
utf_iterator (It(fwd.storage_current()), last)
@@ -289,29 +290,76 @@ namespace sysstr
289
290
};
290
291
}
291
292
292
- template <std::ranges::random_access_range Container>
293
+ template <std::ranges::input_range Container>
293
294
struct utf_access_traits <Container>
294
295
{
295
- using stored_reference = std::add_pointer_t <std::remove_reference_t <Container>>;
296
+ using stored_reference = std::add_pointer_t <std::add_const_t <std:: remove_reference_t <Container> >>;
296
297
297
298
static constexpr bool enable_view = true ;
298
299
static constexpr bool enable_borrowed_range = true ;
299
300
300
- static decltype (auto ) adapt(std::add_lvalue_reference_t < Container> src) noexcept
301
+ static decltype (auto ) adapt(const std::add_const_t <std:: remove_reference_t < Container>> & src) noexcept
301
302
{ return &src; }
302
- static std::add_lvalue_reference_t < Container> access (stored_reference ptr) noexcept
303
+ static std::add_const_t <std:: remove_reference_t < Container>> & access (stored_reference ptr) noexcept
303
304
{ return *ptr; }
304
305
};
305
306
306
-
307
307
template <utf_encoding Enc, class Container , utf_access_traits_t <Container> Traits>
308
+ requires (std::ranges::input_range<std::remove_reference_t <decltype(Traits::access(std::declval<typename Traits::stored_reference>()))>>)
308
309
class utf_view
309
310
{
310
311
private:
311
312
using stored_reference = typename Traits::stored_reference;
312
313
313
314
static constexpr auto source_encoding = utf_encoding_of<std::ranges::range_value_t <decltype(Traits::access(std::declval<stored_reference>()))>>;
314
315
316
+ using access_iterator = decltype(std::begin(Traits::access(std::declval<stored_reference>())));
317
+ using access_sentinel = decltype(std::end(Traits::access(std::declval<stored_reference>())));
318
+ public:
319
+ using iterator = util::utf_iterator<Enc, access_iterator, access_sentinel, util::iter_direction::forward>;
320
+ using const_iterator = iterator;
321
+
322
+ using value_type = typename iterator::value_type;
323
+ using reference = typename iterator::reference;
324
+ using const_reference = reference;
325
+ using pointer = typename iterator::pointer;
326
+ using const_pointer = pointer;
327
+
328
+ public:
329
+ utf_view (const Container & src) noexcept (noexcept (stored_reference(Traits::adapt(src)))) :
330
+ m_ref(Traits::adapt(src))
331
+ {}
332
+ SYS_STRING_FORCE_INLINE iterator begin () const
333
+ { return iterator (std::begin (Traits::access (this ->m_ref )), std::end (Traits::access (this ->m_ref ))); }
334
+ SYS_STRING_FORCE_INLINE std::default_sentinel_t end () const
335
+ { return std::default_sentinel; }
336
+ SYS_STRING_FORCE_INLINE const_iterator cbegin () const
337
+ { return begin (); }
338
+ SYS_STRING_FORCE_INLINE std::default_sentinel_t cend () const
339
+ { return end (); }
340
+
341
+
342
+ template <class Func >
343
+ decltype (auto ) each(Func func) const
344
+ {
345
+ return utf_converter<source_encoding, Enc>::for_each_converted (Traits::access (this ->m_ref ), func);
346
+ }
347
+
348
+ private:
349
+ stored_reference m_ref;
350
+ };
351
+
352
+
353
+ template <utf_encoding Enc, class Container , utf_access_traits_t <Container> Traits>
354
+ requires (std::ranges::input_range<std::remove_reference_t <decltype(Traits::access(std::declval<typename Traits::stored_reference>()))>> &&
355
+ ranges::reverse_traversable_range<std::remove_reference_t<decltype(Traits::access(std::declval<typename Traits::stored_reference>()))>>)
356
+ class utf_view<Enc, Container, Traits>
357
+ {
358
+ private:
359
+ using stored_reference = typename Traits::stored_reference;
360
+
361
+ static constexpr auto source_encoding = utf_encoding_of<std::ranges::range_value_t <decltype (Traits::access (std::declval<stored_reference>()))>>;
362
+
315
363
using access_iterator = decltype (std::begin (Traits::access (std::declval<stored_reference>())));
316
364
using access_sentinel = decltype (std::end (Traits::access (std::declval<stored_reference>())));
317
365
using access_reverse_iterator = decltype (std::rbegin (Traits::access (std::declval<stored_reference>())));
@@ -368,6 +416,33 @@ namespace sysstr
368
416
private:
369
417
stored_reference m_ref;
370
418
};
419
+
420
+ #if __cpp_lib_ranges >= 202202L
421
+
422
+ template <utf_encoding Enc>
423
+ struct as_utf_func :
424
+ #if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION < 190000
425
+ // libc++ lies about __cpp_lib_ranges
426
+ public std::__range_adaptor_closure<as_utf_func<Enc>>
427
+ #else
428
+ public std::ranges::range_adaptor_closure<as_utf_func<Enc>>
429
+ #endif
430
+ {
431
+ template <class Range >
432
+ [[nodiscard]] constexpr auto operator ()(Range && range) const
433
+ noexcept (noexcept (utf_view<Enc, std::remove_reference_t <Range>>(std::forward<Range>(range))))
434
+ -> decltype(utf_view<Enc, std::remove_reference_t <Range>>(std::forward<Range>(range)))
435
+ { return utf_view<Enc, std::remove_reference_t <Range>>(std::forward<Range>(range)); }
436
+
437
+ };
438
+
439
+ template <utf_encoding Enc>
440
+ inline constexpr auto as_utf = as_utf_func<Enc>{};
441
+ inline constexpr auto as_utf8 = as_utf_func<utf8>{};
442
+ inline constexpr auto as_utf16 = as_utf_func<utf16>{};
443
+ inline constexpr auto as_utf32 = as_utf_func<utf32>{};
444
+
445
+ #endif
371
446
}
372
447
373
448
namespace std ::ranges {
0 commit comments