Skip to content

Commit a1e1585

Browse files
committed
Fix __segmented_iterator_traits for implicit template instantiation
1 parent 7d05c23 commit a1e1585

File tree

3 files changed

+61
-13
lines changed

3 files changed

+61
-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: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
#include <__type_traits/integral_constant.h>
26+
27+
#include "test_iterators.h"
28+
#include "test_macros.h"
29+
30+
template <class Iter>
31+
struct is_segmented_random_access_iterator
32+
: std::_BoolConstant<std::__is_segmented_iterator<Iter>::value &&
33+
std::__has_random_access_iterator_category<
34+
typename std::__segmented_iterator_traits<Iter>::__local_iterator>::value> {};
35+
36+
int main(int, char**) {
37+
static_assert(is_segmented_random_access_iterator<std::deque<int>::iterator>::value, "");
38+
static_assert(!is_segmented_random_access_iterator<std::vector<int>::iterator>::value, "");
39+
static_assert(!is_segmented_random_access_iterator<std::list<int>::iterator>::value, "");
40+
static_assert(!is_segmented_random_access_iterator<std::array<int, 0>::iterator>::value, "");
41+
static_assert(!is_segmented_random_access_iterator<cpp17_input_iterator<int*> >::value, "");
42+
static_assert(!is_segmented_random_access_iterator<forward_iterator<int*> >::value, "");
43+
static_assert(!is_segmented_random_access_iterator<random_access_iterator<int*> >::value, "");
44+
static_assert(!is_segmented_random_access_iterator<int*>::value, "");
45+
46+
#if TEST_STD_VER >= 20
47+
using join_view_iterator = decltype((std::declval<std::vector<std::vector<int > >&>() | std::views::join).begin());
48+
static_assert(is_segmented_random_access_iterator<join_view_iterator>::value, "");
49+
#endif
50+
51+
return 0;
52+
}

0 commit comments

Comments
 (0)