~ubuntu-branches/debian/sid/lammps/sid

« back to all changes in this revision

Viewing changes to lib/kokkos/core/src/impl/Kokkos_FunctorAdapter.hpp

  • Committer: Package Import Robot
  • Author(s): Anton Gladky
  • Date: 2015-04-29 23:44:49 UTC
  • mfrom: (5.1.3 experimental)
  • Revision ID: package-import@ubuntu.com-20150429234449-mbhy9utku6hp6oq8
Tags: 0~20150313.gitfa668e1-1
Upload into unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
//@HEADER
 
3
// ************************************************************************
 
4
//
 
5
//   Kokkos: Manycore Performance-Portable Multidimensional Arrays
 
6
//              Copyright (2012) Sandia Corporation
 
7
//
 
8
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
 
9
// the U.S. Government retains certain rights in this software.
 
10
//
 
11
// Redistribution and use in source and binary forms, with or without
 
12
// modification, are permitted provided that the following conditions are
 
13
// met:
 
14
//
 
15
// 1. Redistributions of source code must retain the above copyright
 
16
// notice, this list of conditions and the following disclaimer.
 
17
//
 
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.
 
21
//
 
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.
 
25
//
 
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.
 
37
//
 
38
// Questions? Contact  H. Carter Edwards (hcedwar@sandia.gov)
 
39
//
 
40
// ************************************************************************
 
41
//@HEADER
 
42
*/
 
43
 
 
44
#ifndef KOKKOS_FUNCTORADAPTER_HPP
 
45
#define KOKKOS_FUNCTORADAPTER_HPP
 
46
 
 
47
#include <cstddef>
 
48
#include <Kokkos_Core_fwd.hpp>
 
49
#include <impl/Kokkos_Traits.hpp>
 
50
#include <impl/Kokkos_Tags.hpp>
 
51
 
 
52
//----------------------------------------------------------------------------
 
53
//----------------------------------------------------------------------------
 
