Bug 271931 - The C++20 feature 'std::ranges::copy' is missing
Summary: The C++20 feature 'std::ranges::copy' is missing
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: standards (show other bugs)
Version: 13.2-RELEASE
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-standards (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-06-10 00:40 UTC by Yuri Victorovich
Modified: 2023-07-14 20:29 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Yuri Victorovich freebsd_committer freebsd_triage 2023-06-10 00:40:34 UTC
The example from https://en.cppreference.com/w/cpp/algorithm/ranges/copy fails to compile:
> c++ranges-copy.cpp:16:5: error: no member named 'copy' in namespace 'std::ranges'; did you mean 'std::copy'?
>     std::ranges::copy(source.begin(), source.end(),
>     ^~~~~~~~~~~~~~~~~
>     std::copy

The page tracking the status of C++20 features https://en.cppreference.com/w/cpp/20 doesn't list 'std::ranges::copy' which means that it should be available?
Comment 1 Mark Millard 2023-06-10 02:15:05 UTC
https://en.cppreference.com/w/cpp/ranges does not show there
being such a thing as a copy method directly in what <ranges>
supplies. But . . .

https://en.cppreference.com/w/cpp/algorithm/ranges does
show <algorithm> as supplying such.

Did the example code trying to use std::ranges::copy
have <algorithm> explicitly?
Comment 2 Mark Millard 2023-06-10 02:16:55 UTC
(In reply to Mark Millard from comment #1)

Never mind. I processed the information out of order. (Bad day.)
Comment 3 Mark Millard 2023-06-10 03:56:40 UTC
Trying for some slight useful information this time:

When I look in /usr/include/c++/v1/algorithm I see:

. . .
#include <__algorithm/ranges_copy.h>
. . .

Looking there:

. . .
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)

_LIBCPP_BEGIN_NAMESPACE_STD

namespace ranges {

template <class _InIter, class _OutIter>
using copy_result = in_out_result<_InIter, _OutIter>;

namespace __copy {
. . .
} // namespace __copy

inline namespace __cpo {
  inline constexpr auto copy = __copy::__fn{};
} // namespace __cpo
} // namespace ranges

_LIBCPP_END_NAMESPACE_STD

#endif // _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
. . .

Thus:

# c++ -std=c++2b -pedantic -Wall -Wextra -fexperimental-library ranges_copy.cpp
# ./a.out
destination contains: 0 1 2 3 4 5 6 7 8 9 
odd numbers in destination are: 1 3 5 7 9 

from /usr/include/c++/v1/__config having:

#  if __has_feature(experimental_library)
#    ifndef _LIBCPP_ENABLE_EXPERIMENTAL
#      define _LIBCPP_ENABLE_EXPERIMENTAL
#    endif
#  endif
      
// Incomplete features get their own specific disabling flags. This makes it
// easier to grep for target specific flags once the feature is complete.
#  if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY)
#    define _LIBCPP_HAS_NO_INCOMPLETE_FORMAT
#    define _LIBCPP_HAS_NO_INCOMPLETE_RANGES
#  endif

15.0.7 likely requires -fexperimental-library for many things
to be enabled because of the overall thing being incomplete or
known to be partially broken, such as C++20 ranges overall
having some parts not sufficiently handled (apparently).
Comment 4 Mark Millard 2023-06-10 03:59:08 UTC
(In reply to Mark Millard from comment #3)

FYI: Using -std=c++20 also gets that same result:

# c++ -std=c++20 -pedantic -Wall -Wextra -fexperimental-library ranges_copy.cpp
# ./a.out
destination contains: 0 1 2 3 4 5 6 7 8 9 
odd numbers in destination are: 1 3 5 7 9
Comment 5 Mark Millard 2023-06-10 05:17:41 UTC
FYI: https://libcxx.llvm.org//Status/Cxx20.html#cxx20-status
documents the following as being completed in llvm 16 for
C++20 Ranges (I omitted the "ranges" row labels from the
right hand sides of the rows in order to have shorter lines):


P1035R7	LWG	Input Range Adaptors	Cologne	Complete	16.0

P1638R1	LWG	basic_istream_view::iterator should not be copyable	Cologne	Complete	16.0

P1862R1	LWG	Ranges adaptors for non-copyable iterators	Belfast	Complete	16.0

P1994R1	LWG	elements_view needs its own sentinel	Prague	Complete	16.0

P2325R3	LWG	Views should not be required to be default constructible	June 2021	Complete	16.0

P2210R2	LWG	Superior String Splitting	June 2021	Complete	16.0

P2432R1	LWG	Fix istream_view	October 2021	Complete	16.0

3302	Range adaptor objects keys and values are unspecified	Prague	Complete	16.0

3323	*has-tuple-element* helper concept needs convertible_to	Prague	Complete	16.0

3364	Initialize data members of ranges and their iterators	Prague	Complete	16.0

3388	view iterator types have ill-formed <=> operators	Prague	Complete	16.0

3397	ranges::basic_istream_view::iterator should not provide iterator_category	Prague	Complete	16.0


These were apparently enough for them to have classified LLVM 15's implementation
of C++20 Ranges as experimental.
Comment 6 Yuri Victorovich freebsd_committer freebsd_triage 2023-07-14 19:01:14 UTC
https://libcxx.llvm.org//Status/Cxx20.html#cxx20-status says that "The One Ranges Proposal" was completed in llvm-15.0:

> P0896R4 	LWG 	The One Ranges Proposal Complete   15.0

Yet std::ranges::for_each which is a part of "The One Ranges Proposal" isn't available in clang installed by the llvm-16 package on FreeBSD 13.2.

Do we know why std::ranges::for_each isn't available in clang-16?


> In file included from ../include/effects_base.hpp:48:
> ../include/rnnoise.hpp:93:11: error: no member named 'for_each' in namespace 'std::ranges'; did you mean 'std::for_each'?
>           std::ranges::for_each(data_L, [](auto& v) { v *= static_cast<float>(SHRT_MAX + 1); });
>           ^~~~~~~~~~~~~~~~~~~~~
>           std::for_each
>
Comment 7 Dimitry Andric freebsd_committer freebsd_triage 2023-07-14 19:56:20 UTC
Upstream implemented std::ranges::for_each here: https://github.com/llvm/llvm-project/commit/80045e9afa2f3545d3b1f2d06090a9a053a90307

However, the feature is gated behind a `_LIBCPP_HAS_NO_INCOMPLETE_RANGES` define, currently enabled by default in /usr/include/c++/v1/__config:

// Incomplete features get their own specific disabling flags. This makes it
// easier to grep for target specific flags once the feature is complete.
#  if !defined(_LIBCPP_ENABLE_EXPERIMENTAL) && !defined(_LIBCPP_BUILDING_LIBRARY)
#    define _LIBCPP_HAS_NO_INCOMPLETE_FORMAT
#    define _LIBCPP_HAS_NO_INCOMPLETE_RANGES
#  endif

In https://github.com/llvm/llvm-project/commit/b8cb1dc9ea87faa8e8e9ab7a31710a8c0bb8b084 this was removed, so it shipped in libc++ 16.0.0.

Unfortunately, if you install the llvm port, you only get the compiler, linker etc, but the C++ library from the base system is still used, so on 13.2 that be libc++ 15.0.
Comment 8 Mark Millard 2023-07-14 20:29:13 UTC
(In reply to Yuri Victorovich from comment #6)

FreeBSD 13.2 uses the system's libc++ library, which is from LLVM 15,
not LLVM 16 at this point. So comment #3 still applies for all
devel/llvm* installations.

In other words: use the -fexperimental-library option to get a
preliminary/partial/somewhat-non-compliant implementation enabled
for FreeBSD 13.2. Also supply an appropriate -std=c++?? .