#include <__format/formatter_string.h>
#include <__format/parser_std_format_spec.h>
#include <__iterator/back_insert_iterator.h>
+#include <__iterator/concepts.h>
#include <__iterator/incrementable_traits.h>
+#include <__iterator/readable_traits.h> // iter_value_t
#include <__variant/monostate.h>
#include <array>
#include <string>
std::__throw_format_error("Invalid argument");
}
-template <class _CharT, class _ParseCtx, class _Ctx>
-_LIBCPP_HIDE_FROM_ABI constexpr const _CharT*
-__handle_replacement_field(const _CharT* __begin, const _CharT* __end,
+template <contiguous_iterator _Iterator, class _ParseCtx, class _Ctx>
+_LIBCPP_HIDE_FROM_ABI constexpr _Iterator
+__handle_replacement_field(_Iterator __begin, _Iterator __end,
_ParseCtx& __parse_ctx, _Ctx& __ctx) {
+ using _CharT = iter_value_t<_Iterator>;
__format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx);
- bool __parse = *__r.__ptr == _CharT(':');
- switch (*__r.__ptr) {
+ bool __parse = *__r.__last == _CharT(':');
+ switch (*__r.__last) {
case _CharT(':'):
// The arg-id has a format-specifier, advance the input to the format-spec.
- __parse_ctx.advance_to(__r.__ptr + 1);
+ __parse_ctx.advance_to(__r.__last + 1);
break;
case _CharT('}'):
// The arg-id has no format-specifier.
- __parse_ctx.advance_to(__r.__ptr);
+ __parse_ctx.advance_to(__r.__last);
break;
default:
std::__throw_format_error("The replacement field arg-id should terminate at a ':' or '}'");
using _CharT = typename _ParseCtx::char_type;
static_assert(same_as<typename _Ctx::char_type, _CharT>);
- const _CharT* __begin = __parse_ctx.begin();
- const _CharT* __end = __parse_ctx.end();
+ auto __begin = __parse_ctx.begin();
+ auto __end = __parse_ctx.end();
typename _Ctx::iterator __out_it = __ctx.out();
while (__begin != __end) {
switch (*__begin) {
#include <__assert>
#include <__config>
#include <__format/format_error.h>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h> // iter_value_t
#include <cstddef>
#include <cstdint>
namespace __format {
-template <class _CharT>
+template <contiguous_iterator _Iterator>
struct _LIBCPP_TEMPLATE_VIS __parse_number_result {
- const _CharT* __ptr;
+ _Iterator __last;
uint32_t __value;
};
-template <class _CharT>
-__parse_number_result(const _CharT*, uint32_t) -> __parse_number_result<_CharT>;
+template <contiguous_iterator _Iterator>
+__parse_number_result(_Iterator, uint32_t) -> __parse_number_result<_Iterator>;
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_number(const _CharT* __begin, const _CharT* __end);
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_number(_Iterator __begin, _Iterator __end);
/**
* The maximum value of a numeric argument.
inline constexpr uint32_t __number_max = INT32_MAX;
namespace __detail {
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_zero(const _CharT* __begin, const _CharT*, auto& __parse_ctx) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_zero(_Iterator __begin, _Iterator, auto& __parse_ctx) {
__parse_ctx.check_arg_id(0);
return {++__begin, 0}; // can never be larger than the maximum.
}
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_automatic(const _CharT* __begin, const _CharT*, auto& __parse_ctx) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_automatic(_Iterator __begin, _Iterator, auto& __parse_ctx) {
size_t __value = __parse_ctx.next_arg_id();
_LIBCPP_ASSERT(__value <= __number_max,
"Compilers don't support this number of arguments");
return {__begin, uint32_t(__value)};
}
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_manual(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
- __parse_number_result<_CharT> __r = __format::__parse_number(__begin, __end);
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_manual(_Iterator __begin, _Iterator __end, auto& __parse_ctx) {
+ __parse_number_result<_Iterator> __r = __format::__parse_number(__begin, __end);
__parse_ctx.check_arg_id(__r.__value);
return __r;
}
* The number is used for the 31-bit values @em width and @em precision. This
* allows a maximum value of 2147483647.
*/
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_number(const _CharT* __begin, const _CharT* __end_input) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_number(_Iterator __begin, _Iterator __end_input) {
+ using _CharT = iter_value_t<_Iterator>;
static_assert(__format::__number_max == INT32_MAX,
"The algorithm is implemented based on this value.");
/*
* - Does the value exceed width of an uint32_t? (Switching to uint64_t would
* have the same issue, but with a higher maximum.)
*/
- const _CharT* __end = __end_input - __begin > 9 ? __begin + 9 : __end_input;
+ _Iterator __end = __end_input - __begin > 9 ? __begin + 9 : __end_input;
uint32_t __value = *__begin - _CharT('0');
while (++__begin != __end) {
if (*__begin < _CharT('0') || *__begin > _CharT('9'))
* The parser will return a pointer beyond the last consumed character. This
* should be the closing '}' of the arg-id.
*/
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_CharT>
-__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __parse_number_result<_Iterator>
+__parse_arg_id(_Iterator __begin, _Iterator __end, auto& __parse_ctx) {
+ using _CharT = iter_value_t<_Iterator>;
switch (*__begin) {
case _CharT('0'):
return __detail::__parse_zero(__begin, __end, __parse_ctx);
#include <__format/parser_std_format_spec.h>
#include <__format/unicode.h>
#include <__iterator/back_insert_iterator.h>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h> // iter_value_t
#include <__type_traits/make_unsigned.h>
#include <__utility/move.h>
#include <__utility/unreachable.h>
return __formatter::__fill(_VSTD::move(__out_it), __padding.__after_, __specs.__fill_);
}
-template <class _CharT, class _ParserCharT>
+template <contiguous_iterator _Iterator, class _ParserCharT>
_LIBCPP_HIDE_FROM_ABI auto
-__write(const _CharT* __first,
- const _CharT* __last,
- output_iterator<const _CharT&> auto __out_it,
+__write(_Iterator __first,
+ _Iterator __last,
+ output_iterator<const iter_value_t<_Iterator>&> auto __out_it,
__format_spec::__parsed_specifications<_ParserCharT> __specs,
ptrdiff_t __size) -> decltype(__out_it) {
_LIBCPP_ASSERT(__first <= __last, "Not a valid range");
/// \overload
///
/// Calls the function above where \a __size = \a __last - \a __first.
-template <class _CharT, class _ParserCharT>
+template <contiguous_iterator _Iterator, class _ParserCharT>
_LIBCPP_HIDE_FROM_ABI auto
-__write(const _CharT* __first,
- const _CharT* __last,
- output_iterator<const _CharT&> auto __out_it,
+__write(_Iterator __first,
+ _Iterator __last,
+ output_iterator<const iter_value_t<_Iterator>&> auto __out_it,
__format_spec::__parsed_specifications<_ParserCharT> __specs) -> decltype(__out_it) {
_LIBCPP_ASSERT(__first <= __last, "Not a valid range");
return __formatter::__write(__first, __last, _VSTD::move(__out_it), __specs, __last - __first);
template <class _CharT>
_LIBCPP_HIDE_FROM_ABI int __truncate(basic_string_view<_CharT>& __str, int __precision) {
- __format_spec::__column_width_result<_CharT> __result =
+ __format_spec::__column_width_result __result =
__format_spec::__estimate_column_width(__str, __precision, __format_spec::__column_width_rounding::__down);
__str = basic_string_view<_CharT>{__str.begin(), __result.__last_};
return __result.__width_;
#include <__format/format_parse_context.h>
#include <__format/format_string.h>
#include <__format/unicode.h>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h> // iter_value_t
#include <__variant/monostate.h>
#include <bit>
#include <cstdint>
namespace __format_spec {
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result< _CharT>
-__parse_arg_id(const _CharT* __begin, const _CharT* __end, auto& __parse_ctx) {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __format::__parse_number_result<_Iterator>
+__parse_arg_id(_Iterator __begin, _Iterator __end, auto& __parse_ctx) {
+ using _CharT = iter_value_t<_Iterator>;
// This function is a wrapper to call the real parser. But it does the
// validation for the pre-conditions and post-conditions.
if (__begin == __end)
__format::__parse_number_result __r = __format::__parse_arg_id(__begin, __end, __parse_ctx);
- if (__r.__ptr == __end || *__r.__ptr != _CharT('}'))
+ if (__r.__last == __end || *__r.__last != _CharT('}'))
std::__throw_format_error("Invalid arg-id");
- ++__r.__ptr;
+ ++__r.__last;
return __r;
}
_LIBCPP_HIDE_FROM_ABI constexpr auto __parse(basic_format_parse_context<_CharT>& __parse_ctx, __fields __fields)
-> decltype(__parse_ctx.begin()) {
- const _CharT* __begin = __parse_ctx.begin();
- const _CharT* __end = __parse_ctx.end();
+ auto __begin = __parse_ctx.begin();
+ auto __end = __parse_ctx.end();
if (__begin == __end)
return __begin;
}
// range-fill and tuple-fill are identical
- _LIBCPP_HIDE_FROM_ABI constexpr bool
- __parse_fill_align(const _CharT*& __begin, const _CharT* __end, bool __use_range_fill) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_fill_align(_Iterator& __begin, _Iterator __end, bool __use_range_fill) {
_LIBCPP_ASSERT(__begin != __end, "when called with an empty input the function will cause "
"undefined behavior by evaluating data not in the input");
if (__begin + 1 != __end) {
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(const _CharT*& __begin) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_sign(_Iterator& __begin) {
switch (*__begin) {
case _CharT('-'):
__sign_ = __sign::__minus;
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(const _CharT*& __begin) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_alternate_form(_Iterator& __begin) {
if (*__begin != _CharT('#'))
return false;
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(const _CharT*& __begin) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_zero_padding(_Iterator& __begin) {
if (*__begin != _CharT('0'))
return false;
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(const _CharT*& __begin, const _CharT* __end, auto& __parse_ctx) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_width(_Iterator& __begin, _Iterator __end, auto& __parse_ctx) {
if (*__begin == _CharT('0'))
std::__throw_format_error("A format-spec width field shouldn't have a leading zero");
__format::__parse_number_result __r = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
__width_as_arg_ = true;
__width_ = __r.__value;
- __begin = __r.__ptr;
+ __begin = __r.__last;
return true;
}
__width_ = __r.__value;
_LIBCPP_ASSERT(__width_ != 0, "A zero value isn't allowed and should be impossible, "
"due to validations in this function");
- __begin = __r.__ptr;
+ __begin = __r.__last;
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(const _CharT*& __begin, const _CharT* __end,
- auto& __parse_ctx) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_precision(_Iterator& __begin, _Iterator __end, auto& __parse_ctx) {
if (*__begin != _CharT('.'))
return false;
__format::__parse_number_result __arg_id = __format_spec::__parse_arg_id(++__begin, __end, __parse_ctx);
__precision_as_arg_ = true;
__precision_ = __arg_id.__value;
- __begin = __arg_id.__ptr;
+ __begin = __arg_id.__last;
return true;
}
__format::__parse_number_result __r = __format::__parse_number(__begin, __end);
__precision_ = __r.__value;
__precision_as_arg_ = false;
- __begin = __r.__ptr;
+ __begin = __r.__last;
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(const _CharT*& __begin) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr bool __parse_locale_specific_form(_Iterator& __begin) {
if (*__begin != _CharT('L'))
return false;
return true;
}
- _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(const _CharT*& __begin) {
+ template <contiguous_iterator _Iterator>
+ _LIBCPP_HIDE_FROM_ABI constexpr void __parse_type(_Iterator& __begin) {
// Determines the type. It does not validate whether the selected type is
// valid. Most formatters have optional fields that are only allowed for
// certain types. These parsers need to do validation after the type has
}
}
-template <class _CharT>
+template <contiguous_iterator _Iterator>
struct __column_width_result {
/// The number of output columns.
size_t __width_;
/// One beyond the last code unit used in the estimation.
///
/// This limits the original output to fit in the wanted number of columns.
- const _CharT* __last_;
+ _Iterator __last_;
};
-template <class _CharT>
-__column_width_result(size_t, const _CharT*) -> __column_width_result<_CharT>;
+template <contiguous_iterator _Iterator>
+__column_width_result(size_t, _Iterator) -> __column_width_result<_Iterator>;
/// Since a column width can be two it's possible that the requested column
/// width can't be achieved. Depending on the intended usage the policy can be
return __detail::__column_width_4(__c);
}
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width_grapheme_clustering(
- const _CharT* __first, const _CharT* __last, size_t __maximum, __column_width_rounding __rounding) noexcept {
+template <contiguous_iterator _Iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_Iterator> __estimate_column_width_grapheme_clustering(
+ _Iterator __first, _Iterator __last, size_t __maximum, __column_width_rounding __rounding) noexcept {
+ using _CharT = iter_value_t<_Iterator>;
__unicode::__extended_grapheme_cluster_view<_CharT> __view{__first, __last};
- __column_width_result<_CharT> __result{0, __first};
+ __column_width_result<_Iterator> __result{0, __first};
while (__result.__last_ != __last && __result.__width_ <= __maximum) {
typename __unicode::__extended_grapheme_cluster_view<_CharT>::__cluster __cluster = __view.__consume();
int __width = __detail::__column_width(__cluster.__code_point_);
/// \param __rounding Selects the rounding method.
/// \c __down result.__width_ <= __maximum
/// \c __up result.__width_ <= __maximum + 1
-template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT> __estimate_column_width(
+template <class _CharT, class _Iterator = typename basic_string_view<_CharT>::const_iterator>
+_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_Iterator> __estimate_column_width(
basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding __rounding) noexcept {
// The width estimation is done in two steps:
// - Quickly process for the ASCII part. ASCII has the following properties
// need to scan one code unit beyond the requested precision. When this code
// unit is non-ASCII we omit the current code unit and let the Grapheme
// clustering algorithm do its work.
- const _CharT* __it = __str.begin();
+ auto __it = __str.begin();
if (__format_spec::__is_ascii(*__it)) {
do {
--__maximum;
}
# else // !defined(_LIBCPP_HAS_NO_UNICODE)
template <class _CharT>
-_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<_CharT>
+_LIBCPP_HIDE_FROM_ABI constexpr __column_width_result<typename basic_string_view<_CharT>::const_iterator>
__estimate_column_width(basic_string_view<_CharT> __str, size_t __maximum, __column_width_rounding) noexcept {
// When Unicode isn't supported assume ASCII and every code unit is one code
// point. In ASCII the estimated column width is always one. Thus there's no
#define _LIBCPP___FORMAT_UNICODE_H
#include <__assert>
+#include <__concepts/same_as.h>
#include <__config>
#include <__format/extended_grapheme_cluster_table.h>
+#include <__iterator/concepts.h>
+#include <__iterator/readable_traits.h> // iter_value_t
#include <__type_traits/make_unsigned.h>
#include <__utility/unreachable.h>
#include <bit>
+#include <string_view>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
inline constexpr char32_t __replacement_character = U'\ufffd';
-_LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(const char* __char, int __count) {
+template <contiguous_iterator _Iterator>
+ requires same_as<iter_value_t<_Iterator>, char>
+_LIBCPP_HIDE_FROM_ABI constexpr bool __is_continuation(_Iterator __char, int __count) {
do {
if ((*__char & 0b1000'0000) != 0b1000'0000)
return false;
/// UTF-8 specialization.
template <>
class __code_point_view<char> {
+ using _Iterator = basic_string_view<char>::const_iterator;
+
public:
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const char* __first, const char* __last)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
: __first_(__first), __last_(__last) {}
_LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
- _LIBCPP_HIDE_FROM_ABI constexpr const char* __position() const noexcept { return __first_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
_LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
_LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
# endif // _LIBCPP_STD_VER > 20
private:
- const char* __first_;
- const char* __last_;
+ _Iterator __first_;
+ _Iterator __last_;
};
# ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
/// - 4 UTF-32 (for example Linux)
template <>
class __code_point_view<wchar_t> {
+ using _Iterator = typename basic_string_view<wchar_t>::const_iterator;
+
public:
static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "sizeof(wchar_t) has a not implemented value");
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const wchar_t* __first, const wchar_t* __last)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
: __first_(__first), __last_(__last) {}
- _LIBCPP_HIDE_FROM_ABI constexpr const wchar_t* __position() const noexcept { return __first_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
_LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
_LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
# endif // _LIBCPP_STD_VER > 20
private:
- const wchar_t* __first_;
- const wchar_t* __last_;
+ _Iterator __first_;
+ _Iterator __last_;
};
# endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
/// Therefore only this code point is extracted.
template <class _CharT>
class __extended_grapheme_cluster_view {
+ using _Iterator = typename basic_string_view<_CharT>::const_iterator;
+
public:
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(const _CharT* __first, const _CharT* __last)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __extended_grapheme_cluster_view(_Iterator __first, _Iterator __last)
: __code_point_view_(__first, __last),
__next_code_point_(__code_point_view_.__consume()),
__next_prop_(__extended_grapheme_custer_property_boundary::__get_property(__next_code_point_)) {}
///
/// It's expected the caller has the start position and thus can determine
/// the code unit range of the extended grapheme cluster.
- const _CharT* __last_;
+ _Iterator __last_;
};
_LIBCPP_HIDE_FROM_ABI constexpr __cluster __consume() {
char32_t __next_code_point_;
__extended_grapheme_custer_property_boundary::__property __next_prop_;
- _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __get_break() {
+ _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __get_break() {
bool __ri_break_allowed = true;
bool __has_extened_pictographic = false;
while (true) {
- const _CharT* __result = __code_point_view_.__position();
+ _Iterator __result = __code_point_view_.__position();
__extended_grapheme_custer_property_boundary::__property __prev = __next_prop_;
if (__code_point_view_.__at_end()) {
__next_prop_ = __extended_grapheme_custer_property_boundary::__property::__eot;
}
};
-template <class _CharT>
-__extended_grapheme_cluster_view(const _CharT*, const _CharT*) -> __extended_grapheme_cluster_view<_CharT>;
+template <contiguous_iterator _Iterator>
+__extended_grapheme_cluster_view(_Iterator, _Iterator) -> __extended_grapheme_cluster_view<iter_value_t<_Iterator>>;
# else // _LIBCPP_HAS_NO_UNICODE
// This makes it easier to write code agnostic of the _LIBCPP_HAS_NO_UNICODE define.
template <class _CharT>
class __code_point_view {
+ using _Iterator = typename basic_string_view<_CharT>::const_iterator;
+
public:
- _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(const _CharT* __first, const _CharT* __last)
+ _LIBCPP_HIDE_FROM_ABI constexpr explicit __code_point_view(_Iterator __first, _Iterator __last)
: __first_(__first), __last_(__last) {}
_LIBCPP_HIDE_FROM_ABI constexpr bool __at_end() const noexcept { return __first_ == __last_; }
- _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __position() const noexcept { return __first_; }
+ _LIBCPP_HIDE_FROM_ABI constexpr _Iterator __position() const noexcept { return __first_; }
_LIBCPP_HIDE_FROM_ABI constexpr char32_t __consume() noexcept {
_LIBCPP_ASSERT(__first_ != __last_, "can't move beyond the end of input");
# endif // _LIBCPP_STD_VER > 20
private:
- const _CharT* __first_;
- const _CharT* __last_;
+ _Iterator __first_;
+ _Iterator __last_;
};
# endif // _LIBCPP_HAS_NO_UNICODE
module permutable { private header "__iterator/permutable.h" }
module prev { private header "__iterator/prev.h" }
module projected { private header "__iterator/projected.h" }
- module readable_traits { private header "__iterator/readable_traits.h" }
+ module readable_traits {
+ private header "__iterator/readable_traits.h"
+ export __iterator.iterator_traits
+ }
module reverse_access { private header "__iterator/reverse_access.h" }
module reverse_iterator { private header "__iterator/reverse_iterator.h" }
module segmented_iterator { private header "__iterator/segmented_iterator.h" }