54
 
 
55
namespace Kokkos {
 
56
namespace Impl {
 
57
 
 
58
template< class FunctorType , class ArgTag , class Enable = void >
 
59
struct FunctorDeclaresValueType : public Impl::false_type {};
 
60
 
 
61
template< class FunctorType , class ArgTag >
 
62
struct FunctorDeclaresValueType< FunctorType , ArgTag
 
63
                               , typename Impl::enable_if_type< typename FunctorType::value_type >::type >
 
64
  : public Impl::true_type {};
 
65
 
 
66
 
 
67
/** \brief  Query Functor and execution policy argument tag for value type.
 
68
 *
 
69
 *  If C++11 enabled and 'value_type' is not explicitly declared then attempt
 
70
 *  to deduce the type from FunctorType::operator().
 
71
 */
 
72
template< class FunctorType , class ArgTag , bool Dec = FunctorDeclaresValueType<FunctorType,ArgTag>::value >
 
73
struct FunctorValueTraits
 
74
{
 
75
  typedef void value_type ;
 
76
  typedef void pointer_type ;
 
77
  typedef void reference_type ;
 
78
 
 
79
  enum { StaticValueSize = 0 };
 
80
 
 
81
  KOKKOS_FORCEINLINE_FUNCTION static
 
82
  unsigned value_count( const FunctorType & ) { return 0 ; }
 
83
 
 
84
  KOKKOS_FORCEINLINE_FUNCTION static
 
85
  unsigned value_size( const FunctorType & ) { return 0 ; }
 
86
};
 
87
 
 
88
/** \brief  FunctorType::value_type is explicitly declared so use it.
 
89
 *
 
90
 * Two options for declaration
 
91
 *
 
92
 *   1) A plain-old-data (POD) type
 
93
 *        typedef {pod_type} value_type ;
 
94
 *
 
95
 *   2) An array of POD of a runtime specified count.
 
96
 *        typedef {pod_type} value_type[] ;
 
97
 *        const unsigned     value_count ;
 
98
 */
 
99
template< class FunctorType , class ArgTag >
 
100
struct FunctorValueTraits< FunctorType , ArgTag , true /* exists FunctorType::value_type */ >
 
101
{
 
102
  typedef typename Impl::remove_extent< typename FunctorType::value_type >::type  value_type ;
 
103
 
 
104
  // If not an array then what is the sizeof(value_type)
 
105
  enum { StaticValueSize = Impl::is_array< typename FunctorType::value_type >::value ? 0 : sizeof(value_type) };
 
106
 
 
107
  typedef value_type                 * pointer_type ;
 
108
 
 
109
  // The reference_type for an array is 'value_type *'
 
110
  // The reference_type for a single value is 'value_type &'
 
111
 
 
112
  typedef typename Impl::if_c< ! StaticValueSize , value_type *
 
113
                                                 , value_type & >::type  reference_type ;
 
114
 
 
115
  // Number of values if single value
 
116
  template< class F >
 
117
  KOKKOS_FORCEINLINE_FUNCTION static
 
118
  typename Impl::enable_if< Impl::is_same<F,FunctorType>::value && StaticValueSize , unsigned >::type
 
119
    value_count( const F & ) { return 1 ; }
 
120
 
 
121
  // Number of values if an array, protect via templating because 'f.value_count'
 
122
  // will only exist when the functor declares the value_type to be an array.
 
123
  template< class F >
 
124
  KOKKOS_FORCEINLINE_FUNCTION static
 
125
  typename Impl::enable_if< Impl::is_same<F,FunctorType>::value && ! StaticValueSize , unsigned >::type
 
126
    value_count( const F & f ) { return f.value_count ; }
 
127
 
 
128
  // Total size of the value
 
129
  KOKKOS_INLINE_FUNCTION static
 
130
  unsigned value_size( const FunctorType & f ) { return value_count( f ) * sizeof(value_type) ; }
 
131
};
 
132
 
 
133
 
 
134
#if defined( KOKKOS_HAVE_CXX11 )
 
135
 
 
136
// If have C++11 and functor does not explicitly specify a value type
 
137
// then try to deduce the value type from FunctorType::operator().
 
138
// Can only deduce single value type since array length cannot be deduced.
 
139
template< class FunctorType >
 
140
struct FunctorValueTraits< FunctorType
 
141
                       , void  /* == ArgTag */
 
142
                       , false /* == exists FunctorType::value_type */
 
143
                       >
 
144
{
 
145
private:
 
146
 
 
147
  struct VOID {};
 
148
 
 
149
  // parallel_for operator without a tag:
 
150
  template< class ArgMember >
 
151
  KOKKOS_INLINE_FUNCTION
 
152
  static VOID deduce( void (FunctorType::*)( ArgMember ) const ) {}
 
153
 
 
154
  // parallel_reduce operator without a tag:
 
155
  template< class ArgMember , class T >
 
156
  KOKKOS_INLINE_FUNCTION
 
157
  static T deduce( void (FunctorType::*)( ArgMember , T & ) const ) {}
 
158
 
 
159
  // parallel_scan operator without a tag:
 
160
  template< class ArgMember , class T >
 
161
  KOKKOS_INLINE_FUNCTION
 
162
  static T deduce( void (FunctorType::*)( ArgMember , T & , bool ) const ) {}
 
163
 
 
164
  typedef decltype( deduce( & FunctorType::operator() ) ) ValueType ;
 
165
 
 
166
  enum { IS_VOID = Impl::is_same<VOID,ValueType>::value };
 
167
 
 
168
public:
 
169
 
 
170
  typedef typename Impl::if_c< IS_VOID , void , ValueType   >::type  value_type ;
 
171
  typedef typename Impl::if_c< IS_VOID , void , ValueType * >::type  pointer_type ;
 
172
  typedef typename Impl::if_c< IS_VOID , void , ValueType & >::type  reference_type ;
 
173
 
 
174
  enum { StaticValueSize = IS_VOID ? 0 : sizeof(ValueType) };
 
175
 
 
176
  KOKKOS_FORCEINLINE_FUNCTION static
 
177
  unsigned value_size( const FunctorType & ) { return StaticValueSize ; }
 
178
 
 
179
  KOKKOS_FORCEINLINE_FUNCTION static
 
180
  unsigned value_count( const FunctorType & ) { return IS_VOID ? 0 : 1 ; }
 
181
};
 
182
 
 
183
 
 
184
template< class FunctorType , class ArgTag >
 
185
struct FunctorValueTraits< FunctorType
 
186
                       , ArgTag /* != void */
 
187
                       , false  /* == exists FunctorType::value_type */
 
188
                       >
 
189
{
 
190
private:
 
191
 
 
192
  //----------------------------------------
 
193
  // parallel_for operator with a tag:
 
194
 
 
195
  struct VOID {}; // to allow valid sizeof(ValueType)
 
196
 
 
197
  template< class ArgMember >
 
198
  KOKKOS_INLINE_FUNCTION
 
199
  static VOID deduce( void (FunctorType::*)( ArgTag , ArgMember ) const ) {}
 
200
 
 
201
  template< class ArgMember >
 
202
  KOKKOS_INLINE_FUNCTION
 
203
  static VOID deduce( void (FunctorType::*)( const ArgTag & , ArgMember ) const ) {}
 
204
 
 
205
  //----------------------------------------
 
206
  // parallel_reduce operator with a tag:
 
207
 
 
208
  template< class ArgMember , class T >
 
209
  KOKKOS_INLINE_FUNCTION
 
210
  static T deduce( void (FunctorType::*)( ArgTag , ArgMember , T & ) const ) {}
 
211
 
 
212
  template< class ArgMember , class T >
 
213
  KOKKOS_INLINE_FUNCTION
 
214
  static T deduce( void (FunctorType::*)( const ArgTag & , ArgMember , T & ) const ) {}
 
215
 
 
216
  //----------------------------------------
 
217
  // parallel_scan operator with a tag:
 
218
 
 
219
  template< class ArgMember , class T >
 
220
  KOKKOS_INLINE_FUNCTION
 
221
  static T deduce( void (FunctorType::*)( ArgTag , ArgMember , T & , bool ) const ) {}
 
222
 
 
223
  template< class ArgMember , class T >
 
224
  KOKKOS_INLINE_FUNCTION
 
225
  static T deduce( void (FunctorType::*)( const ArgTag & , ArgMember , T & , bool ) const ) {}
 
226
 
 
227
  //----------------------------------------
 
228
 
 
229
  typedef decltype( deduce( & FunctorType::operator() ) ) ValueType ;
 
230
 
 
231
  enum { IS_VOID = Impl::is_same<VOID,ValueType>::value };
 
232
 
 
233
public:
 
234
 
 
235
  typedef typename Impl::if_c< IS_VOID , void , ValueType   >::type  value_type ;
 
236
  typedef typename Impl::if_c< IS_VOID , void , ValueType * >::type  pointer_type ;
 
237
  typedef typename Impl::if_c< IS_VOID , void , ValueType & >::type  reference_type ;
 
238
 
 
239
  enum { StaticValueSize = IS_VOID ? 0 : sizeof(ValueType) };
 
240
 
 
241
  KOKKOS_FORCEINLINE_FUNCTION static
 
242
  unsigned value_size( const FunctorType & ) { return StaticValueSize ; }
 
243
 
 
244
  KOKKOS_FORCEINLINE_FUNCTION static
 
245
  unsigned value_count( const FunctorType & ) { return IS_VOID ? 0 : 1 ; }
 
246
};
 
247
 
 
248
#endif /* #if defined( KOKKOS_HAVE_CXX11 ) */
 
249
 
 
250
} // namespace Impl
 
251
} // namespace Kokkos
 
