Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions include/beman/utf_view/detail/constant_wrapper_polyfill.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: BSL-1.0

// Copyright Eddie Nolan and Jonathan Wakely 2023 - 2025.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is new in 2026, and it's all your work, isn't it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created #199 to address this

// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)

#ifndef BEMAN_UTF_VIEW_CONSTANT_WRAPPER_POLYFILL_HPP
#define BEMAN_UTF_VIEW_CONSTANT_WRAPPER_POLYFILL_HPP

#include <utility>
#include <version>

namespace beman::utf_view::detail {

#ifdef __cpp_lib_constant_wrapper

template <auto X, typename T>
using constant_wrapper = std::constant_wrapper<X, T>;

template<auto X> constexpr auto cw{std::cw<X>};

#else

template<auto X, typename T>
struct constant_wrapper {
static constexpr const auto value = X;
};

template<auto X> constexpr auto cw{constant_wrapper<X, decltype(X)>{}};

#endif


} // namespace beman::utf_view::detail

#endif // BEMAN_UTF_VIEW_CONSTANT_WRAPPER_POLYFILL_HPP
37 changes: 0 additions & 37 deletions include/beman/utf_view/detail/nontype_t_polyfill.hpp

This file was deleted.

22 changes: 13 additions & 9 deletions include/beman/utf_view/to_utf_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <beman/utf_view/detail/concepts.hpp>
#include <beman/utf_view/detail/constexpr_unless_msvc.hpp>
#include <beman/utf_view/detail/fake_inplace_vector.hpp>
#include <beman/utf_view/detail/nontype_t_polyfill.hpp>
#include <beman/utf_view/detail/constant_wrapper_polyfill.hpp>
#include <bit>
#include <cassert>
#include <concepts>
Expand Down Expand Up @@ -131,9 +131,13 @@ class to_utf_view : public std::ranges::view_interface<to_utf_view<V, E, ToType>
constexpr to_utf_view()
requires std::default_initializable<V>
= default;
/* PAPER: constexpr explicit to_utf_view(V base, nontype_t<E>, to_utf_tag_t<ToType>); */
/* PAPER: template <auto E2> */
/* PAPER: constexpr explicit to_utf_view(V base, constant_wrapper<E2, to_utf_view_error_kind>, to_utf_tag_t<ToType>) */
/* PAPER: requires (constant_wrapper<E2, to_utf_view_error_kind>::value == E); */
/* !PAPER */
constexpr explicit to_utf_view(V base, detail::nontype_t<E>, to_utf_tag_t<ToType>)
template <auto E2>
constexpr explicit to_utf_view(V base, detail::constant_wrapper<E2, to_utf_view_error_kind>, to_utf_tag_t<ToType>)
requires (detail::constant_wrapper<E2, to_utf_view_error_kind>::value == E)
: base_(std::move(base)) { }
/* PAPER */

Expand Down Expand Up @@ -202,8 +206,8 @@ class to_utf_view : public std::ranges::view_interface<to_utf_view<V, E, ToType>
/* PAPER */
};

template <class R, to_utf_view_error_kind E, exposition_only_code_unit ToType>
to_utf_view(R&&, detail::nontype_t<E>, to_utf_tag_t<ToType>) -> to_utf_view<std::views::all_t<R>, E, ToType>;
template <class R, auto E2, exposition_only_code_unit ToType>
to_utf_view(R&&, detail::constant_wrapper<E2, to_utf_view_error_kind>, to_utf_tag_t<ToType>) -> to_utf_view<std::views::all_t<R>, detail::constant_wrapper<E2, to_utf_view_error_kind>::value, ToType>;

template <std::ranges::input_range V, to_utf_view_error_kind E, exposition_only_code_unit ToType>
requires std::ranges::view<V> && exposition_only_code_unit<std::ranges::range_value_t<V>>
Expand Down Expand Up @@ -884,14 +888,14 @@ namespace detail {
return std::ranges::empty_view<std::expected<ToType, utf_transcoding_error>>{};
}
} else if constexpr (detail::is_to_utf_view_v<T>) {
return to_utf_view(std::forward<R>(r).base(), detail::nontype<E>, to_utf_tag<ToType>);
return to_utf_view(std::forward<R>(r).base(), detail::cw<E>, to_utf_tag<ToType>);
} else if constexpr (detail::is_to_utf_subrange_v<T>) {
return to_utf_view(
std::ranges::subrange(r.begin().base(), r.end().base()),
detail::nontype<E>,
detail::cw<E>,
to_utf_tag<ToType>);
} else {
return to_utf_view(std::forward<R>(r), detail::nontype<E>, to_utf_tag<ToType>);
} else {
return to_utf_view(std::forward<R>(r), detail::cw<E>, to_utf_tag<ToType>);
}
}
};
Expand Down
23 changes: 16 additions & 7 deletions papers/P2728.md
Original file line number Diff line number Diff line change
Expand Up @@ -496,14 +496,14 @@ expression-equivalent to:
- Otherwise, `empty_view<expected<Char, utf_trancoding_error>>{}`.

