Skip to content

Commit 878a2a0

Browse files
BeanavilNB4444
authored andcommitted
Ensure that {cr}begin works with types that pull in namespace std via ADL
1 parent de4aae2 commit 878a2a0

File tree

7 files changed

+126
-3
lines changed

7 files changed

+126
-3
lines changed

thrust/detail/config/cpp_compatibility.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@
4141
# define THRUST_NODISCARD
4242
#endif
4343

44+
// NVCC below 11.3 does not support nodiscard on friend operators
45+
// It always fails with clang
46+
#if (defined(__CUDACC__) && (__CUDACC_VER_MAJOR__ <= 11 && __CUDACC_VER_MINOR__ < 3)) || THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_CLANG
47+
# define THRUST_NODISCARD_FRIEND friend
48+
#else
49+
# define THRUST_NODISCARD_FRIEND THRUST_NODISCARD friend
50+
#endif
51+
52+
4453
#if THRUST_CPP_DIALECT >= 2017 && __cpp_if_constexpr
4554
# define THRUST_IF_CONSTEXPR if constexpr
4655
#else

thrust/detail/contiguous_storage.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <thrust/detail/execution_policy.h>
2121
#include <thrust/detail/allocator/allocator_traits.h>
2222
#include <thrust/detail/config.h>
23+
#include <thrust/sequence_access.h>
2324

2425
THRUST_NAMESPACE_BEGIN
2526

@@ -162,15 +163,15 @@ template<typename T, typename Alloc>
162163
THRUST_HOST_DEVICE
163164
void propagate_allocator(const contiguous_storage &other);
164165

165-
#if THRUST_CPP_DIALECT >= 2011
166166
THRUST_HOST_DEVICE
167167
void propagate_allocator(contiguous_storage &other);
168168

169169
// allow move assignment for a sane implementation of allocator propagation
170170
// on move assignment
171171
THRUST_HOST_DEVICE
172172
contiguous_storage &operator=(contiguous_storage &&other);
173-
#endif // THRUST_CPP_DIALECT >= 2011
173+
174+
THRUST_SYNTHESIZE_SEQUENCE_ACCESS(contiguous_storage, const_iterator);
174175

175176
private:
176177
// XXX we could inherit from this to take advantage of empty base class optimization

thrust/detail/range/head_flags.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <thrust/iterator/counting_iterator.h>
2323
#include <thrust/tuple.h>
2424
#include <thrust/functional.h>
25+
#include <thrust/sequence_access.h>
2526

2627

2728
THRUST_NAMESPACE_BEGIN
@@ -116,6 +117,8 @@ template<typename RandomAccessIterator,
116117
return *(begin() + i);
117118
}
118119

120+
THRUST_SYNTHESIZE_SEQUENCE_ACCESS(head_flags_with_init, iterator);
121+
119122
private:
120123
iterator m_begin, m_end;
121124
};

thrust/detail/range/tail_flags.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <thrust/iterator/counting_iterator.h>
2323
#include <thrust/tuple.h>
2424
#include <thrust/functional.h>
25+
#include <thrust/sequence_access.h>
2526

2627
THRUST_NAMESPACE_BEGIN
2728
namespace detail
@@ -105,6 +106,8 @@ template<typename RandomAccessIterator,
105106
return *(begin() + i);
106107
}
107108

109+
THRUST_SYNTHESIZE_SEQUENCE_ACCESS(tail_flags, iterator);
110+
108111
private:
109112
iterator m_begin, m_end;
110113
};

thrust/detail/trivial_sequence.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include <thrust/detail/type_traits.h>
3030
#include <thrust/detail/execution_policy.h>
3131
#include <thrust/detail/temporary_array.h>
32+
#include <thrust/sequence_access.h>
3233
#include <thrust/type_traits/is_contiguous_iterator.h>
3334

3435
THRUST_NAMESPACE_BEGIN
@@ -54,8 +55,18 @@ struct _trivial_sequence<Iterator, DerivedPolicy, thrust::detail::true_type>
5455
THRUST_HOST_DEVICE
5556
iterator_type begin() { return first; }
5657

58+
THRUST_HOST_DEVICE friend iterator_type begin(_trivial_sequence& sequence)
59+
{
60+
return sequence.first;
61+
}
62+
5763
THRUST_HOST_DEVICE
5864
iterator_type end() { return last; }
65+
66+
THRUST_HOST_DEVICE friend iterator_type end(_trivial_sequence& sequence)
67+
{
68+
return sequence.first;
69+
}
5970
};
6071

