LvArray
typeManipulation.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021, Lawrence Livermore National Security, LLC and LvArray contributors.
3  * All rights reserved.
4  * See the LICENSE file for details.
5  * SPDX-License-Identifier: (BSD-3-Clause)
6  */
7 
13 #pragma once
14 
15 // Source includes
16 #include "LvArrayConfig.hpp"
17 #include "Macros.hpp"
18 
19 // TPL includes
20 #include <camp/camp.hpp>
21 
22 // System includes
23 #include <initializer_list>
24 #include <utility>
25 #include <type_traits>
26 
27 #if defined(__GLIBCXX__) && __GLIBCXX__ <= 20150626
28 namespace std
29 {
33 template< typename T >
34 using is_trivially_default_constructible = has_trivial_default_constructor< T >;
35 }
36 #endif
37 
45 #define IS_VALID_EXPRESSION( NAME, T, ... ) \
46  template< typename _T > \
47  struct NAME ## _impl \
48  { \
49 private: \
50  template< typename T > static constexpr auto test( int )->decltype( __VA_ARGS__, bool() ) \
51  { return true; } \
52  template< typename T > static constexpr auto test( ... )->bool \
53  { return false; } \
54 public: \
55  static constexpr bool value = test< _T >( 0 ); \
56  }; \
57  template< typename T > \
58  static constexpr bool NAME = NAME ## _impl< T >::value
59 
68 #define IS_VALID_EXPRESSION_2( NAME, T, U, ... ) \
69  template< typename _T, typename _U > \
70  struct NAME ## _impl \
71  { \
72 private: \
73  template< typename T, typename U > static constexpr auto test( int )->decltype( __VA_ARGS__, bool() ) \
74  { return true; } \
75  template< typename T, typename U > static constexpr auto test( ... )->bool \
76  { return false; } \
77 public: \
78  static constexpr bool value = test< _T, _U >( 0 ); \
79  }; \
80  template< typename T, typename U > \
81  static constexpr bool NAME = NAME ## _impl< T, U >::value
82 
91 #define HAS_MEMBER_FUNCTION_NO_RTYPE( NAME, ... ) \
92  IS_VALID_EXPRESSION( HasMemberFunction_ ## NAME, CLASS, std::declval< CLASS & >().NAME( __VA_ARGS__ ) )
93 
100 #define HAS_MEMBER_TYPE( NAME ) \
101  IS_VALID_EXPRESSION( HasMemberType_ ## NAME, CLASS, std::declval< typename CLASS::NAME >() )
102 
109 #define HAS_STATIC_MEMBER( NAME ) \
110  IS_VALID_EXPRESSION( HasStaticMember_ ## NAME, CLASS, std::enable_if_t< !std::is_member_pointer< decltype( &CLASS::NAME ) >::value, bool >{} )
111 
112 namespace LvArray
113 {
114 
118 namespace typeManipulation
119 {
120 
127 template< typename F >
128 inline constexpr LVARRAY_HOST_DEVICE
129 void forEachArg( F && f )
130 { LVARRAY_UNUSED_VARIABLE( f ); }
131 
142 template< typename F, typename ARG, typename ... ARGS >
143 inline constexpr LVARRAY_HOST_DEVICE
144 void forEachArg( F && f, ARG && arg, ARGS && ... args )
145 {
146  f( arg );
147  forEachArg( std::forward< F >( f ), std::forward< ARGS >( args ) ... );
148 }
149 
155 template< bool ... BOOLS >
157 
163 template< typename ... TYPES >
165 
172 template< template< typename ... > class TEMPLATE,
173  typename TYPE >
174 constexpr bool is_instantiation_of = false;
175 
183 template< template< typename ... > class TEMPLATE,
184  typename ... ARGS >
185 constexpr bool is_instantiation_of< TEMPLATE, TEMPLATE< ARGS... > > = true;
186 
193 
199 HAS_MEMBER_FUNCTION_NO_RTYPE( toViewConstSizes, );
200 
206 HAS_MEMBER_FUNCTION_NO_RTYPE( toViewConst, );
207 
213 HAS_MEMBER_FUNCTION_NO_RTYPE( toNestedView, );
214 
220 HAS_MEMBER_FUNCTION_NO_RTYPE( toNestedViewConst, );
221 
222 namespace internal
223 {
224 
231 template< typename T, bool=HasMemberFunction_toView< T > >
233 {
235  using type = T &;
236 };
237 
244 template< typename T >
245 struct GetViewType< T, true >
246 {
248  using type = decltype( std::declval< T & >().toView() );
249 };
250 
257 template< typename T, bool=HasMemberFunction_toViewConstSizes< T > >
259 {
261  using type = typename GetViewType< T >::type;
262 };
263 
270 template< typename T >
271 struct GetViewTypeConstSizes< T, true >
272 {
274  using type = decltype( std::declval< T & >().toViewConstSizes() );
275 };
276 
283 template< typename T, bool=HasMemberFunction_toViewConst< T > >
285 {
287  using type = std::remove_reference_t< T > const &;
288 };
289 
296 template< typename T >
297 struct GetViewTypeConst< T, true >
298 {
300  using type = decltype( std::declval< T & >().toViewConst() );
301 };
302 
308 template< typename T, bool=HasMemberFunction_toNestedView< T > >
310 {
312  using type = typename GetViewType< T >::type;
313 };
314 
321 template< typename T >
322 struct GetNestedViewType< T, true >
323 {
325  using type = decltype( std::declval< T & >().toNestedView() ) const;
326 };
327 
333 template< typename T, bool=HasMemberFunction_toNestedViewConst< T > >
335 {
338 };
339 
346 template< typename T >
347 struct GetNestedViewTypeConst< T, true >
348 {
350  using type = decltype( std::declval< T & >().toNestedViewConst() ) const;
351 };
352 
353 } // namespace internal
354 
359 template< typename T >
361 
366 template< typename T >
368 
373 template< typename T >
375 
380 template< typename T >
382 
387 template< typename T >
389 
390 
391 namespace internal
392 {
393 
399 template< camp::idx_t INDEX_TO_FIND, camp::idx_t INDEX >
400 constexpr bool contains( camp::idx_seq< INDEX > )
401 { return INDEX_TO_FIND == INDEX; }
402 
410 template< camp::idx_t INDEX_TO_FIND, camp::idx_t INDEX0, camp::idx_t INDEX1, camp::idx_t... INDICES >
411 constexpr bool contains( camp::idx_seq< INDEX0, INDEX1, INDICES... > )
412 { return ( INDEX_TO_FIND == INDEX0 ) || contains< INDEX_TO_FIND >( camp::idx_seq< INDEX1, INDICES... > {} ); }
413 
419 template< typename PERMUTATION, camp::idx_t... INDICES >
420 constexpr bool isValidPermutation( PERMUTATION, camp::idx_seq< INDICES... > )
421 { return all_of< contains< INDICES >( PERMUTATION {} )... >::value; }
422 
427 template< camp::idx_t... INDICES >
428 constexpr camp::idx_t getDimension( camp::idx_seq< INDICES... > )
429 { return sizeof...( INDICES ); }
430 
431 } // namespace internal
432 
437 template< typename T >
438 static constexpr camp::idx_t getDimension = internal::getDimension( T {} );
439 
444 template< camp::idx_t... INDICES >
445 LVARRAY_HOST_DEVICE constexpr camp::idx_t getStrideOneDimension( camp::idx_seq< INDICES... > )
446 {
447  constexpr camp::idx_t dimension = camp::seq_at< sizeof...( INDICES ) - 1, camp::idx_seq< INDICES... > >::value;
448  static_assert( dimension >= 0, "The dimension must be greater than zero." );
449  static_assert( dimension < sizeof...( INDICES ), "The dimension must be less than NDIM." );
450  return dimension;
451 }
452 
457 template< typename PERMUTATION >
458 constexpr bool isValidPermutation( PERMUTATION )
459 {
460  constexpr int NDIM = getDimension< PERMUTATION >;
461  return internal::isValidPermutation( PERMUTATION {}, camp::make_idx_seq_t< NDIM > {} );
462 }
463 
473 template< typename T, typename U, typename INDEX_TYPE >
474 constexpr inline LVARRAY_HOST_DEVICE
475 std::enable_if_t< ( sizeof( T ) <= sizeof( U ) ), INDEX_TYPE >
476 convertSize( INDEX_TYPE const numU )
477 {
478  static_assert( sizeof( U ) % sizeof( T ) == 0, "T and U need to have compatable sizes." );
479 
480  return numU * sizeof( U ) / sizeof( T );
481 }
482 
492 template< typename T, typename U, typename INDEX_TYPE >
493 inline LVARRAY_HOST_DEVICE
494 std::enable_if_t< ( sizeof( T ) > sizeof( U ) ), INDEX_TYPE >
495 convertSize( INDEX_TYPE const numU )
496 {
497  static_assert( sizeof( T ) % sizeof( U ) == 0, "T and U need to have compatable sizes." );
498 
499  INDEX_TYPE const numUPerT = sizeof( T ) / sizeof( U );
500  INDEX_TYPE const remainder = numU % numUPerT;
501  LVARRAY_ERROR_IF_NE( remainder, 0 );
502 
503  return numU / numUPerT;
504 }
505 
512 template< typename T, camp::idx_t N >
513 struct CArray
514 {
519  LVARRAY_INTEL_CONSTEXPR inline LVARRAY_HOST_DEVICE
520  T & operator[]( camp::idx_t const i )
521  { return data[ i ]; }
522 
527  constexpr inline LVARRAY_HOST_DEVICE
528  T const & operator[]( camp::idx_t const i ) const
529  { return data[ i ]; }
530 
534  constexpr inline LVARRAY_HOST_DEVICE
535  camp::idx_t size()
536  { return N; }
537 
539  // TODO(corbett5) remove {}
540  T data[ N ] = {};
541 };
542 
547 template< camp::idx_t... INDICES >
548 LVARRAY_HOST_DEVICE inline constexpr
549 CArray< camp::idx_t, sizeof...( INDICES ) > asArray( camp::idx_seq< INDICES... > )
550 { return { INDICES ... }; }
551 
552 } // namespace typeManipulation
553 } // namespace LvArray
#define LVARRAY_UNUSED_VARIABLE(X)
Mark X as an unused variable, used to silence compiler warnings.
Definition: Macros.hpp:51
typename GetViewTypeConst< T >::type type
An alias for the view type.
Definition: typeManipulation.hpp:337
decltype(std::declval< T &>().toNestedViewConst()) const type
An alias for the view type.
Definition: typeManipulation.hpp:350
T & type
An alias for the view type.
Definition: typeManipulation.hpp:235
LVARRAY_HOST_DEVICE constexpr CArray< camp::idx_t, sizeof...(INDICES) > asArray(camp::idx_seq< INDICES... >)
Definition: typeManipulation.hpp:549
A helper struct used to get the const view type of an object.
Definition: typeManipulation.hpp:284
constexpr bool isValidPermutation(PERMUTATION)
Definition: typeManipulation.hpp:458
A helper struct used to get the nested view const type of an object.
Definition: typeManipulation.hpp:334
decltype(std::declval< T &>().toNestedView()) const type
An alias for the view type.
Definition: typeManipulation.hpp:325
typename GetViewType< T >::type type
An alias for the view type.
Definition: typeManipulation.hpp:261
decltype(std::declval< T &>().toViewConst()) type
An alias for the const view type.
Definition: typeManipulation.hpp:300
LVARRAY_HOST_DEVICE constexpr camp::idx_t getStrideOneDimension(camp::idx_seq< INDICES... >)
Definition: typeManipulation.hpp:445
typename internal::GetViewTypeConst< T >::type ViewTypeConst
An alias for the const view type of T.
Definition: typeManipulation.hpp:374
constexpr bool is_instantiation_of
Trait to detect if.
Definition: typeManipulation.hpp:174
A helper struct used to get the view type of an object.
Definition: typeManipulation.hpp:232
decltype(std::declval< T &>().toView()) type
An alias for the view type.
Definition: typeManipulation.hpp:248
A helper struct used to get the un-resizable view type of an object.
Definition: typeManipulation.hpp:258
constexpr LVARRAY_HOST_DEVICE camp::idx_t size()
Definition: typeManipulation.hpp:535
decltype(std::declval< T &>().toViewConstSizes()) type
An alias for the view type.
Definition: typeManipulation.hpp:274
#define HAS_MEMBER_FUNCTION_NO_RTYPE(NAME,...)
Macro that expands to a static constexpr bool templated on a type that is only true when the type has...
Definition: typeManipulation.hpp:91
camp::concepts::metalib::all_of< BOOLS ... > all_of
A struct that contains a static constexpr bool value that is true if all of BOOLS are true...
Definition: typeManipulation.hpp:156
typename internal::GetNestedViewTypeConst< T >::type NestedViewTypeConst
An alias for the nested const view type of T.
Definition: typeManipulation.hpp:388
The top level namespace.
Definition: Array.hpp:24
typename internal::GetViewTypeConstSizes< T >::type ViewTypeConstSizes
An alias for the un-resizable view type of T.
Definition: typeManipulation.hpp:367
typename internal::GetNestedViewType< T >::type NestedViewType
An alias for the nested view type of T.
Definition: typeManipulation.hpp:381
typename GetViewType< T >::type type
An alias for the view type.
Definition: typeManipulation.hpp:312
Contains a bunch of macro definitions.
LVARRAY_HOST_DEVICE std::enable_if_t<(sizeof(T) > sizeof(U)), INDEX_TYPE > convertSize(INDEX_TYPE const numU)
Convert a number of values of type U to a number of values of type T.
Definition: typeManipulation.hpp:495
constexpr LVARRAY_HOST_DEVICE T const & operator[](camp::idx_t const i) const
Definition: typeManipulation.hpp:528
A helper struct used to get the nested view type of an object.
Definition: typeManipulation.hpp:309
A wrapper around a compile time c array.
Definition: typeManipulation.hpp:513
typename internal::GetViewType< T >::type ViewType
An alias for the view type of T.
Definition: typeManipulation.hpp:360
#define DISABLE_HD_WARNING
Disable host device warnings.
Definition: Macros.hpp:561
camp::concepts::metalib::all_of_t< TYPES ... > all_of_t
A struct that contains a static constexpr bool value that is true if all of TYPES::value are true...
Definition: typeManipulation.hpp:164
#define LVARRAY_ERROR_IF_NE(lhs, rhs)
Raise a hard error if two values are not equal.
Definition: Macros.hpp:321
DISABLE_HD_WARNING constexpr LVARRAY_HOST_DEVICE void forEachArg(F &&f, ARG &&arg, ARGS &&... args)
Call the f with arg and then again with each argument in args .
Definition: typeManipulation.hpp:144
#define LVARRAY_HOST_DEVICE
Mark a function for both host and device usage.
Definition: Macros.hpp:549
std::remove_reference_t< T > const & type
An alias for the const view type.
Definition: typeManipulation.hpp:287
static constexpr camp::idx_t getDimension
Definition: typeManipulation.hpp:438
LVARRAY_INTEL_CONSTEXPR LVARRAY_HOST_DEVICE T & operator[](camp::idx_t const i)
Definition: typeManipulation.hpp:520