Skip to content

Commit 70e6031

Browse files
committed
Improve the compatibility of is_trivially_relocatable.
Bug 2586774
1 parent d95d2e0 commit 70e6031

1 file changed

Lines changed: 41 additions & 11 deletions

File tree

thrust/type_traits/is_trivially_relocatable.h

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,27 +134,57 @@ struct proclaim_trivially_relocatable : false_type {};
134134
namespace detail
135135
{
136136

137+
// There is no way to actually detect the libstdc++ version; __GLIBCXX__
138+
// is always set to the date of libstdc++ being packaged, not the release
139+
// day or version. This means that we can't detect the libstdc++ version,
140+
// except when compiling with GCC.
141+
//
142+
// Therefore, for the best approximation of is_trivially_copyable, we need to
143+
// handle three distinct cases:
144+
// 1) GCC above 5, or another C++11 compiler not using libstdc++: use the
145+
// standard trait directly.
146+
// 2) A C++11 compiler using libstdc++ that provides the intrinsic: use the
147+
// intrinsic.
148+
// 3) Any other case (essentially: compiling without C++11): has_trivial_assign.
149+
150+
#ifndef __has_feature
151+
#define __has_feature(x) 0
152+
#endif
153+
154+
template <typename T>
155+
struct is_trivially_copyable_impl
156+
: integral_constant<
157+
bool,
158+
#if THRUST_CPP_DIALECT >= 2011
159+
#if defined(__GLIBCXX__) && __has_feature(is_trivially_copyable)
160+
__is_trivially_copyable(T)
161+
#elif THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_GCC && THRUST_GCC_VERSION >= 50000
162+
std::is_trivially_copyable<T>::value
163+
#else
164+
has_trivial_assign<T>::value
165+
#endif
166+
#else
167+
has_trivial_assign<T>::value
168+
#endif
169+
>
170+
{
171+
};
172+
137173
// https://wg21.link/P1144R0#wording-inheritance
138174
template <typename T>
139175
struct is_trivially_relocatable_impl
140-
: integral_constant<
141-
bool
142-
#if THRUST_CPP_DIALECT >= 2011 \
143-
&& ( (THRUST_HOST_COMPILER != THRUST_HOST_COMPILER_GCC) \
144-
|| (THRUST_GCC_VERSION >= 50000))
145-
, std::is_trivially_copyable<T>::value
146-
#else
147-
, has_trivial_assign<T>::value
148-
#endif
149-
|| proclaim_trivially_relocatable<T>::value
176+
: integral_constant<
177+
bool,
178+
is_trivially_copyable_impl<T>::value
179+
|| proclaim_trivially_relocatable<T>::value
150180
>
151181
{};
152182

153183
template <typename T, std::size_t N>
154184
struct is_trivially_relocatable_impl<T[N]> : is_trivially_relocatable_impl<T> {};
155185

156186
} // namespace detail
157-
187+
158188
THRUST_END_NS
159189

160190
#if THRUST_DEVICE_SYSTEM == THRUST_DEVICE_SYSTEM_CUDA

0 commit comments

Comments
 (0)