6172
// non-trivial case
@@ -64,7 +75,7 @@ struct _trivial_sequence<Iterator, DerivedPolicy, thrust::detail::false_type>
6475
{
6576
typedef typename thrust::iterator_value<Iterator>::type iterator_value;
6677
typedef typename thrust::detail::temporary_array<iterator_value, DerivedPolicy>::iterator iterator_type;
67-
78+
6879
thrust::detail::temporary_array<iterator_value, DerivedPolicy> buffer;
6980

7081
THRUST_HOST_DEVICE
@@ -76,8 +87,18 @@ struct _trivial_sequence<Iterator, DerivedPolicy, thrust::detail::false_type>
7687
THRUST_HOST_DEVICE
7788
iterator_type begin() { return buffer.begin(); }
7889

90+
THRUST_HOST_DEVICE friend iterator_type begin(_trivial_sequence& sequence)
91+
{
92+
return sequence.begin();
93+
}
94+
7995
THRUST_HOST_DEVICE
8096
iterator_type end() { return buffer.end(); }
97+
98+
THRUST_HOST_DEVICE friend iterator_type end(_trivial_sequence& sequence)
99+
{
100+
return sequence.end();
101+
}
81102
};
82103

83104
template <typename Iterator, typename DerivedPolicy>

thrust/detail/vector_base.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <thrust/detail/type_traits.h>
2929
#include <thrust/detail/config.h>
3030
#include <thrust/detail/contiguous_storage.h>
31+
#include <thrust/sequence_access.h>
3132

3233
#include <initializer_list>
3334
#include <vector>
@@ -488,6 +489,9 @@ template<typename T, typename Alloc>
488489
*/
489490
allocator_type get_allocator(void) const;
490491

492+
THRUST_SYNTHESIZE_SEQUENCE_ACCESS(vector_base, const_iterator);
493+
THRUST_SYNTHESIZE_SEQUENCE_REVERSE_ACCESS(vector_base, const_reverse_iterator);
494+
491495
protected:
492496
// Our storage
493497
storage_type m_storage;

thrust/sequence_access.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of libcu++, the C++ Standard Library for your entire system,
4+
// under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
// SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES.
8+
// SPDX-FileCopyrightText: Modifications Copyright (c) 2024 Advanced Micro Devices, Inc. All rights reserved.
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
#ifndef THRUST_SEQUENCE_ACCESS_H
13+
#define THRUST_SEQUENCE_ACCESS_H
14+
15+
#pragma once
16+
17+
#include <thrust/detail/config.h>
18+
19+
// We need to define hidden friends for {cr,r,}{begin,end} of our containers as we will otherwise encounter ambiguities
20+
#define THRUST_SYNTHESIZE_SEQUENCE_ACCESS(_ClassName, _ConstIter) \
21+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE iterator begin(_ClassName& __sequence) noexcept( \
22+
noexcept(__sequence.begin())) \
23+
{ \
24+
return __sequence.begin(); \
25+
} \
26+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE _ConstIter begin(const _ClassName& __sequence) noexcept( \
27+
noexcept(__sequence.begin())) \
28+
{ \
29+
return __sequence.begin(); \
30+
} \
31+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE iterator end(_ClassName& __sequence) noexcept(noexcept(__sequence.end())) \
32+
{ \
33+
return __sequence.end(); \
34+
} \
35+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE _ConstIter end(const _ClassName& __sequence) noexcept( \
36+
noexcept(__sequence.end())) \
37+
{ \
38+
return __sequence.end(); \
39+
} \
40+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE _ConstIter cbegin(const _ClassName& __sequence) noexcept( \
41+
noexcept(__sequence.begin())) \
42+
{ \
43+
return __sequence.begin(); \
44+
} \
45+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE _ConstIter cend(const _ClassName& __sequence) noexcept( \
46+
noexcept(__sequence.end())) \
47+
{ \
48+
return __sequence.end(); \
49+
}
50+
#define THRUST_SYNTHESIZE_SEQUENCE_REVERSE_ACCESS(_ClassName, _ConstRevIter) \
51+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE reverse_iterator rbegin(_ClassName& __sequence) noexcept( \
52+
noexcept(__sequence.rbegin())) \
53+
{ \
54+
return __sequence.rbegin(); \
55+
} \
56+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE _ConstRevIter rbegin(const _ClassName& __sequence) noexcept( \
57+
noexcept(__sequence.rbegin())) \
58+
{ \
59+
return __sequence.rbegin(); \
60+
} \
61+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE reverse_iterator rend(_ClassName& __sequence) noexcept( \
62+
noexcept(__sequence.rend())) \
63+
{ \
64+
return __sequence.rend(); \
65+
} \
66+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE _ConstRevIter rend(const _ClassName& __sequence) noexcept( \
67+
noexcept(__sequence.rend())) \
68+
{ \
69+
return __sequence.rend(); \
70+
} \
71+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE _ConstRevIter crbegin(const _ClassName& __sequence) noexcept( \
72+
noexcept(__sequence.rbegin())) \
73+
{ \
74+
return __sequence.rbegin(); \
75+
} \
76+
THRUST_NODISCARD_FRIEND THRUST_HOST_DEVICE _ConstRevIter crend(const _ClassName& __sequence) noexcept( \
77+
noexcept(__sequence.rend())) \
78+
{ \
79+
return __sequence.rend(); \
80+
}
81+
82+
#endif // THRUST_SEQUENCE_ACCESS_H

0 commit comments

Comments
 (0)