3
// ************************************************************************
5
// Kokkos: Manycore Performance-Portable Multidimensional Arrays
6
// Copyright (2012) Sandia Corporation
8
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9
// the U.S. Government retains certain rights in this software.
11
// Redistribution and use in source and binary forms, with or without
12
// modification, are permitted provided that the following conditions are
15
// 1. Redistributions of source code must retain the above copyright
16
// notice, this list of conditions and the following disclaimer.
18
// 2. Redistributions in binary form must reproduce the above copyright
19
// notice, this list of conditions and the following disclaimer in the
20
// documentation and/or other materials provided with the distribution.
22
// 3. Neither the name of the Corporation nor the names of the
23
// contributors may be used to endorse or promote products derived from
24
// this software without specific prior written permission.
26
// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
// Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
40
// ************************************************************************
44
#ifndef KOKKOSTRAITS_HPP
45
#define KOKKOSTRAITS_HPP
49
#include <Kokkos_Macros.hpp>
54
/* C++11 conformal compile-time type traits utilities.
55
* Prefer to use C++11 when portably available.
57
//----------------------------------------------------------------------------
60
template < class T , T v >
61
struct integral_constant
63
// Declaration of 'static const' causes an unresolved linker symbol in debug
64
// static const T value = v ;
65
enum { value = T(v) };
67
typedef integral_constant<T,v> type;
68
KOKKOS_INLINE_FUNCTION operator T() { return v ; }
71
typedef integral_constant<bool,false> false_type ;
72
typedef integral_constant<bool,true> true_type ;
74
//----------------------------------------------------------------------------
75
// C++11 Type relationships:
77
template< class X , class Y > struct is_same : public false_type {};
78
template< class X > struct is_same<X,X> : public true_type {};
80
//----------------------------------------------------------------------------
81
// C++11 Type properties:
83
template <typename T> struct is_const : public false_type {};
84
template <typename T> struct is_const<const T> : public true_type {};
85
template <typename T> struct is_const<const T & > : public true_type {};
87
template <typename T> struct is_array : public false_type {};
88
template <typename T> struct is_array< T[] > : public true_type {};
89
template <typename T, unsigned N > struct is_array< T[N] > : public true_type {};
91
//----------------------------------------------------------------------------
92
// C++11 Type transformations:
94
template <typename T> struct remove_const { typedef T type; };
95
template <typename T> struct remove_const<const T> { typedef T type; };
96
template <typename T> struct remove_const<const T & > { typedef T & type; };
98
template <typename T> struct add_const { typedef const T type; };
99
template <typename T> struct add_const<T & > { typedef const T & type; };
100
template <typename T> struct add_const<const T> { typedef const T type; };
101
template <typename T> struct add_const<const T & > { typedef const T & type; };
103
template <typename T> struct remove_reference { typedef T type ; };
104
template <typename T> struct remove_reference< T & > { typedef T type ; };
105
template <typename T> struct remove_reference< const T & > { typedef const T type ; };
107
template <typename T> struct remove_extent { typedef T type ; };
108
template <typename T> struct remove_extent<T[]> { typedef T type ; };
109
template <typename T, unsigned N > struct remove_extent<T[N]> { typedef T type ; };
111
//----------------------------------------------------------------------------
112
// C++11 Other type generators:
114
template< bool , class T , class F >
115
struct condition { typedef F type ; };
117
template< class T , class F >
118
struct condition<true,T,F> { typedef T type ; };
120
template< bool , class = void >
124
struct enable_if< true , T > { typedef T type ; };
126
//----------------------------------------------------------------------------
129
} // namespace Kokkos
131
//----------------------------------------------------------------------------
132
//----------------------------------------------------------------------------
138
//----------------------------------------------------------------------------
140
template< class , class T = void >
141
struct enable_if_type { typedef T type ; };
143
//----------------------------------------------------------------------------
146
struct bool_ : public integral_constant<bool,B> {};
148
template< unsigned I >
149
struct unsigned_ : public integral_constant<unsigned,I> {};
152
struct int_ : public integral_constant<int,I> {};
154
typedef bool_<true> true_;
155
typedef bool_<false> false_;
156
//----------------------------------------------------------------------------
159
template < bool Cond , typename TrueType , typename FalseType>
162
enum { value = Cond };
164
typedef FalseType type;
167
typedef typename remove_const<
168
typename remove_reference<type>::type >::type value_type ;
170
typedef typename add_const<value_type>::type const_value_type ;
172
static KOKKOS_INLINE_FUNCTION
173
const_value_type & select( const_value_type & v ) { return v ; }
175
static KOKKOS_INLINE_FUNCTION
176
value_type & select( value_type & v ) { return v ; }
179
static KOKKOS_INLINE_FUNCTION
180
value_type & select( const T & ) { value_type * ptr(0); return *ptr ; }
184
static KOKKOS_INLINE_FUNCTION
185
const_value_type & select( const T & , const_value_type & v ) { return v ; }
188
static KOKKOS_INLINE_FUNCTION
189
value_type & select( const T & , value_type & v ) { return v ; }
192
template <typename TrueType, typename FalseType>
193
struct if_c< true , TrueType , FalseType >
195
enum { value = true };
197
typedef TrueType type;
200
typedef typename remove_const<
201
typename remove_reference<type>::type >::type value_type ;
203
typedef typename add_const<value_type>::type const_value_type ;
205
static KOKKOS_INLINE_FUNCTION
206
const_value_type & select( const_value_type & v ) { return v ; }
208
static KOKKOS_INLINE_FUNCTION
209
value_type & select( value_type & v ) { return v ; }
212
static KOKKOS_INLINE_FUNCTION
213
value_type & select( const T & ) { value_type * ptr(0); return *ptr ; }
217
static KOKKOS_INLINE_FUNCTION
218
const_value_type & select( const_value_type & v , const F & ) { return v ; }
221
static KOKKOS_INLINE_FUNCTION
222
value_type & select( value_type & v , const F & ) { return v ; }
225
template< typename TrueType >
226
struct if_c< false , TrueType , void >
228
enum { value = false };
231
typedef void value_type ;
234
template< typename FalseType >
235
struct if_c< true , void , FalseType >
237
enum { value = true };
240
typedef void value_type ;
243
template <typename Cond, typename TrueType, typename FalseType>
244
struct if_ : public if_c<Cond::value, TrueType, FalseType> {};
246
//----------------------------------------------------------------------------
248
// Allows aliased types:
249
template< typename T >
250
struct is_integral : public integral_constant< bool ,
252
Impl::is_same< T , char >::value ||
253
Impl::is_same< T , unsigned char >::value ||
254
Impl::is_same< T , short int >::value ||
255
Impl::is_same< T , unsigned short int >::value ||
256
Impl::is_same< T , int >::value ||
257
Impl::is_same< T , unsigned int >::value ||
258
Impl::is_same< T , long int >::value ||
259
Impl::is_same< T , unsigned long int >::value ||
260
Impl::is_same< T , long long int >::value ||
261
Impl::is_same< T , unsigned long long int >::value ||
263
Impl::is_same< T , int8_t >::value ||
264
Impl::is_same< T , int16_t >::value ||
265
Impl::is_same< T , int32_t >::value ||
266
Impl::is_same< T , int64_t >::value ||
267
Impl::is_same< T , uint8_t >::value ||
268
Impl::is_same< T , uint16_t >::value ||
269
Impl::is_same< T , uint32_t >::value ||
270
Impl::is_same< T , uint64_t >::value
274
//----------------------------------------------------------------------------
277
template < size_t N >
278
struct is_power_of_two
280
enum type { value = (N > 0) && !(N & (N-1)) };
283
template < size_t N , bool OK = is_power_of_two<N>::value >
284
struct power_of_two ;
286
template < size_t N >
287
struct power_of_two<N,true>
289
enum type { value = 1+ power_of_two<(N>>1),true>::value };
293
struct power_of_two<2,true>
295
enum type { value = 1 };
299
struct power_of_two<1,true>
301
enum type { value = 0 };
304
/** \brief If power of two then return power,
305
* otherwise return ~0u.
307
static KOKKOS_FORCEINLINE_FUNCTION
308
unsigned power_of_two_if_valid( const unsigned N )
311
if ( N && ! ( N & ( N - 1 ) ) ) {
312
#if defined( __CUDA_ARCH__ )
314
#elif defined( __GNUC__ ) || defined( __GNUG__ )
315
p = __builtin_ffs(N) - 1 ;
316
#elif defined( __INTEL_COMPILER )
317
p = _bit_scan_forward(N);
320
for ( unsigned j = 1 ; ! ( N & j ) ; j <<= 1 ) { ++p ; }
326
//----------------------------------------------------------------------------
328
template< typename T , T v , bool NonZero = ( v != T(0) ) >
329
struct integral_nonzero_constant
331
// Declaration of 'static const' causes an unresolved linker symbol in debug
332
// static const T value = v ;
333
enum { value = T(v) };
334
typedef T value_type ;
335
typedef integral_nonzero_constant<T,v> type ;
336
KOKKOS_INLINE_FUNCTION integral_nonzero_constant( const T & ) {}
339
template< typename T , T zero >
340
struct integral_nonzero_constant<T,zero,false>
343
typedef T value_type ;
344
typedef integral_nonzero_constant<T,0> type ;
345
KOKKOS_INLINE_FUNCTION integral_nonzero_constant( const T & v ) : value(v) {}
348
//----------------------------------------------------------------------------
350
template < class C > struct is_integral_constant : public false_
352
typedef void integral_type ;
353
enum { integral_value = 0 };
356
template < typename T , T v >
357
struct is_integral_constant< integral_constant<T,v> > : public true_
359
typedef T integral_type ;
360
enum { integral_value = v };
364
} // namespace Kokkos
366
//----------------------------------------------------------------------------
367
//----------------------------------------------------------------------------
369
#endif /* #ifndef KOKKOSTRAITS_HPP */