252
 
 
253
//----------------------------------------------------------------------------
 
254
//----------------------------------------------------------------------------
 
255
 
 
256
namespace Kokkos {
 
257
namespace Impl {
 
258
 
 
259
// Function signatures for FunctorType::init function with a tag and not an array
 
260
template< class FunctorType , class ArgTag , bool IsArray = 0 == FunctorValueTraits<FunctorType,ArgTag>::StaticValueSize >
 
261
struct FunctorValueInitFunction {
 
262
 
 
263
  typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
 
264
 
 
265
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type & ) const );
 
266
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type & ) const );
 
267
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type & ) );
 
268
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type & ) );
 
269
 
 
270
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type volatile & ) const );
 
271
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile & ) const );
 
272
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type volatile & ) );
 
273
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type volatile & ) );
 
274
};
 
275
 
 
276
// Function signatures for FunctorType::init function with a tag and is an array
 
277
template< class FunctorType , class ArgTag >
 
278
struct FunctorValueInitFunction< FunctorType , ArgTag , true > {
 
279
 
 
280
  typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
 
281
 
 
282
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type * ) const );
 
283
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type * ) const );
 
284
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type * ) );
 
285
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type * ) );
 
286
 
 
287
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type volatile * ) const );
 
288
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile * ) const );
 
289
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type volatile * ) );
 
290
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type volatile * ) );
 
291
};
 
292
 
 
293
// Function signatures for FunctorType::init function without a tag and not an array
 
294
template< class FunctorType >
 
295
struct FunctorValueInitFunction< FunctorType , void , false > {
 
296
 
 
297
  typedef typename FunctorValueTraits<FunctorType,void>::reference_type value_type ;
 
298
 
 
299
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type & ) const );
 
300
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( value_type & ) );
 
301
 
 
302
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type volatile & ) const );
 
303
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( value_type volatile & ) );
 
304
};
 
305
 
 
306
// Function signatures for FunctorType::init function without a tag and is an array
 
307
template< class FunctorType >
 
308
struct FunctorValueInitFunction< FunctorType , void , true > {
 
309
 
 
310
  typedef typename FunctorValueTraits<FunctorType,void>::reference_type value_type ;
 
311
 
 
312
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type * ) const );
 
313
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( value_type * ) );
 
314
 
 
315
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type volatile * ) const );
 
316
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( value_type volatile * ) );
 
317
};
 
318
 
 
319
// Adapter for value initialization function.
 
320
// If a proper FunctorType::init is declared then use it,
 
321
// otherwise use default constructor.
 
322
template< class FunctorType , class ArgTag
 
323
        , class T = typename FunctorValueTraits<FunctorType,ArgTag>::reference_type
 
324
        , class Enable = void >
 
325
struct FunctorValueInit ;
 
326
 
 
327
/* No 'init' function provided for single value */
 
328
template< class FunctorType , class ArgTag , class T , class Enable >
 
329
struct FunctorValueInit< FunctorType , ArgTag , T & , Enable >
 
330
{
 
331
  KOKKOS_FORCEINLINE_FUNCTION static
 
332
  T & init( const FunctorType & f , void * p )
 
333
    { return *( new(p) T() ); };
 
334
};
 
335
 
 
336
/* No 'init' function provided for array value */
 
337
template< class FunctorType , class ArgTag , class T , class Enable >
 
338
struct FunctorValueInit< FunctorType , ArgTag , T * , Enable >
 
339
{
 
340
  KOKKOS_FORCEINLINE_FUNCTION static
 
341
  T * init( const FunctorType & f , void * p )
 
342
    {
 
343
      const int n = FunctorValueTraits< FunctorType , ArgTag >::value_count(f);
 
344
      for ( int i = 0 ; i < n ; ++i ) { new( ((T*)p) + i ) T(); }
 
345
      return (T*)p ;
 
346
    }
 
347
};
 
348
 
 
349
/* 'init' function provided for single value */
 
350
template< class FunctorType , class ArgTag , class T >
 
351
struct FunctorValueInit
 
352
  < FunctorType
 
353
  , ArgTag
 
354
  , T &
 
