Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement ranges::ssize #1076

Merged
merged 5 commits into from
Aug 1, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
45 changes: 37 additions & 8 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,10 @@ concept weakly_incrementable = default_initializable<_Ty> && movable<_Ty> && req
template <class _Ty>
using _Make_unsigned_like_t = make_unsigned_t<_Ty>;

// ALIAS TEMPLATE _Make_signed_like_t
template <class _Ty>
using _Make_signed_like_t = make_signed_t<_Ty>; // Per the proposed resolution of LWG-3403

// CONCEPT incrementable
template <class _Ty>
concept incrementable = regular<_Ty> && weakly_incrementable<_Ty> && requires(_Ty __t) {
Expand Down Expand Up @@ -3121,7 +3125,7 @@ namespace ranges {
~_Not_quite_object() = default;
};

// CLASS ranges::_Advance_fn
// VARIABLE ranges::advance
class _Advance_fn : private _Not_quite_object {
public:
using _Not_quite_object::_Not_quite_object;
Expand Down Expand Up @@ -3211,10 +3215,9 @@ namespace ranges {
}
};

// VARIABLE ranges::advance
inline constexpr _Advance_fn advance{_Not_quite_object::_Construct_tag{}};

// CLASS ranges::_Distance_fn
// VARIABLE ranges::distance
class _Distance_fn : private _Not_quite_object {
public:
using _Not_quite_object::_Not_quite_object;
Expand Down Expand Up @@ -3246,10 +3249,38 @@ namespace ranges {
}
};

// VARIABLE ranges::distance
inline constexpr _Distance_fn distance{_Not_quite_object::_Construct_tag{}};

// CLASS ranges::_Next_fn
// VARIABLE ranges::ssize
class _Ssize_fn { // Per the proposed resolution of LWG-3403
public:
// clang-format off
template <class _Rng>
_NODISCARD constexpr auto operator()(_Rng&& _Range) const requires requires { _RANGES size(_Range); } {
using _SSSsssigned = _Make_signed_like_t<decltype(_RANGES size(_Range))>;
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
using _Ty = typename _Parsel_type<is_integral_v<_SSSsssigned>>::template _Apply<_SSSsssigned>;
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
return static_cast<_Ty>(_RANGES size(_Range));
}
// clang-format on
private:
template <bool _IsIntegral>
struct _Parsel_type {
template <class _Ty>
using _Apply = common_type_t<ptrdiff_t, _Ty>;
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
};

template <>
struct _Parsel_type<false> {
template <class _Ty>
using _Apply = _Ty;
};
};

inline namespace _Cpos {
inline constexpr _Ssize_fn ssize;
}

// VARIABLE ranges::next
class _Next_fn : private _Not_quite_object {
public:
using _Not_quite_object::_Not_quite_object;
Expand Down Expand Up @@ -3279,10 +3310,9 @@ namespace ranges {
}
};

// VARIABLE ranges::next
inline constexpr _Next_fn next{_Not_quite_object::_Construct_tag{}};

// CLASS ranges::_Prev_fn
// VARIABLE ranges::prev
class _Prev_fn : private _Not_quite_object {
public:
using _Not_quite_object::_Not_quite_object;
Expand All @@ -3308,7 +3338,6 @@ namespace ranges {
}
};

// VARIABLE ranges::prev
inline constexpr _Prev_fn prev{_Not_quite_object::_Construct_tag{}};

// FUNCTION TEMPLATE _Find_last_iterator
Expand Down
1 change: 1 addition & 0 deletions stl/inc/yvals_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@
// P1871R1 disable_sized_sentinel_for
// P1872R0 span Should Have size_type, Not index_type
// P1878R1 Constraining Readable Types
// P1907R2 ranges::ssize
// P1956R1 <bit> has_single_bit(), bit_ceil(), bit_floor(), bit_width()
// P1959R0 Removing weak_equality And strong_equality
// P1964R2 Replacing boolean With boolean-testable
Expand Down
14 changes: 13 additions & 1 deletion tests/std/tests/P0896R4_ranges_range_machinery/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ concept CanEmpty = requires(R&& r) { ranges::empty(std::forward<R>(r)); };
template <class R>
concept CanSize = requires(R&& r) { ranges::size(std::forward<R>(r)); };

template <class R>
concept CanSSize = requires(R&& r) { ranges::ssize(std::forward<R>(r)); };

template <class R>
concept CanSizeType = requires { typename ranges::range_size_t<R>; };

Expand Down Expand Up @@ -116,6 +119,7 @@ STATIC_ASSERT(test_cpo(ranges::rend));
STATIC_ASSERT(test_cpo(ranges::crbegin));
STATIC_ASSERT(test_cpo(ranges::crend));
STATIC_ASSERT(test_cpo(ranges::size));
STATIC_ASSERT(test_cpo(ranges::ssize));
STATIC_ASSERT(test_cpo(ranges::empty));
STATIC_ASSERT(test_cpo(ranges::data));
STATIC_ASSERT(test_cpo(ranges::cdata));
Expand All @@ -136,6 +140,7 @@ void test_cpo_ambiguity() {
(void) crbegin(vri);
(void) crend(vri);
(void) size(vri);
(void) ssize(vri);
(void) empty(vri);
(void) data(vri);
(void) cdata(vri);
Expand Down Expand Up @@ -315,16 +320,20 @@ constexpr bool test_empty() {

template <class Range, class Size = invalid_type>
constexpr bool test_size() {
// Validate ranges::size and ranges::sized_range
// Validate ranges::size, ranges::sized_range, and ranges::ssize
STATIC_ASSERT(!is_valid<Size> || std::integral<Size>);

STATIC_ASSERT(CanSize<Range> == is_valid<Size>);
STATIC_ASSERT(CanSSize<Range> == is_valid<Size>);
STATIC_ASSERT(CanSizeType<Range> == is_valid<Size>);
STATIC_ASSERT(ranges::sized_range<Range> == is_valid<Size>);
if constexpr (is_valid<Size>) {
STATIC_ASSERT(std::same_as<decltype(ranges::size(std::declval<Range>())), Size>);
STATIC_ASSERT(std::same_as<ranges::range_size_t<Range>, Size>);

using SS = std::common_type_t<std::ptrdiff_t, std::make_signed_t<Size>>;
STATIC_ASSERT(std::same_as<decltype(ranges::ssize(std::declval<Range>())), SS>);
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved

STATIC_ASSERT(CanEmpty<Range>);
}

Expand Down Expand Up @@ -1612,6 +1621,9 @@ namespace exhaustive_size_and_view_test {
STATIC_ASSERT(ranges::sized_range<Rng> == is_valid<Size>);
if constexpr (is_valid<Size>) {
STATIC_ASSERT(std::same_as<decltype(ranges::size(std::declval<Rng>())), Size>);

using SS = std::common_type_t<std::ptrdiff_t, std::make_signed_t<Size>>;
STATIC_ASSERT(std::same_as<decltype(ranges::ssize(std::declval<Rng>())), SS>);
}

STATIC_ASSERT(ranges::view<Rng> == IsView);
Expand Down