diff --git a/libcxx/docs/Status/RangesPaper.csv b/libcxx/docs/Status/RangesPaper.csv --- a/libcxx/docs/Status/RangesPaper.csv +++ b/libcxx/docs/Status/RangesPaper.csv @@ -103,10 +103,10 @@ | `ranges::iterator_t `_ | `ranges::sentinel_t `_ | `ranges::range_difference_t `_ -| ranges::range_size_t +| `ranges::range_size_t `_ | `ranges::range_value_t `_ | `ranges::range_reference_t `_ -| `ranges::range_rvalue_reference_t `_",[range.access],Christopher Di Bella,In progress +| `ranges::range_rvalue_reference_t `_",[range.access],Christopher Di Bella,✅ `[range.sized] `_,"| `ranges::sized_range `_ | `ranges::disable_sized_range `_","| [range.primitives] | [range.range]",Christopher Di Bella,✅ diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h --- a/libcxx/include/__ranges/concepts.h +++ b/libcxx/include/__ranges/concepts.h @@ -69,6 +69,9 @@ template concept sized_range = range<_Tp> && requires(_Tp& __t) { ranges::size(__t); }; + template + using range_size_t = decltype(ranges::size(declval<_Rp&>())); + // `disable_sized_range` defined in `<__ranges/size.h>` // [range.view], views diff --git a/libcxx/include/ranges b/libcxx/include/ranges --- a/libcxx/include/ranges +++ b/libcxx/include/ranges @@ -36,13 +36,13 @@ inline constexpr bool enable_borrowed_range = false; template - using iterator_t = decltype(ranges::begin(declval())); - template - using iterator_t = decltype(ranges::begin(declval())); + using iterator_t = decltype(ranges::begin(declval())); template using sentinel_t = decltype(ranges::end(declval())); template using range_difference_t = iter_difference_t>; + template + using range_size_t = decltype(ranges::size(declval())); template using range_value_t = iter_value_t>; template diff --git a/libcxx/test/std/ranges/range.req/range.range/range_size_t.compile.pass.cpp b/libcxx/test/std/ranges/range.req/range.range/range_size_t.compile.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/ranges/range.req/range.range/range_size_t.compile.pass.cpp @@ -0,0 +1,42 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 +// UNSUPPORTED: libcpp-no-concepts +// UNSUPPORTED: gcc-10 + +// template +// using range_size_t = decltype(ranges::size(declval())); + +#include +#include +#include + +#include "test_iterators.h" + +template +concept has_range_size_t = requires { typename std::ranges::range_size_t; }; + +struct A { int *begin(); int *end(); short size(); }; +static_assert(std::same_as, short>); +static_assert(std::same_as, short>); +static_assert(std::same_as, short>); +static_assert(!has_range_size_t); +static_assert(!has_range_size_t); +static_assert(!has_range_size_t); + +struct B { int *begin(); int *end(); }; +static_assert(std::same_as, std::size_t>); +static_assert(std::same_as, std::size_t>); +static_assert(std::same_as, std::size_t>); +static_assert(!has_range_size_t); +static_assert(!has_range_size_t); +static_assert(!has_range_size_t); + +struct C { bidirectional_iterator begin(); bidirectional_iterator end(); }; +static_assert(!has_range_size_t);