355
    // First  substitution failure when FunctorType::init does not exist.
 
356
#if defined( KOKKOS_HAVE_CXX11 )
 
357
    // Second substitution failure when FunctorType::init is not compatible.
 
358
  , decltype( FunctorValueInitFunction< FunctorType , ArgTag >::enable_if( & FunctorType::init ) )
 
359
#else
 
360
  , typename Impl::enable_if< 0 < sizeof( & FunctorType::init ) >::type
 
361
#endif
 
362
  >
 
363
{
 
364
  KOKKOS_FORCEINLINE_FUNCTION static
 
365
  T & init( const FunctorType & f , void * p )
 
366
    { f.init( *((T*)p) ); return *((T*)p) ; }
 
367
};
 
368
 
 
369
/* 'init' function provided for array value */
 
370
template< class FunctorType , class ArgTag , class T >
 
371
struct FunctorValueInit
 
372
  < FunctorType
 
373
  , ArgTag
 
374
  , T *
 
375
    // First  substitution failure when FunctorType::init does not exist.
 
376
#if defined( KOKKOS_HAVE_CXX11 )
 
377
    // Second substitution failure when FunctorType::init is not compatible
 
378
  , decltype( FunctorValueInitFunction< FunctorType , ArgTag >::enable_if( & FunctorType::init ) )
 
379
#else
 
380
  , typename Impl::enable_if< 0 < sizeof( & FunctorType::init ) >::type
 
381
#endif
 
382
  >
 
383
{
 
384
  KOKKOS_FORCEINLINE_FUNCTION static
 
385
  T * init( const FunctorType & f , void * p )
 
386
    { f.init( (T*)p ); return (T*)p ; }
 
387
};
 
388
 
 
389
} // namespace Impl
 
390
} // namespace Kokkos
 
391
 
 
392
//----------------------------------------------------------------------------
 
393
//----------------------------------------------------------------------------
 
394
 
 
395
namespace Kokkos {
 
396
namespace Impl {
 
397
 
 
398
// Signatures for compatible FunctorType::join with tag and not an array
 
399
template< class FunctorType , class ArgTag , bool IsArray = 0 == FunctorValueTraits<FunctorType,ArgTag>::StaticValueSize >
 
400
struct FunctorValueJoinFunction {
 
401
 
 
402
  typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
 
403
 
 
404
  typedef       volatile value_type & vref_type ;
 
405
  typedef const volatile value_type & cvref_type ;
 
406
 
 
407
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , vref_type , cvref_type ) const );
 
408
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , vref_type , cvref_type ) const );
 
409
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , vref_type , cvref_type ) );
 
410
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , vref_type , cvref_type ) );
 
411
};
 
412
 
 
413
// Signatures for compatible FunctorType::join with tag and is an array
 
414
template< class FunctorType , class ArgTag >
 
415
struct FunctorValueJoinFunction< FunctorType , ArgTag , true > {
 
416
 
 
417
  typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
 
418
 
 
419
  typedef       volatile value_type * vptr_type ;
 
420
  typedef const volatile value_type * cvptr_type ;
 
421
 
 
422
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , vptr_type , cvptr_type ) const );
 
423
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , vptr_type , cvptr_type ) const );
 
424
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , vptr_type , cvptr_type ) );
 
425
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , vptr_type , cvptr_type ) );
 
426
};
 
427
 
 
428
// Signatures for compatible FunctorType::join without tag and not an array
 
429
template< class FunctorType >
 
430
struct FunctorValueJoinFunction< FunctorType , void , false > {
 
431
 
 
432
  typedef typename FunctorValueTraits<FunctorType,void>::value_type value_type ;
 
433
 
 
434
  typedef       volatile value_type & vref_type ;
 
435
  typedef const volatile value_type & cvref_type ;
 
436
 
 
437
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( vref_type , cvref_type ) const );
 
438
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( vref_type , cvref_type ) );
 
439
};
 
440
 
 
441
// Signatures for compatible FunctorType::join without tag and is an array
 
442
template< class FunctorType >
 
443
struct FunctorValueJoinFunction< FunctorType , void , true > {
 
444
 
 
445
  typedef typename FunctorValueTraits<FunctorType,void>::value_type value_type ;
 
446
 
 
447
  typedef       volatile value_type * vptr_type ;
 
448
  typedef const volatile value_type * cvptr_type ;
 
449
 
 
450
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( vptr_type , cvptr_type ) const );
 
451
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( vptr_type , cvptr_type ) );
 
452
};
 
453
 
 
454
 
 
455
template< class FunctorType , class ArgTag
 
456
        , class T = typename FunctorValueTraits<FunctorType,ArgTag>::reference_type
 
457
        , class Enable = void >
 
458
struct FunctorValueJoin ;
 
459
 
 
460
/* No 'join' function provided, single value */
 
461
template< class FunctorType , class ArgTag , class T , class Enable >
 
462
struct FunctorValueJoin< FunctorType , ArgTag , T & , Enable >
 
463
{
 
464
  KOKKOS_FORCEINLINE_FUNCTION static
 
465
  void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
 
466
    {
 
467
      *((volatile T*)lhs) += *((const volatile T*)rhs);
 
468
    }
 
469
};
 
470
 
 
471
/* No 'join' function provided, array of values */
 
472
template< class FunctorType , class ArgTag , class T , class Enable >
 
