diff --git a/gnu/local.mk b/gnu/local.mk index 07e0785c05..d4874d4e53 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -1686,6 +1686,7 @@ dist_patch_DATA = \ %D%/packages/patches/qtwebkit-fix-building-with-icu-68.patch \ %D%/packages/patches/qtwebkit-fix-building-with-glib-2.68.patch \ %D%/packages/patches/randomjungle-disable-static-build.patch \ + %D%/packages/patches/range-v3-build-with-gcc10.patch \ %D%/packages/patches/rapicorn-isnan.patch \ %D%/packages/patches/rapidjson-gcc-compat.patch \ %D%/packages/patches/raptor2-heap-overflow.patch \ diff --git a/gnu/packages/cpp.scm b/gnu/packages/cpp.scm index 7ac4b0c39b..154d5ae333 100644 --- a/gnu/packages/cpp.scm +++ b/gnu/packages/cpp.scm @@ -89,11 +89,13 @@ (commit version))) (file-name (git-file-name name version)) + (patches (search-patches "range-v3-build-with-gcc10.patch")) (sha256 (base32 "18230bg4rq9pmm5f8f65j444jpq56rld4fhmpham8q3vr1c1bdjh")))) (build-system cmake-build-system) (native-inputs `(("doxygen" ,doxygen) + ("gcc" ,gcc-9) ("perl" ,perl))) (inputs `(("boost" ,boost))) diff --git a/gnu/packages/patches/range-v3-build-with-gcc10.patch b/gnu/packages/patches/range-v3-build-with-gcc10.patch new file mode 100644 index 0000000000..a5d5b33523 --- /dev/null +++ b/gnu/packages/patches/range-v3-build-with-gcc10.patch @@ -0,0 +1,122 @@ +From 0487cca29e352e8f16bbd91fda38e76e39a0ed28 Mon Sep 17 00:00:00 2001 +From: Louis Dionne +Date: Tue, 15 Jun 2021 14:40:01 -0400 +Subject: [PATCH] Work around broken integration with latest libc++. (#1635) + +* Work around broken integration with latest libc++. + +In newer versions of libc++, the base template of std::iterator_traits +provides a member typedef called __primary_template which is an alias +to the std::iterator_traits specialization itself. This fix works with +both the old version of libc++ and the new one. + +Fixes issue #1633. + +* Fix is_std_iterator_traits_specialized_v on MSVC + +It used to pretend that std::iterator_traits is a user-defined +specialization, which isn't the case. This is due to MSVC's +iterator_traits specialization not posing as the base template. +--- + include/std/detail/associated_types.hpp | 22 +++++++++++----- + test/CMakeLists.txt | 1 + + test/bug1633.cpp | 34 +++++++++++++++++++++++++ + 3 files changed, 51 insertions(+), 6 deletions(-) + create mode 100644 test/bug1633.cpp + +diff --git a/include/std/detail/associated_types.hpp b/include/std/detail/associated_types.hpp +index b642166d4..449a3f91c 100644 +--- a/include/std/detail/associated_types.hpp ++++ b/include/std/detail/associated_types.hpp +@@ -265,11 +265,22 @@ namespace ranges + template + char is_std_iterator_traits_specialized_impl_(void *); + #elif defined(_LIBCPP_VERSION) +- template +- char ( +- &is_std_iterator_traits_specialized_impl_(std::__iterator_traits *))[2]; ++ // In older versions of libc++, the base template inherits from std::__iterator_traits. ++ template class IteratorTraitsBase, typename I, bool B> ++ char (&libcpp_iterator_traits_base_impl(IteratorTraitsBase *))[2]; ++ template class IteratorTraitsBase, typename I> ++ char libcpp_iterator_traits_base_impl(void *); ++ ++ // In newer versions, the base template has only one template parameter and provides the ++ // __primary_template typedef which aliases the iterator_traits specialization. ++ template class, typename I> ++ char (&libcpp_iterator_traits_base_impl(typename std::iterator_traits::__primary_template *))[2]; ++ template class, typename I> ++ char libcpp_iterator_traits_base_impl(void *); ++ + template +- char is_std_iterator_traits_specialized_impl_(void *); ++ auto is_std_iterator_traits_specialized_impl_(std::iterator_traits* traits) ++ -> decltype(libcpp_iterator_traits_base_impl(traits)); + #elif defined(_MSVC_STL_VERSION) + template + char (&is_std_iterator_traits_specialized_impl_( +@@ -287,14 +298,13 @@ namespace ranges + RANGES_INLINE_VAR constexpr bool is_std_iterator_traits_specialized_v = + 1 == sizeof(is_std_iterator_traits_specialized_impl_( + static_cast *>(nullptr))); +- ++#endif + // The standard iterator_traits specialization(s) do not count + // as user-specialized. This will no longer be necessary in C++20. + // This helps with `T volatile*` and `void *`. + template + RANGES_INLINE_VAR constexpr bool is_std_iterator_traits_specialized_v = + false; +-#endif + } // namespace detail + /// \endcond + } // namespace ranges +diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt +index 889f314af..2c2b7c09c 100644 +--- a/test/CMakeLists.txt ++++ b/test/CMakeLists.txt +@@ -19,3 +19,4 @@ rv3_add_test(test.bug474 bug474 bug474.cpp) + rv3_add_test(test.bug566 bug566 bug566.cpp) + rv3_add_test(test.bug1322 bug1322 bug1322.cpp) + rv3_add_test(test.bug1335 bug1335 bug1335.cpp) ++rv3_add_test(test.bug1633 bug1633 bug1633.cpp) +diff --git a/test/bug1633.cpp b/test/bug1633.cpp +new file mode 100644 +index 000000000..be52420ad +--- /dev/null ++++ b/test/bug1633.cpp +@@ -0,0 +1,34 @@ ++// Range v3 library ++// ++// Use, modification and distribution is subject to the ++// Boost Software License, Version 1.0. (See accompanying ++// file LICENSE_1_0.txt or copy at ++// http://www.boost.org/LICENSE_1_0.txt) ++// ++// Project home: https://github.com/ericniebler/range-v3 ++ ++#include ++#include ++#include ++ ++struct X { }; ++ ++namespace std { ++ template<> struct iterator_traits { }; ++} ++ ++struct Y { ++ using difference_type = std::ptrdiff_t; ++ using value_type = int; ++ using pointer = int*; ++ using reference = int&; ++ using iterator_category = std::forward_iterator_tag; ++}; ++ ++static_assert(ranges::detail::is_std_iterator_traits_specialized_v, ""); ++static_assert(!ranges::detail::is_std_iterator_traits_specialized_v, ""); ++static_assert(!ranges::detail::is_std_iterator_traits_specialized_v, ""); ++ ++int main() ++{ ++}