Skip to content

Commit a5e9953

Browse files
committed
Fix __segmented_iterator_traits for implicit template instantiation
1 parent b8b752d commit a5e9953

File tree

3 files changed

+60
-13
lines changed

3 files changed

+60
-13
lines changed

libcxx/include/__iterator/segmented_iterator.h

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,28 +51,22 @@
5151
_LIBCPP_BEGIN_NAMESPACE_STD
5252

5353
template <class _Iterator>
54-
struct __segmented_iterator_traits;
55-
/* exposition-only:
56-
{
57-
using __segment_iterator = ...;
58-
using __local_iterator = ...;
54+
struct __segmented_iterator_traits {
55+
using __is_segmented_iterator _LIBCPP_NODEBUG = false_type;
56+
using __segment_iterator _LIBCPP_NODEBUG = void;
57+
using __local_iterator _LIBCPP_NODEBUG = void;
5958

59+
/* exposition-only:
6060
static __segment_iterator __segment(_Iterator);
6161
static __local_iterator __local(_Iterator);
6262
static __local_iterator __begin(__segment_iterator);
6363
static __local_iterator __end(__segment_iterator);
6464
static _Iterator __compose(__segment_iterator, __local_iterator);
65+
*/
6566
};
66-
*/
67-
68-
template <class _Tp, size_t = 0>
69-
struct __has_specialization : false_type {};
70-
71-
template <class _Tp>
72-
struct __has_specialization<_Tp, sizeof(_Tp) * 0> : true_type {};
7367

7468
template <class _Iterator>
75-
using __is_segmented_iterator _LIBCPP_NODEBUG = __has_specialization<__segmented_iterator_traits<_Iterator> >;
69+
struct __is_segmented_iterator : __segmented_iterator_traits<_Iterator>::__is_segmented_iterator {};
7670

7771
_LIBCPP_END_NAMESPACE_STD
7872

libcxx/include/__ranges/join_view.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <__ranges/range_adaptor.h>
3232
#include <__ranges/view_interface.h>
3333
#include <__type_traits/common_type.h>
34+
#include <__type_traits/integral_constant.h>
3435
#include <__type_traits/maybe_const.h>
3536
#include <__utility/as_lvalue.h>
3637
#include <__utility/empty.h>
@@ -378,6 +379,7 @@ template <class _JoinViewIterator>
378379
__has_random_access_iterator_category<typename _JoinViewIterator::_Outer>::value &&
379380
__has_random_access_iterator_category<typename _JoinViewIterator::_Inner>::value)
380381
struct __segmented_iterator_traits<_JoinViewIterator> {
382+
using __is_segmented_iterator _LIBCPP_NODEBUG = true_type;
381383
using __segment_iterator _LIBCPP_NODEBUG =
382384
__iterator_with_data<typename _JoinViewIterator::_Outer, typename _JoinViewIterator::_Parent*>;
383385
using __local_iterator _LIBCPP_NODEBUG = typename _JoinViewIterator::_Inner;
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
10+
// <iterator>
11+
12+
// __segmented_iterator_traits<_Iter>
13+
14+
// verifies that __segmented_iterator_traits<_Iter> does not result in implicit
15+
// template instantaition, which may cause hard errors in SFINAE.
16+
17+
// XFAIL: FROZEN-CXX03-HEADERS-FIXME
18+
19+
#include <array>
20+
#include <deque>
21+
#include <list>
22+
#include <ranges>
23+
#include <vector>
24+
#include <__iterator/segmented_iterator.h>
25+
26+
#include "test_iterators.h"
27+
#include "test_macros.h"
28+
29+
template <class Iter>
30+
struct is_segmented_random_access_iterator
31+
: std::bool_constant<std::__is_segmented_iterator<Iter>::value &&
32+
std::__has_random_access_iterator_category<
33+
typename std::__segmented_iterator_traits<Iter>::__local_iterator>::value> {};
34+
35+
int main(int, char**) {
36+
static_assert(is_segmented_random_access_iterator<std::deque<int>::iterator>::value, "");
37+
static_assert(!is_segmented_random_access_iterator<std::vector<int>::iterator>::value, "");
38+
static_assert(!is_segmented_random_access_iterator<std::list<int>::iterator>::value, "");
39+
static_assert(!is_segmented_random_access_iterator<std::array<int, 0>::iterator>::value, "");
40+
static_assert(!is_segmented_random_access_iterator<cpp17_input_iterator<int*>>::value, "");
41+
static_assert(!is_segmented_random_access_iterator<forward_iterator<int*>>::value, "");
42+
static_assert(!is_segmented_random_access_iterator<random_access_iterator<int*>>::value, "");
43+
static_assert(!is_segmented_random_access_iterator<int*>::value, "");
44+
45+
#if TEST_STD_VER >= 20
46+
using join_view_iterator = decltype((std::declval<std::vector<std::vector<int > >&>() | std::views::join).begin());
47+
static_assert(is_segmented_random_access_iterator<join_view_iterator>::value, "");
48+
#endif
49+
50+
return 0;
51+
}

0 commit comments

Comments
 (0)