473
struct FunctorValueJoin< FunctorType , ArgTag , T * , Enable >
 
474
{
 
475
  KOKKOS_FORCEINLINE_FUNCTION static
 
476
  void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
 
477
    {
 
478
      const int n = FunctorValueTraits<FunctorType,ArgTag>::value_count(f);
 
479
 
 
480
      for ( int i = 0 ; i < n ; ++i ) { ((volatile T*)lhs)[i] += ((const volatile T*)rhs)[i]; }
 
481
    }
 
482
};
 
483
 
 
484
/* 'join' function provided, single value */
 
485
template< class FunctorType , class ArgTag , class T >
 
486
struct FunctorValueJoin
 
487
  < FunctorType
 
488
  , ArgTag
 
489
  , T &
 
490
    // First  substitution failure when FunctorType::join does not exist.
 
491
#if defined( KOKKOS_HAVE_CXX11 )
 
492
    // Second substitution failure when enable_if( & Functor::join ) does not exist
 
493
  , decltype( FunctorValueJoinFunction< FunctorType , ArgTag >::enable_if( & FunctorType::join ) )
 
494
#else
 
495
  , typename Impl::enable_if< 0 < sizeof( & FunctorType::join ) >::type
 
496
#endif
 
497
  >
 
498
{
 
499
  KOKKOS_FORCEINLINE_FUNCTION static
 
500
  void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
 
501
    {
 
502
      f.join( ArgTag() , *((volatile T *)lhs) , *((const volatile T *)rhs) );
 
503
    }
 
504
};
 
505
 
 
506
/* 'join' function provided, no tag, single value */
 
507
template< class FunctorType , class T >
 
508
struct FunctorValueJoin
 
509
  < FunctorType
 
510
  , void
 
511
  , T &
 
512
    // First  substitution failure when FunctorType::join does not exist.
 
513
#if defined( KOKKOS_HAVE_CXX11 )
 
514
    // Second substitution failure when enable_if( & Functor::join ) does not exist
 
515
  , decltype( FunctorValueJoinFunction< FunctorType , void >::enable_if( & FunctorType::join ) )
 
516
#else
 
517
  , typename Impl::enable_if< 0 < sizeof( & FunctorType::join ) >::type
 
518
#endif
 
519
  >
 
520
{
 
521
  KOKKOS_FORCEINLINE_FUNCTION static
 
522
  void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
 
523
    {
 
524
      f.join( *((volatile T *)lhs) , *((const volatile T *)rhs) );
 
525
    }
 
526
};
 
527
 
 
528
/* 'join' function provided for array value */
 
529
template< class FunctorType , class ArgTag , class T >
 
530
struct FunctorValueJoin
 
531
  < FunctorType
 
532
  , ArgTag
 
533
  , T *
 
534
    // First  substitution failure when FunctorType::join does not exist.
 
535
#if defined( KOKKOS_HAVE_CXX11 )
 
536
    // Second substitution failure when enable_if( & Functor::join ) does not exist
 
537
  , decltype( FunctorValueJoinFunction< FunctorType , ArgTag >::enable_if( & FunctorType::join ) )
 
538
#else
 
539
  , typename Impl::enable_if< 0 < sizeof( & FunctorType::join ) >::type
 
540
#endif
 
541
  >
 
542
{
 
543
  KOKKOS_FORCEINLINE_FUNCTION static
 
544
  void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
 
545
    {
 
546
      f.join( ArgTag() , (volatile T *)lhs , (const volatile T *)rhs );
 
547
    }
 
548
};
 
549
 
 
550
/* 'join' function provided, no tag, array value */
 
551
template< class FunctorType , class T >
 
552
struct FunctorValueJoin
 
553
  < FunctorType
 
554
  , void
 
555
  , T *
 
556
    // First  substitution failure when FunctorType::join does not exist.
 
557
#if defined( KOKKOS_HAVE_CXX11 )
 
558
    // Second substitution failure when enable_if( & Functor::join ) does not exist
 
559
  , decltype( FunctorValueJoinFunction< FunctorType , void >::enable_if( & FunctorType::join ) )
 
560
#else
 
561
  , typename Impl::enable_if< 0 < sizeof( & FunctorType::join ) >::type
 
562
#endif
 
563
  >
 
564
{
 
565
  KOKKOS_FORCEINLINE_FUNCTION static
 
566
  void join( const FunctorType & f , volatile void * const lhs , const volatile void * const rhs )
 
567
    {
 
568
      f.join( (volatile T *)lhs , (const volatile T *)rhs );
 
569
    }
 
570
};
 
571
 
 
572
} // namespace Impl
 
573
} // namespace Kokkos
 
574
 
 
575
#ifdef KOKKOS_HAVE_CXX11
 