- Otherwise, if the type of `E` is a (possibly cv-qualified) specialization of
`to_utf_view`, then `to_utf_view(E.base(), nontype<Error>, to_utf_tag<Char>)`.
`to_utf_view`, then `to_utf_view(E.base(), cw<Error>, to_utf_tag<Char>)`.

- Otherwise, if the type of `E` is *cv* `subrange<to_utf_view::@*iterator*@,
to_utf_view::@*iterator*@, subrange_kind::unsized>` for some specialization of
`to_utf_view`, then `to_utf_view(subrange(E.begin().base(), E.end().base()),
nontype<Error>, to_utf_tag<Char>)`.
cw<Error>, to_utf_tag<Char>)`.

- Otherwise, `to_utf_view(E, nontype<Error>, to_utf_tag<Char>)`.
- Otherwise, `to_utf_view(E, cw<Error>, to_utf_tag<Char>)`.

#### 24.7.?.2 Enumeration `utf_transcoding_error` [range.transcoding.error.transcoding] {-}

Expand Down Expand Up @@ -569,7 +569,9 @@ private:

public:
constexpr to_utf_view() requires default_initializable<V> = default;
constexpr explicit to_utf_view(V base, nontype_t<E>, to_utf_tag_t<ToType>);
template <auto E2>
constexpr explicit to_utf_view(V base, constant_wrapper<E2, to_utf_view_error_kind>, to_utf_tag_t<ToType>)
requires (constant_wrapper<E2, to_utf_view_error_kind>::value == E);

constexpr V base() const& requires copy_constructible<V> { return @*base_*@; }
constexpr V base() && { return std::move(@*base_*@); }
Expand Down Expand Up @@ -607,12 +609,15 @@ public:
constexpr auto reserve_hint() const requires approximately_sized_range<const V>;
};

template<class R, to_utf_view_error_kind E, @*code-unit*@ ToType>
to_utf_view(R&&, nontype_t<E>, to_utf_tag_t<ToType>) -> to_utf_view<views::all_t<R>, E, ToType>;
template<class R, auto E2, @*code-unit*@ ToType>
to_utf_view(R&&, constant_wrapper<E2, to_utf_view_error_kind>, to_utf_tag_t<ToType>)
-> to_utf_view<views::all_t<R>, constant_wrapper<E2, to_utf_view_error_kind>::value, ToType>;
```

```cpp
constexpr explicit to_utf_view(V base, nontype_t<E>, to_utf_tag_t<ToType>);
template <auto E2>
constexpr explicit to_utf_view(V base, constant_wrapper<E2, to_utf_view_error_kind>, to_utf_tag_t<ToType>)
requires (constant_wrapper<E2, to_utf_view_error_kind>::value == E);
```

_Effects_: Initializes `@*base_*@` with `std::move(base)`.
Expand Down Expand Up @@ -1067,6 +1072,10 @@ gives back the original underlying view if it detects that it's reversing anothe

# Changelog

## Changes since R11

- Refactor use of `std::nontype` to use `std::constant_wrapper` instead per P3948.

## Changes since R10

- Fix the wording around rejecting arrays for the code unit adaptors
Expand Down
2 changes: 1 addition & 1 deletion src/beman/utf_view/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ target_sources(
FILES
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/utf_view/code_unit_view.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/utf_view/detail/concepts.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/utf_view/detail/constant_wrapper_polyfill.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/utf_view/detail/constexpr_unless_msvc.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/utf_view/detail/fake_inplace_vector.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/utf_view/detail/nontype_t_polyfill.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/utf_view/endian_view.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/utf_view/null_term.hpp
${CMAKE_CURRENT_SOURCE_DIR}/../../../include/beman/utf_view/to_utf_view.hpp
Expand Down
3 changes: 2 additions & 1 deletion tests/beman/utf_view/to_utf_view.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
// (See accompanying file LICENSE.txt or copy at
// https://www.boost.org/LICENSE_1_0.txt)

#include <beman/utf_view/detail/constant_wrapper_polyfill.hpp>
#include <beman/utf_view/detail/constexpr_unless_msvc.hpp>
#include <beman/utf_view/null_term.hpp>
#include <beman/utf_view/to_utf_view.hpp>
Expand Down Expand Up @@ -871,7 +872,7 @@ constexpr bool empty_test() {
std::is_same_v<
decltype(std::views::empty<char8_t> | to_utf8_or_error),
std::ranges::empty_view<std::expected<char8_t, utf_transcoding_error>>>);
auto empty_utf{to_utf_view{std::views::empty<char8_t>, detail::nontype<to_utf_view_error_kind::replacement>, to_utf8_tag}};
auto empty_utf{to_utf_view{std::views::empty<char8_t>, detail::cw<to_utf_view_error_kind::replacement>, to_utf8_tag}};
if (!empty_utf.empty()) {
return false;
}
Expand Down
Loading