diff --git a/include/beman/utf_view/to_utf_view.hpp b/include/beman/utf_view/to_utf_view.hpp index f578f11..b572b27 100644 --- a/include/beman/utf_view/to_utf_view.hpp +++ b/include/beman/utf_view/to_utf_view.hpp @@ -92,8 +92,13 @@ enum class utf_transcoding_error { invalid_utf8_leading_byte }; -template -requires std::ranges::view && exposition_only_code_unit> +enum class to_utf_view_error_kind : bool { + replacement, + expected +}; + +template + requires std::ranges::view && exposition_only_code_unit> /* !PAPER */ class exposition_only_to_utf_view_impl { /* PAPER */ @@ -206,12 +211,12 @@ class exposition_only_to_utf_view_impl { /* PAPER */ }; -template +template requires std::ranges::view && exposition_only_code_unit> template -/* PAPER: class @*to-utf-view-impl*@::@*iterator*@ { */ +/* PAPER: class @*to-utf-view-impl*@::@*iterator*@ { */ /* !PAPER */ -struct exposition_only_to_utf_view_impl::exposition_only_iterator : detail::iter_category_impl { +struct exposition_only_to_utf_view_impl::exposition_only_iterator : detail::iter_category_impl { /* PAPER */ private: using exposition_only_Parent = exposition_only_maybe_const; // @*exposition only*@ @@ -238,7 +243,7 @@ struct exposition_only_to_utf_view_impl::exposition_only_ite using iterator_concept = decltype(iter_concept_impl()); /* PAPER */ using value_type = - std::conditional_t, ToType>; + std::conditional_t, ToType>; using reference_type = value_type; using difference_type = ptrdiff_t; @@ -261,7 +266,7 @@ struct exposition_only_to_utf_view_impl::exposition_only_ite /* PAPER */ - template + template requires std::ranges::view && exposition_only_code_unit> friend class exposition_only_to_utf_view_impl; // @*exposition only*@ @@ -294,7 +299,7 @@ struct exposition_only_to_utf_view_impl::exposition_only_ite /* PAPER: constexpr value_type operator*() const; */ /* !PAPER */ constexpr value_type operator*() const { - if constexpr (OrError) { + if constexpr (E == to_utf_view_error_kind::expected) { if (!success_.has_value()) { return std::unexpected{success_.error()}; } @@ -303,7 +308,7 @@ struct exposition_only_to_utf_view_impl::exposition_only_ite } /* PAPER */ - constexpr exposition_only_iterator& operator++() requires(OrError) + constexpr exposition_only_iterator& operator++() requires(E == to_utf_view_error_kind::expected) { if (!exposition_only_success()) { /* !PAPER */ @@ -318,7 +323,7 @@ struct exposition_only_to_utf_view_impl::exposition_only_ite return *this; } - constexpr exposition_only_iterator& operator++() requires(!OrError) + constexpr exposition_only_iterator& operator++() requires(E == to_utf_view_error_kind::replacement) { exposition_only_advance_one(); return *this; @@ -395,11 +400,11 @@ struct exposition_only_to_utf_view_impl::exposition_only_ite return std::ranges::end(parent_->base_); } - /* PAPER: constexpr expected @*success*@() const noexcept requires(OrError); // @*exposition only*@ */ + /* PAPER: constexpr expected @*success*@() const noexcept requires(E == to_utf_view_error_kind::expected); // @*exposition only*@ */ /* !PAPER */ constexpr bool exposition_only_success() const noexcept // @*exposition only*@ - requires(OrError) + requires(E == to_utf_view_error_kind::expected) { return !!success_; } @@ -808,7 +813,7 @@ struct exposition_only_to_utf_view_impl::exposition_only_ite current_ = read_reverse_impl_result.new_curr; assert(buf_.size()); buf_index_ = buf_.size() - 1; - if constexpr (OrError) { + if constexpr (E == to_utf_view_error_kind::expected) { if (!success_.has_value()) { buf_index_ = 0; } @@ -818,12 +823,12 @@ struct exposition_only_to_utf_view_impl::exposition_only_ite /* PAPER */ }; -template +template requires std::ranges::view && exposition_only_code_unit> template -/* PAPER: class @*to-utf-view-impl*@::@*sentinel*@ { */ +/* PAPER: class @*to-utf-view-impl*@::@*sentinel*@ { */ /* !PAPER */ -struct exposition_only_to_utf_view_impl::exposition_only_sentinel { +struct exposition_only_to_utf_view_impl::exposition_only_sentinel { /* PAPER */ private: using exposition_only_Parent = exposition_only_maybe_const; // @*exposition only*@ @@ -909,7 +914,7 @@ class to_utf8_view : public std::ranges::view_interface> { /* PAPER */ private: - exposition_only_to_utf_view_impl impl_; // @*exposition only*@ + exposition_only_to_utf_view_impl impl_; // @*exposition only*@ }; template @@ -972,7 +977,7 @@ class to_utf8_or_error_view /* PAPER */ private: - exposition_only_to_utf_view_impl impl_; // @*exposition only*@ + exposition_only_to_utf_view_impl impl_; // @*exposition only*@ }; template @@ -1034,7 +1039,7 @@ class to_utf16_view : public std::ranges::view_interface> { /* PAPER */ private: - exposition_only_to_utf_view_impl impl_; // @*exposition only*@ + exposition_only_to_utf_view_impl impl_; // @*exposition only*@ }; template @@ -1097,7 +1102,7 @@ class to_utf16_or_error_view /* PAPER */ private: - exposition_only_to_utf_view_impl impl_; // @*exposition only*@ + exposition_only_to_utf_view_impl impl_; // @*exposition only*@ }; template @@ -1165,7 +1170,7 @@ class to_utf32_view : public std::ranges::view_interface> { /* PAPER */ private: - exposition_only_to_utf_view_impl impl_; // @*exposition only*@ + exposition_only_to_utf_view_impl impl_; // @*exposition only*@ }; template @@ -1234,7 +1239,7 @@ class to_utf32_or_error_view /* PAPER */ private: - exposition_only_to_utf_view_impl impl_; // @*exposition only*@ + exposition_only_to_utf_view_impl impl_; // @*exposition only*@ }; template @@ -1244,9 +1249,9 @@ to_utf32_or_error_view(R&&) -> to_utf32_or_error_view>; namespace detail { - template + template using to_utf_view = std::conditional_t< - OrError, + E == to_utf_view_error_kind::expected, std::conditional_t< std::is_same_v, to_utf8_or_error_view, std::conditional_t, to_utf16_or_error_view, @@ -1258,8 +1263,8 @@ namespace detail { std::conditional_t, to_utf32_view, void>>>>; - template - struct to_utf_impl : std::ranges::range_adaptor_closure> { + template + struct to_utf_impl : std::ranges::range_adaptor_closure> { template constexpr auto operator()(R&& r) const { using T = std::remove_cvref_t; @@ -1273,10 +1278,10 @@ namespace detail { --last; } std::ranges::subrange subrange(first, last); - return to_utf_view(std::move(subrange)); + return to_utf_view(std::move(subrange)); } else { auto view = std::views::all(std::forward(r)); - return to_utf_view(std::move(view)); + return to_utf_view(std::move(view)); } } }; @@ -1284,22 +1289,22 @@ namespace detail { } // namespace detail template -inline constexpr detail::to_utf_impl to_utf; +inline constexpr detail::to_utf_impl to_utf; -inline constexpr detail::to_utf_impl to_utf8; +inline constexpr detail::to_utf_impl to_utf8; -inline constexpr detail::to_utf_impl to_utf16; +inline constexpr detail::to_utf_impl to_utf16; -inline constexpr detail::to_utf_impl to_utf32; +inline constexpr detail::to_utf_impl to_utf32; template -inline constexpr detail::to_utf_impl to_utf_or_error; +inline constexpr detail::to_utf_impl to_utf_or_error; -inline constexpr detail::to_utf_impl to_utf8_or_error; +inline constexpr detail::to_utf_impl to_utf8_or_error; -inline constexpr detail::to_utf_impl to_utf16_or_error; +inline constexpr detail::to_utf_impl to_utf16_or_error; -inline constexpr detail::to_utf_impl to_utf32_or_error; +inline constexpr detail::to_utf_impl to_utf32_or_error; /* PAPER: namespace views { */ /* PAPER: */ diff --git a/paper/P2728.md b/paper/P2728.md index 06b422e..4753aab 100644 --- a/paper/P2728.md +++ b/paper/P2728.md @@ -498,10 +498,19 @@ enum class utf_transcoding_error { }; ``` -#### 24.7.?.3 Exposition-only class template `@*to-utf-view-impl*@` [range.transcoding.view.impl] {-} +#### 24.7.?.3 Enumeration `to_utf_view_error_kind` [range.transcoding.error.kind] {-} ```c++ -template + enum class to_utf_view_error_kind : bool { + replacement, + expected + }; +``` + +#### 24.7.?.4 Exposition-only class template `@*to-utf-view-impl*@` [range.transcoding.view.impl] {-} + +```c++ +template requires view && @*code-unit*@> class @*to-utf-view-impl*@ private: @@ -590,11 +599,13 @@ transcoding view is empty if and only if its underlying range is empty. ::: -#### 24.7.?.4 Class `@*to-utf-view-impl*@::@*iterator*@` [range.transcoding.view.impl.iterator] {-} +#### 24.7.?.5 Class `@*to-utf-view-impl*@::@*iterator*@` [range.transcoding.view.impl.iterator] {-} ```c++ +template + requires view && @*code-unit*@> template -class @*to-utf-view-impl*@::@*iterator*@ { +class @*to-utf-view-impl*@::@*iterator*@ { private: using @*Parent*@ = @*maybe-const*@; // @*exposition only*@ using @*Base*@ = @*maybe-const*@; // @*exposition only*@ @@ -602,7 +613,7 @@ private: public: using iterator_concept = @*see below*@; using iterator_category = @*see below*@; // @*not always present*@ - using value_type = conditional_t, ToType>; + using value_type = conditional_t, ToType>; using reference_type = value_type; using difference_type = ptrdiff_t; @@ -615,7 +626,7 @@ private: int8_t buf_index_ = 0; // @*exposition only*@ uint8_t to_increment_ = 0; // @*exposition only*@ - template + template requires view && @*code-unit*@> friend class @*to-utf-view-impl*@; // @*exposition only*@ @@ -635,7 +646,7 @@ public: constexpr value_type operator*() const; - constexpr @*iterator*@& operator++() requires (OrError) + constexpr @*iterator*@& operator++() requires (E == to_utf_view_error_kind::expected) { if (!@*success*@()) { if constexpr (is_same_v) { @@ -647,7 +658,7 @@ public: return *this; } - constexpr @*iterator*@& operator++() requires (!OrError) + constexpr @*iterator*@& operator++() requires (E == to_utf_view_error_kind::replacement) { @*advance-one*@(); return *this; @@ -689,7 +700,7 @@ private: return end(parent_->@*base_*@); } - constexpr expected @*success*@() const noexcept requires(OrError); // @*exposition only*@ + constexpr expected @*success*@() const noexcept requires(E == to_utf_view_error_kind::expected); // @*exposition only*@ constexpr void @*advance-one*@() // @*exposition only*@ { @@ -759,10 +770,10 @@ In that case, `@*to-utf-view-impl*@::@*iterator*@::iterator_category` is defined constexpr value_type operator*() const; ``` -_Returns_: Either `buf_[buf_index_]`, or, if `OrError` is `true` and `!@*success*@()`, then `unexpected{@*success*@().error()}` +_Returns_: Either `buf_[buf_index_]`, or, if `E` is `to_utf_view_error_kind::expected` and `!@*success*@()`, then `unexpected{@*success*@().error()}` ```cpp -constexpr expected @*success*@() const noexcept requires(OrError); // @*exposition only*@ +constexpr expected @*success*@() const noexcept requires(E == to_utf_view_error_kind::expected); // @*exposition only*@ ``` _Returns_: @@ -833,13 +844,13 @@ the UTF encoding corresponding to `ToType`; and sets `buf_index_` to `buf_.size() - 1`, or to `0` if this is an `or_error` view and we read an invalid subsequence. -#### 24.7.?.5 Class `@*to-utf-view-impl*@::@*sentinel*@` [range.transcoding.view.impl.sentinel] {-} +#### 24.7.?.6 Class `@*to-utf-view-impl*@::@*sentinel*@` [range.transcoding.view.impl.sentinel] {-} ```c++ -template +template requires view && @*code-unit*@> template -class @*to-utf-view-impl*@::@*sentinel*@ { +class @*to-utf-view-impl*@::@*sentinel*@ { private: using @*Parent*@ = @*maybe-const*@; // @*exposition only*@ using @*Base*@ = @*maybe-const*@; // @*exposition only*@ @@ -867,7 +878,7 @@ public: }; ``` -#### 24.7.?.6 Class template `to_utf8_view` [range.transcoding.view.to_utf8] +#### 24.7.?.7 Class template `to_utf8_view` [range.transcoding.view.to_utf8] ```c++ template @@ -909,7 +920,7 @@ template to_utf8_view(R&&) -> to_utf8_view>; ``` -#### 24.7.?.7 Class template `to_utf8_or_error_view` [range.transcoding.view.to_utf8_or_error] +#### 24.7.?.8 Class template `to_utf8_or_error_view` [range.transcoding.view.to_utf8_or_error] ```c++ template @@ -951,7 +962,7 @@ template to_utf8_or_error_view(R&&) -> to_utf8_or_error_view>; ``` -#### 24.7.?.8 Class template `to_utf16_view` [range.transcoding.view.to_utf16] +#### 24.7.?.9 Class template `to_utf16_view` [range.transcoding.view.to_utf16] ```c++ template @@ -993,7 +1004,7 @@ template to_utf16_view(R&&) -> to_utf16_view>; ``` -#### 24.7.?.9 Class template `to_utf16_or_error_view` [range.transcoding.view.to_utf16_or_error] +#### 24.7.?.10 Class template `to_utf16_or_error_view` [range.transcoding.view.to_utf16_or_error] ```c++ template @@ -1040,7 +1051,7 @@ template to_utf16_or_error_view(R&&) -> to_utf16_or_error_view>; ``` -#### 24.7.?.10 Class template `to_utf32_view` [range.transcoding.view.to_utf32] +#### 24.7.?.11 Class template `to_utf32_view` [range.transcoding.view.to_utf32] ```c++ template @@ -1087,7 +1098,7 @@ template to_utf32_view(R&&) -> to_utf32_view>; ``` -#### 24.7.?.11 Class template `to_utf32_or_error_view` [range.transcoding.view.to_utf32_or_error] +#### 24.7.?.12 Class template `to_utf32_or_error_view` [range.transcoding.view.to_utf32_or_error] ```c++ template @@ -1555,6 +1566,11 @@ These concepts are true when the type in question is the iterator/sentinel of a # Changelog +## Changes since R9 + +- Replace bool OrError CTP with `to_utf_view_error_kind` enum class like + ranges::subrange_kind + ## Changes since R8 - Fix const correctness bug in wording relating to noncopyable input iterators