576
namespace Kokkos {
 
577
 
 
578
namespace Impl {
 
579
 
 
580
  template<typename ValueType, class JoinOp, class Enable = void>
 
581
  struct JoinLambdaAdapter {
 
582
    typedef ValueType value_type;
 
583
    const JoinOp& lambda;
 
584
    KOKKOS_INLINE_FUNCTION
 
585
    JoinLambdaAdapter(const JoinOp& lambda_):lambda(lambda_) {}
 
586
 
 
587
    KOKKOS_INLINE_FUNCTION
 
588
    void join(volatile value_type& dst, const volatile value_type& src) const {
 
589
      lambda(dst,src);
 
590
    }
 
591
 
 
592
    KOKKOS_INLINE_FUNCTION
 
593
    void join(value_type& dst, const value_type& src) const {
 
594
      lambda(dst,src);
 
595
    }
 
596
 
 
597
    KOKKOS_INLINE_FUNCTION
 
598
    void operator() (volatile value_type& dst, const volatile value_type& src) const {
 
599
      lambda(dst,src);
 
600
    }
 
601
 
 
602
    KOKKOS_INLINE_FUNCTION
 
603
    void operator() (value_type& dst, const value_type& src) const {
 
604
      lambda(dst,src);
 
605
    }
 
606
  };
 
607
 
 
608
  template<typename ValueType, class JoinOp>
 
609
  struct JoinLambdaAdapter<ValueType, JoinOp, decltype( FunctorValueJoinFunction< JoinOp , void >::enable_if( & JoinOp::join ) )> {
 
610
    typedef ValueType value_type;
 
611
    typedef StaticAssertSame<ValueType,typename JoinOp::value_type> assert_value_types_match;
 
612
    const JoinOp& lambda;
 
613
    KOKKOS_INLINE_FUNCTION
 
614
    JoinLambdaAdapter(const JoinOp& lambda_):lambda(lambda_) {}
 
615
 
 
616
    KOKKOS_INLINE_FUNCTION
 
617
    void join(volatile value_type& dst, const volatile value_type& src) const {
 
618
      lambda.join(dst,src);
 
619
    }
 
620
 
 
621
    KOKKOS_INLINE_FUNCTION
 
622
    void join(value_type& dst, const value_type& src) const {
 
623
      lambda.join(dst,src);
 
624
    }
 
625
 
 
626
    KOKKOS_INLINE_FUNCTION
 
627
    void operator() (volatile value_type& dst, const volatile value_type& src) const {
 
628
      lambda.join(dst,src);
 
629
    }
 
630
 
 
631
    KOKKOS_INLINE_FUNCTION
 
632
    void operator() (value_type& dst, const value_type& src) const {
 
633
      lambda.join(dst,src);
 
634
    }
 
635
  };
 
636
 
 
637
  template<typename ValueType>
 
638
  struct JoinAdd {
 
639
    typedef ValueType value_type;
 
640
 
 
641
    KOKKOS_INLINE_FUNCTION
 
642
    JoinAdd() {}
 
643
 
 
644
    KOKKOS_INLINE_FUNCTION
 
645
    void join(volatile value_type& dst, const volatile value_type& src) const {
 
646
      dst+=src;
 
647
    }
 
648
    KOKKOS_INLINE_FUNCTION
 
649
    void operator() (value_type& dst, const value_type& src) const {
 
650
      dst+=src;
 
651
    }
 
652
    KOKKOS_INLINE_FUNCTION
 
653
    void operator() (volatile value_type& dst, const volatile value_type& src) const {
 
654
      dst+=src;
 
655
    }
 
656
  };
 
657
 
 
658
}
 
659
}
 
660
#endif
 
661
 
 
662
//----------------------------------------------------------------------------
 
663
//----------------------------------------------------------------------------
 
664
 
 
665
namespace Kokkos {
 
666
namespace Impl {
 
667
 
 
668
template< class FunctorType , class ArgTag
 
669
        , class T = typename FunctorValueTraits<FunctorType,ArgTag>::reference_type >
 
670
struct FunctorValueOps ;
 
671
 
 
672
template< class FunctorType , class ArgTag , class T >
 
673
struct FunctorValueOps< FunctorType , ArgTag , T & >
 
674
{
 
675
  KOKKOS_FORCEINLINE_FUNCTION static
 
676
  T * pointer( T & r ) { return & r ; }
 
677
 
 
678
  KOKKOS_FORCEINLINE_FUNCTION static
 
679
  T & reference( void * p ) { return *((T*)p); }
 
680
 
 
681
  KOKKOS_FORCEINLINE_FUNCTION static
 
682
  void copy( const FunctorType & , void * const lhs , const void * const rhs )
 
683
    { *((T*)lhs) = *((const T*)rhs); }
 
684
};
 
685
 
 
686
/* No 'join' function provided, array of values */
 
687
template< class FunctorType , class ArgTag , class T >
 
688
struct FunctorValueOps< FunctorType , ArgTag , T * >
 
689
{
 
690
  KOKKOS_FORCEINLINE_FUNCTION static
 
691
  T * pointer( T * p ) { return p ; }
 
692
 
 
693
  KOKKOS_FORCEINLINE_FUNCTION static
 
694
  T * reference( void * p ) { return ((T*)p); }
 
695
 
 
696
  KOKKOS_FORCEINLINE_FUNCTION static
 
697
  void copy( const FunctorType & f , void * const lhs , const void * const rhs )
 
698
    {
 
699
      const int n = FunctorValueTraits<FunctorType,ArgTag>::value_count(f);
 
700
      for ( int i = 0 ; i < n ; ++i ) { ((T*)lhs)[i] = ((const T*)rhs)[i]; }
 
701
    }
 
702
};
 
703
 
 
704
} // namespace Impl
 
705
} // namespace Kokkos
 
