@@ -63,6 +63,80 @@ namespace thrust
6363 * \{
6464 */
6565
66+ namespace detail
67+ {
68+
69+ template <typename T, std::size_t Align>
70+ struct complex_storage ;
71+
72+ #if __cplusplus >= 201103L \
73+ && (THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_GCC) \
74+ && (THRUST_GCC_VERSION >= 40800 )
75+ // C++11 implementation, excluding GCC 4.7, which doesn't have `alignas`.
76+ template <typename T, std::size_t Align>
77+ struct complex_storage
78+ {
79+ struct alignas (Align) type { T x; T y; };
80+ };
81+ #elif (THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_MSVC) \
82+ || ( (THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_GCC) \
83+ && (THRUST_GCC_VERSION < 40300 ))
84+ // C++03 implementation for MSVC and GCC <= 4.2.
85+ //
86+ // We have to implement `aligned_type` with specializations for MSVC
87+ // and GCC 4.2 and older because they require literals as arguments to
88+ // their alignment attribute.
89+
90+ #if (THRUST_HOST_COMPILER == THRUST_HOST_COMPILER_MSVC)
91+ // MSVC implementation.
92+ #define THRUST_DEFINE_COMPLEX_STORAGE_SPECIALIZATION (X ) \
93+ template <typename T> \
94+ struct complex_storage <T, X> \
95+ { \
96+ __declspec (align(X)) struct type { T x; T y; }; \
97+ }; \
98+ /* */
99+ #else
100+ // GCC <= 4.2 implementation.
101+ #define THRUST_DEFINE_COMPLEX_STORAGE_SPECIALIZATION (X ) \
102+ template <typename T> \
103+ struct complex_storage <T, X> \
104+ { \
105+ struct type { T x; T y; } __attribute__((aligned(X))); \
106+ }; \
107+ /* */
108+ #endif
109+
110+ // The primary template is a fallback, which doesn't specify any alignment.
111+ // It's only used when T is very large and we're using an older compilers
112+ // which we have to fully specialize each alignment case.
113+ template <typename T, std::size_t Align>
114+ struct complex_storage
115+ {
116+ T x; T y;
117+ };
118+
119+ THRUST_DEFINE_COMPLEX_STORAGE_SPECIALIZATION (1 );
120+ THRUST_DEFINE_COMPLEX_STORAGE_SPECIALIZATION (2 );
121+ THRUST_DEFINE_COMPLEX_STORAGE_SPECIALIZATION (4 );
122+ THRUST_DEFINE_COMPLEX_STORAGE_SPECIALIZATION (8 );
123+ THRUST_DEFINE_COMPLEX_STORAGE_SPECIALIZATION (16 );
124+ THRUST_DEFINE_COMPLEX_STORAGE_SPECIALIZATION (32 );
125+ THRUST_DEFINE_COMPLEX_STORAGE_SPECIALIZATION (64 );
126+ THRUST_DEFINE_COMPLEX_STORAGE_SPECIALIZATION (128 );
127+
128+ #undef THRUST_DEFINE_COMPLEX_STORAGE_SPECIALIZATION
129+ #else
130+ // C++03 implementation for GCC > 4.2, Clang, PGI, ICPC, and xlC.
131+ template <typename T, std::size_t Align>
132+ struct complex_storage
133+ {
134+ struct type { T x; T y; } __attribute__((aligned(Align)));
135+ };
136+ #endif
137+
138+ } // end namespace detail
139+
66140 /* ! \p complex is the Thrust equivalent to <tt>std::complex</tt>. It is
67141 * functionally identical to it, but can also be used in device code which
68142 * <tt>std::complex</tt> currently cannot.
@@ -377,31 +451,7 @@ struct complex
377451 operator std::complex <T>() const { return std::complex <T>(real (), imag ()); }
378452
379453private:
380- /* ! \cond
381- */
382- struct generic_storage_type { T x; T y; };
383- /* ! \endcond
384- */
385-
386- #if THRUST_DEVICE_COMPILER == THRUST_DEVICE_COMPILER_NVCC
387- typedef typename detail::conditional<
388- detail::is_same<T, float >::value, float2,
389- typename detail::conditional<
390- detail::is_same<T, float const >::value, float2 const ,
391- typename detail::conditional<
392- detail::is_same<T, double >::value, double2,
393- typename detail::conditional<
394- detail::is_same<T, double const >::value, double2 const ,
395- generic_storage_type
396- >::type
397- >::type
398- >::type
399- >::type storage_type;
400- #else
401- typedef generic_storage_type storage_type;
402- #endif
403-
404- storage_type data;
454+ typename detail::complex_storage<T, sizeof (T) * 2 >::type data;
405455};
406456
407457
0 commit comments