View | Details | Raw Unified | Return to bug 260044
Collapse All | Expand All

(-)b/devel/range-v3/Makefile (+1 lines)
Lines 1-5 Link Here
1
PORTNAME=	range-v3
1
PORTNAME=	range-v3
2
DISTVERSION=	0.11.0
2
DISTVERSION=	0.11.0
3
PORTREVISION=	1
3
CATEGORIES=	devel
4
CATEGORIES=	devel
4
5
5
MAINTAINER=	henry.hu.sh@gmail.com
6
MAINTAINER=	henry.hu.sh@gmail.com
(-)b/devel/range-v3/files/patch-0487cca29e35 (+122 lines)
Added Link Here
1
From 0487cca29e352e8f16bbd91fda38e76e39a0ed28 Mon Sep 17 00:00:00 2001
2
From: Louis Dionne <ldionne.2@gmail.com>
3
Date: Tue, 15 Jun 2021 14:40:01 -0400
4
Subject: [PATCH] Work around broken integration with latest libc++. (#1635)
5
6
* Work around broken integration with latest libc++.
7
8
In newer versions of libc++, the base template of std::iterator_traits
9
provides a member typedef called __primary_template which is an alias
10
to the std::iterator_traits specialization itself. This fix works with
11
both the old version of libc++ and the new one.
12
13
Fixes issue #1633.
14
15
* Fix is_std_iterator_traits_specialized_v on MSVC
16
17
It used to pretend that std::iterator_traits<T*> is a user-defined
18
specialization, which isn't the case. This is due to MSVC's
19
iterator_traits<T*> specialization not posing as the base template.
20
---
21
 include/std/detail/associated_types.hpp | 22 +++++++++++-----
22
 test/CMakeLists.txt                     |  1 +
23
 test/bug1633.cpp                        | 34 +++++++++++++++++++++++++
24
 3 files changed, 51 insertions(+), 6 deletions(-)
25
 create mode 100644 test/bug1633.cpp
26
27
diff --git a/include/std/detail/associated_types.hpp b/include/std/detail/associated_types.hpp
28
index b642166d4..449a3f91c 100644
29
--- include/std/detail/associated_types.hpp
30
+++ include/std/detail/associated_types.hpp
31
@@ -265,11 +265,22 @@ namespace ranges
32
         template<typename I>
33
         char is_std_iterator_traits_specialized_impl_(void *);
34
 #elif defined(_LIBCPP_VERSION)
35
-        template<typename I, bool B>
36
-        char (
37
-            &is_std_iterator_traits_specialized_impl_(std::__iterator_traits<I, B> *))[2];
38
+        // In older versions of libc++, the base template inherits from std::__iterator_traits<typename, bool>.
39
+        template<template<typename, bool> class IteratorTraitsBase, typename I, bool B>
40
+        char (&libcpp_iterator_traits_base_impl(IteratorTraitsBase<I, B> *))[2];
41
+        template<template<typename, bool> class IteratorTraitsBase, typename I>
42
+        char libcpp_iterator_traits_base_impl(void *);
43
+
44
+        // In newer versions, the base template has only one template parameter and provides the
45
+        // __primary_template typedef which aliases the iterator_traits specialization.
46
+        template<template<typename> class, typename I>
47
+        char (&libcpp_iterator_traits_base_impl(typename std::iterator_traits<I>::__primary_template *))[2];
48
+        template<template<typename> class, typename I>
49
+        char libcpp_iterator_traits_base_impl(void *);
50
+
51
         template<typename I>
52
-        char is_std_iterator_traits_specialized_impl_(void *);
53
+        auto is_std_iterator_traits_specialized_impl_(std::iterator_traits<I>* traits)
54
+            -> decltype(libcpp_iterator_traits_base_impl<std::__iterator_traits, I>(traits));
55
 #elif defined(_MSVC_STL_VERSION)
56
         template<typename I>
57
         char (&is_std_iterator_traits_specialized_impl_(
58
@@ -287,14 +298,13 @@ namespace ranges
59
         RANGES_INLINE_VAR constexpr bool is_std_iterator_traits_specialized_v =
60
             1 == sizeof(is_std_iterator_traits_specialized_impl_<I>(
61
                      static_cast<std::iterator_traits<I> *>(nullptr)));
62
-
63
+#endif
64
         // The standard iterator_traits<T *> specialization(s) do not count
65
         // as user-specialized. This will no longer be necessary in C++20.
66
         // This helps with `T volatile*` and `void *`.
67
         template<typename T>
68
         RANGES_INLINE_VAR constexpr bool is_std_iterator_traits_specialized_v<T *> =
69
             false;
70
-#endif
71
     } // namespace detail
72
     /// \endcond
73
 } // namespace ranges
74
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
75
index 889f314af..2c2b7c09c 100644
76
--- test/CMakeLists.txt
77
+++ test/CMakeLists.txt
78
@@ -19,3 +19,4 @@ rv3_add_test(test.bug474 bug474 bug474.cpp)
79
 rv3_add_test(test.bug566 bug566 bug566.cpp)
80
 rv3_add_test(test.bug1322 bug1322 bug1322.cpp)
81
 rv3_add_test(test.bug1335 bug1335 bug1335.cpp)
82
+rv3_add_test(test.bug1633 bug1633 bug1633.cpp)
83
diff --git a/test/bug1633.cpp b/test/bug1633.cpp
84
new file mode 100644
85
index 000000000..be52420ad
86
--- /dev/null
87
+++ test/bug1633.cpp
88
@@ -0,0 +1,34 @@
89
+// Range v3 library
90
+//
91
+//  Use, modification and distribution is subject to the
92
+//  Boost Software License, Version 1.0. (See accompanying
93
+//  file LICENSE_1_0.txt or copy at
94
+//  http://www.boost.org/LICENSE_1_0.txt)
95
+//
96
+// Project home: https://github.com/ericniebler/range-v3
97
+
98
+#include <cstddef>
99
+#include <iterator>
100
+#include <range/v3/iterator.hpp>
101
+
102
+struct X { };
103
+
104
+namespace std {
105
+    template<> struct iterator_traits<X> { };
106
+}
107
+
108
+struct Y {
109
+    using difference_type = std::ptrdiff_t;
110
+    using value_type = int;
111
+    using pointer = int*;
112
+    using reference = int&;
113
+    using iterator_category = std::forward_iterator_tag;
114
+};
115
+
116
+static_assert(ranges::detail::is_std_iterator_traits_specialized_v<X>, "");
117
+static_assert(!ranges::detail::is_std_iterator_traits_specialized_v<Y>, "");
118
+static_assert(!ranges::detail::is_std_iterator_traits_specialized_v<int*>, "");
119
+
120
+int main()
121
+{
122
+}

Return to bug 260044