706
 
 
707
//----------------------------------------------------------------------------
 
708
//----------------------------------------------------------------------------
 
709
 
 
710
namespace Kokkos {
 
711
namespace Impl {
 
712
 
 
713
// Compatible functions for 'final' function and value_type not an array
 
714
template< class FunctorType , class ArgTag , bool IsArray = 0 == FunctorValueTraits<FunctorType,ArgTag>::StaticValueSize >
 
715
struct FunctorFinalFunction {
 
716
 
 
717
  typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
 
718
 
 
719
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type & ) const );
 
720
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type & ) const );
 
721
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type & ) );
 
722
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type & ) );
 
723
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type & ) );
 
724
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type & ) );
 
725
 
 
726
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type volatile & ) const );
 
727
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile & ) const );
 
728
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type volatile & ) );
 
729
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile & ) );
 
730
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type volatile & ) );
 
731
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type volatile & ) );
 
732
 
 
733
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type const & ) const );
 
734
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const & ) const );
 
735
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type const & ) );
 
736
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const & ) );
 
737
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type const & ) );
 
738
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type const & ) );
 
739
 
 
740
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type const volatile & ) const );
 
741
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const volatile & ) const );
 
742
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type const volatile & ) );
 
743
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const volatile & ) );
 
744
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type const volatile & ) );
 
745
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type const volatile & ) );
 
746
};
 
747
 
 
748
// Compatible functions for 'final' function and value_type is an array
 
749
template< class FunctorType , class ArgTag >
 
750
struct FunctorFinalFunction< FunctorType , ArgTag , true > {
 
751
 
 
752
  typedef typename FunctorValueTraits<FunctorType,ArgTag>::value_type value_type ;
 
753
 
 
754
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type * ) const );
 
755
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type * ) const );
 
756
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type * ) );
 
757
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type * ) );
 
758
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type * ) );
 
759
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type * ) );
 
760
 
 
761
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type volatile * ) const );
 
762
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile * ) const );
 
763
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type volatile * ) );
 
764
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type volatile * ) );
 
765
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type volatile * ) );
 
766
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type volatile * ) );
 
767
 
 
768
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type const * ) const );
 
769
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const * ) const );
 
770
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type const * ) );
 
771
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const * ) );
 
772
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type const * ) );
 
773
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type const * ) );
 
774
 
 
775
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type const volatile * ) const );
 
776
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const volatile * ) const );
 
777
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , value_type const volatile * ) );
 
778
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , value_type const volatile * ) );
 
779
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , value_type const volatile * ) );
 
780
  // KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , value_type const volatile * ) );
 
781
};
 
782
 
 
783
template< class FunctorType >
 
784
struct FunctorFinalFunction< FunctorType , void , false > {
 
785
 
 
786
  typedef typename FunctorValueTraits<FunctorType,void>::value_type value_type ;
 
787
 
 
788
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type & ) const );
 
789
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type & ) );
 
790
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( value_type & ) );
 
791
 
 
792
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( const value_type & ) const );
 
793
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( const value_type & ) );
 
794
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( const value_type & ) );
 
795
};
 
796
 
 
797
template< class FunctorType >
 
798
struct FunctorFinalFunction< FunctorType , void , true > {
 
799
 
 
800
  typedef typename FunctorValueTraits<FunctorType,void>::value_type value_type ;
 
801
 
 
802
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type * ) const );
 
803
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( value_type * ) );
 
804
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( value_type * ) );
 
805
 
 
806
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( const value_type * ) const );
 
807
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( const value_type * ) );
 
808
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( const value_type * ) );
 
809
};
 
810
 
 
811
/* No 'final' function provided */
 
812
template< class FunctorType , class ArgTag
 
813
        , class ResultType = typename FunctorValueTraits<FunctorType,ArgTag>::reference_type
 
814
        , class Enable = void >
 
815
struct FunctorFinal
 
816
{
 
817
  KOKKOS_FORCEINLINE_FUNCTION static
 
818
  void final( const FunctorType & , void * ) {}
 
819
};
 
820
 
 
821
/* 'final' function provided */
 
822
template< class FunctorType , class ArgTag , class T >
 
823
struct FunctorFinal
 
824
  < FunctorType
 
825
  , ArgTag
 
826
  , T &
 
827
    // First  substitution failure when FunctorType::final does not exist.
 
828
#if defined( KOKKOS_HAVE_CXX11 )
 
829
    // Second substitution failure when enable_if( & Functor::final ) does not exist
 
830
  , decltype( FunctorFinalFunction< FunctorType , ArgTag >::enable_if( & FunctorType::final ) )
 
831
#else
 
832
  , typename Impl::enable_if< 0 < sizeof( & FunctorType::final ) >::type
 
833
#endif
 
834
  >
 
835
{
 
836
  KOKKOS_FORCEINLINE_FUNCTION static
 
837
  void final( const FunctorType & f , void * p ) { f.final( *((T*)p) ); }
 
838
 
 
839
  KOKKOS_FORCEINLINE_FUNCTION static
 
840
  void final( FunctorType & f , void * p ) { f.final( *((T*)p) ); }
 
841
};
 
842
 
 
843
/* 'final' function provided for array value */
 
844
template< class FunctorType , class ArgTag , class T >
 
845
struct FunctorFinal
 
