Solved Failed to compile any C++ using std::ranges::reverse with clang

I have attempted to compile ueberzugpp (Überzug++) a few times using clang/clang++ (14, 15, and 16) and gcc14/gcc++14. clang --version returns 14.0.5. I am on 13.2-RELEASE and am fully up to date with both freebsd-update and pkg, which is set to latest.

I first satisfied its dependencies
pkg install cmake gmake vips libsixel chafa onetbb nlohmann-json cli11 libfmt microsoft-gsl

When I try building it with gcc it builds to 100%, but at the end results in ld errors. I gave up with gcc14/g++14 and instead tried building with clang. I added
Code:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -I/usr/local/include -L/usr/local/lib")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/usr/include/c++ -I/usr/local/include")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/lib")
to CMakeLists.txt
Before running the commands I set CC and CXX environment variables to the respective versions of clang. I tried clang14, clang15, and clang16, with the respective clang++ versions. I then followed the github, using the commands:
Code:
cd ueberzugpp
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_X11=OFF -DENABLE_OPENCV=OFF ..    # On Wayland. Didn't get opencv. Always gave expected outputs.
cmake --build .
First cmake command would work as expected, but then when bulding, the output would always be:
Code:
/ueberzugpp/src/terminal.cpp:302:11: error: no member named 'reverse' in namespace 'std::ranges'; did you mean 'std::reverse'?
    using std::ranges::reverse;
          ^~~~~~~~~~~~~~~~~~~~
          std::reverse
/usr/include/c++/v1/__algorithm/reverse.h:49:1: note: 'std::reverse' declared here
reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
^
/ueberzugpp/src/terminal.cpp:309:9: error: no matching function for call to 'reverse'
        reverse(tree);
        ^~~~~~~
/usr/include/c++/v1/__algorithm/reverse.h:49:1: note: candidate function not viable: requires 2 arguments, but 1 was provided
reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
^
2 errors generated.
gmake[2]: *** [CMakeFiles/ueberzug.dir/build.make:146: CMakeFiles/ueberzug.dir/src/terminal.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/ueberzug.dir/all] Error 2
gmake: *** [Makefile:136: all] Error 2

Anything I try building that uses std::ranges::reverse that I think should be defined by algorithm fails to build with clang++ -std=c++20:
Code:
./test.cpp:10:5: error: no member named 'reverse' in namespace 'std::ranges'; did you mean 'std::reverse'?
    std::ranges::reverse(s.begin(), s.end());
    ^~~~~~~~~~~~~~~~~~~~
    std::reverse
/usr/include/c++/v1/__algorithm/reverse.h:49:1: note: 'std::reverse' declared here
reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
^
./test.cpp:12:18: error: no type named 'reverse' in namespace 'std::ranges'
    std::ranges::reverse(s);
    ~~~~~~~~~~~~~^
./test.cpp:19:18: error: no type named 'reverse' in namespace 'std::ranges'
    std::ranges::reverse(a);
    ~~~~~~~~~~~~~^
3 errors generated.

How can I get it to compile/will it likely compile on 14.0?
 
You could just provide an implementation (taken fromcppreference).

Code:
struct reverse_fn
{
    template<std::bidirectional_iterator I, std::sentinel_for<I> S>
    requires std::permutable<I>
    constexpr I operator()(I first, S last) const
    {
        auto last2 {ranges::next(first, last)};
        for (auto tail {last2}; !(first == tail or first == --tail); ++first)
            ranges::iter_swap(first, tail);
        return last2;
    }
 
    template<ranges::bidirectional_range R>
    requires std::permutable<ranges::iterator_t<R>>
    constexpr ranges::borrowed_iterator_t<R>
        operator()(R&& r) const
    {
        return (*this)(ranges::begin(r), ranges::end(r));
    }
};
 
inline constexpr reverse_fn reverse {};
 
Hello & Welcome to this FreeBSD Community!

When I try building it with gcc it builds to 100%, but at the end results in ld errors.
I assume this is because your dependencies (pulled in via pkg) are built with clang so they can't be "used" by GCC built binaries due to differences in the binary interfaces.
When you want to build something with GCC, you also need to build all binary dependencies with GCC.

Anything I try building that uses std::ranges::reverse that I think should be defined by algorithm fails to build with clang++ -std=c++20
Clang is lacking a bit behind when it comes to library support for ranges. Check which version of clang actually supports std::ranges::reverse.
And depending your findings, what cracauer@ proposed.
 
You could just provide an implementation (taken from cppreference).

Code:
struct reverse_fn
{
    template<std::bidirectional_iterator I, std::sentinel_for<I> S>
    requires std::permutable<I>
    constexpr I operator()(I first, S last) const
    {
        auto last2 {ranges::next(first, last)};
        for (auto tail {last2}; !(first == tail or first == --tail); ++first)
            ranges::iter_swap(first, tail);
        return last2;
    }
 
    template<ranges::bidirectional_range R>
    requires std::permutable<ranges::iterator_t<R>>
    constexpr ranges::borrowed_iterator_t<R>
        operator()(R&& r) const
    {
        return (*this)(ranges::begin(r), ranges::end(r));
    }
};
 
inline constexpr reverse_fn reverse {};
I added the iterator header to the test and tried to build the test with clang but it results in the error, " no member named 'permutable' in namespace 'std'". Have I made a mistake?
Hello & Welcome to this FreeBSD Community!
Thank you!
I assume this is because your dependencies (pulled in via pkg) are built with clang so they can't be "used" by GCC built binaries due to differences in the binary interfaces.
When you want to build something with GCC, you also need to build all binary dependencies with GCC.
I should probably just edit make.conf to use gcc/g++ then build the dependencies from ports instead of trying to force clang to build it.
Check which version of clang actually supports std::ranges::reverse.
Do you know where I could check that? I've tried the cppreference C++ compiler support page and couldn't find any results for ranges::reverse when searching the page.
 
Do you know where I could check that?

I added the iterator header to the test and tried to build the test with clang but it results in the error, " no member named 'permutable' in namespace 'std'". Have I made a mistake?
Either you didn't include the necessary header or your C++ library doesn't implement it yet. See link above.

std::ranges requires libc++ >= 16 shipped in FreeBSD >= 13.3/14.0. Clang version doesn't matter, so installing devel/llvm won't help.
One of the reasons why my desktops are on stable/13 (and now stable/14).
 
Back
Top