846
  < FunctorType
 
847
  , ArgTag
 
848
  , T *
 
849
    // First  substitution failure when FunctorType::final does not exist.
 
850
#if defined( KOKKOS_HAVE_CXX11 )
 
851
    // Second substitution failure when enable_if( & Functor::final ) does not exist
 
852
  , decltype( FunctorFinalFunction< FunctorType , ArgTag >::enable_if( & FunctorType::final ) )
 
853
#else
 
854
  , typename Impl::enable_if< 0 < sizeof( & FunctorType::final ) >::type
 
855
#endif
 
856
  >
 
857
{
 
858
  KOKKOS_FORCEINLINE_FUNCTION static
 
859
  void final( const FunctorType & f , void * p ) { f.final( (T*)p ); }
 
860
 
 
861
  KOKKOS_FORCEINLINE_FUNCTION static
 
862
  void final( FunctorType & f , void * p ) { f.final( (T*)p ); }
 
863
};
 
864
 
 
865
} // namespace Impl
 
866
} // namespace Kokkos
 
867
 
 
868
//----------------------------------------------------------------------------
 
869
//----------------------------------------------------------------------------
 
870
 
 
871
namespace Kokkos {
 
872
namespace Impl {
 
873
 
 
874
template< class FunctorType , class ArgTag
 
875
        , class ReferenceType = typename FunctorValueTraits<FunctorType,ArgTag>::reference_type >
 
876
struct FunctorApplyFunction {
 
877
 
 
878
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , ReferenceType ) const );
 
879
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , ReferenceType ) const );
 
880
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag         , ReferenceType ) );
 
881
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ArgTag const & , ReferenceType ) );
 
882
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag         , ReferenceType ) );
 
883
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ArgTag const & , ReferenceType ) );
 
884
};
 
885
 
 
886
template< class FunctorType , class ReferenceType >
 
887
struct FunctorApplyFunction< FunctorType , void , ReferenceType > {
 
888
 
 
889
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ReferenceType ) const );
 
890
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)( ReferenceType ) );
 
891
  KOKKOS_INLINE_FUNCTION static void enable_if( void (             *)( ReferenceType ) );
 
892
};
 
893
 
 
894
template< class FunctorType >
 
895
struct FunctorApplyFunction< FunctorType , void , void > {
 
896
 
 
897
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)() const );
 
898
  KOKKOS_INLINE_FUNCTION static void enable_if( void (FunctorType::*)() );
 
899
};
 
900
 
 
901
template< class FunctorType , class ArgTag , class ReferenceType
 
902
        , class Enable = void >
 
903
struct FunctorApply
 
904
{
 
905
  KOKKOS_FORCEINLINE_FUNCTION static
 
906
  void apply( const FunctorType & , void * ) {}
 
907
};
 
908
 
 
909
/* 'apply' function provided for void value */
 
910
template< class FunctorType , class ArgTag >
 
911
struct FunctorApply
 
912
  < FunctorType
 
913
  , ArgTag
 
914
  , void
 
915
    // First  substitution failure when FunctorType::apply does not exist.
 
916
#if defined( KOKKOS_HAVE_CXX11 )
 
917
    // Second substitution failure when enable_if( & Functor::apply ) does not exist
 
918
  , decltype( FunctorApplyFunction< FunctorType , ArgTag , void >::enable_if( & FunctorType::apply ) )
 
919
#else
 
920
  , typename Impl::enable_if< 0 < sizeof( & FunctorType::apply ) >::type
 
921
#endif
 
922
  >
 
923
{
 
924
  KOKKOS_FORCEINLINE_FUNCTION static
 
925
  void apply( FunctorType & f ) { f.apply(); }
 
926
 
 
927
  KOKKOS_FORCEINLINE_FUNCTION static
 
928
  void apply( const FunctorType & f ) { f.apply(); }
 
929
};
 
930
 
 
931
/* 'apply' function provided for single value */
 
932
template< class FunctorType , class ArgTag , class T >
 
933
struct FunctorApply
 
934
  < FunctorType
 
935
  , ArgTag
 
936
  , T &
 
937
    // First  substitution failure when FunctorType::apply does not exist.
 
938
#if defined( KOKKOS_HAVE_CXX11 )
 
939
    // Second substitution failure when enable_if( & Functor::apply ) does not exist
 
940
  , decltype( FunctorApplyFunction< FunctorType , ArgTag >::enable_if( & FunctorType::apply ) )
 
941
#else
 
942
  , typename Impl::enable_if< 0 < sizeof( & FunctorType::apply ) >::type
 
943
#endif
 
944
  >
 
945
{
 
946
  KOKKOS_FORCEINLINE_FUNCTION static
 
947
  void apply( const FunctorType & f , void * p ) { f.apply( *((T*)p) ); }
 
948
 
 
949
  KOKKOS_FORCEINLINE_FUNCTION static
 
950
  void apply( FunctorType & f , void * p ) { f.apply( *((T*)p) ); }
 
951
};
 
952
 
 
953
} // namespace Impl
 
954
} // namespace Kokkos
 
955
 
 
956
//----------------------------------------------------------------------------
 
957
//----------------------------------------------------------------------------
 
958
 
 
959
#endif /* KOKKOS_FUNCTORADAPTER_HPP */
 
960