Smith  0.1
Smith is an implicit thermal structural mechanics simulation code.
tuple.hpp
Go to the documentation of this file.
1 // Copyright (c) Lawrence Livermore National Security, LLC and
2 // other Smith Project Developers. See the top-level LICENSE file for
3 // details.
4 //
5 // SPDX-License-Identifier: (BSD-3-Clause)
6 
12 #pragma once
13 
14 #include <utility>
15 
17 
18 namespace smith {
19 
27 template <typename... T>
28 struct tuple {};
29 
35 template <typename T0>
36 struct tuple<T0> {
37  T0 v0;
38 };
39 
46 template <typename T0, typename T1>
47 struct tuple<T0, T1> {
48  T0 v0;
49  T1 v1;
50 };
51 
59 template <typename T0, typename T1, typename T2>
60 struct tuple<T0, T1, T2> {
61  T0 v0;
62  T1 v1;
63  T2 v2;
64 };
65 
74 template <typename T0, typename T1, typename T2, typename T3>
75 struct tuple<T0, T1, T2, T3> {
76  T0 v0;
77  T1 v1;
78  T2 v2;
79  T3 v3;
80 };
81 
91 template <typename T0, typename T1, typename T2, typename T3, typename T4>
92 struct tuple<T0, T1, T2, T3, T4> {
93  T0 v0;
94  T1 v1;
95  T2 v2;
96  T3 v3;
97  T4 v4;
98 };
99 
110 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
111 struct tuple<T0, T1, T2, T3, T4, T5> {
112  T0 v0;
113  T1 v1;
114  T2 v2;
115  T3 v3;
116  T4 v4;
117  T5 v5;
118 };
119 
131 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
132 struct tuple<T0, T1, T2, T3, T4, T5, T6> {
133  T0 v0;
134  T1 v1;
135  T2 v2;
136  T3 v3;
137  T4 v4;
138  T5 v5;
139  T6 v6;
140 };
141 
154 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
155 struct tuple<T0, T1, T2, T3, T4, T5, T6, T7> {
156  T0 v0;
157  T1 v1;
158  T2 v2;
159  T3 v3;
160  T4 v4;
161  T5 v5;
162  T6 v6;
163  T7 v7;
164 };
165 
179 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
180  typename T8>
181 struct tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> {
182  T0 v0;
183  T1 v1;
184  T2 v2;
185  T3 v3;
186  T4 v4;
187  T5 v5;
188  T6 v6;
189  T7 v7;
190  T8 v8;
191 };
192 
207 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
208  typename T8, typename T9>
209 struct tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> {
210  T0 v0;
211  T1 v1;
212  T2 v2;
213  T3 v3;
214  T4 v4;
215  T5 v5;
216  T6 v6;
217  T7 v7;
218  T8 v8;
219  T9 v9;
220 };
221 
237 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
238  typename T8, typename T9, typename T10>
239 struct tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> {
240  T0 v0;
241  T1 v1;
242  T2 v2;
243  T3 v3;
244  T4 v4;
245  T5 v5;
246  T6 v6;
247  T7 v7;
248  T8 v8;
249  T9 v9;
250  T10 v10;
251 };
252 
257 template <typename... T>
258 tuple(T...) -> tuple<T...>;
259 
265 template <typename... T>
266 SMITH_HOST_DEVICE tuple<T...> make_tuple(const T&... args)
267 {
268  return tuple<T...>{args...};
269 }
270 
271 template <class... Types>
272 struct tuple_size {};
273 
274 template <class... Types>
275 struct tuple_size<smith::tuple<Types...>> : std::integral_constant<std::size_t, sizeof...(Types)> {};
276 
282 template <int i, typename... T>
283 SMITH_HOST_DEVICE constexpr auto& get(tuple<T...>& values)
284 {
285  static_assert(i < sizeof...(T), "");
286  if constexpr (i == 0) {
287  return values.v0;
288  }
289  if constexpr (i == 1) {
290  return values.v1;
291  }
292  if constexpr (i == 2) {
293  return values.v2;
294  }
295  if constexpr (i == 3) {
296  return values.v3;
297  }
298  if constexpr (i == 4) {
299  return values.v4;
300  }
301  if constexpr (i == 5) {
302  return values.v5;
303  }
304  if constexpr (i == 6) {
305  return values.v6;
306  }
307  if constexpr (i == 7) {
308  return values.v7;
309  }
310  if constexpr (i == 8) {
311  return values.v8;
312  }
313  if constexpr (i == 9) {
314  return values.v9;
315  }
316  if constexpr (i == 10) {
317  return values.v10;
318  }
319 }
320 
326 template <int i, typename... T>
327 SMITH_HOST_DEVICE constexpr const auto& get(const tuple<T...>& values)
328 {
329  static_assert(i < sizeof...(T), "");
330  if constexpr (i == 0) {
331  return values.v0;
332  }
333  if constexpr (i == 1) {
334  return values.v1;
335  }
336  if constexpr (i == 2) {
337  return values.v2;
338  }
339  if constexpr (i == 3) {
340  return values.v3;
341  }
342  if constexpr (i == 4) {
343  return values.v4;
344  }
345  if constexpr (i == 5) {
346  return values.v5;
347  }
348  if constexpr (i == 6) {
349  return values.v6;
350  }
351  if constexpr (i == 7) {
352  return values.v7;
353  }
354  if constexpr (i == 8) {
355  return values.v8;
356  }
357  if constexpr (i == 9) {
358  return values.v9;
359  }
360  if constexpr (i == 10) {
361  return values.v10;
362  }
363 }
364 
375 template <int i, typename... T>
376 SMITH_HOST_DEVICE constexpr auto type(const tuple<T...>& values)
377 {
378  static_assert(i < sizeof...(T), "");
379  if constexpr (i == 0) {
380  return values.v0;
381  }
382  if constexpr (i == 1) {
383  return values.v1;
384  }
385  if constexpr (i == 2) {
386  return values.v2;
387  }
388  if constexpr (i == 3) {
389  return values.v3;
390  }
391  if constexpr (i == 4) {
392  return values.v4;
393  }
394  if constexpr (i == 5) {
395  return values.v5;
396  }
397  if constexpr (i == 6) {
398  return values.v6;
399  }
400  if constexpr (i == 7) {
401  return values.v7;
402  }
403  if constexpr (i == 8) {
404  return values.v8;
405  }
406  if constexpr (i == 9) {
407  return values.v9;
408  }
409  if constexpr (i == 10) {
410  return values.v10;
411  }
412 }
413 
424 template <typename... S, typename... T, int... i>
425 SMITH_HOST_DEVICE constexpr auto plus_helper(const tuple<S...>& x, const tuple<T...>& y,
426  std::integer_sequence<int, i...>)
427 {
428  return tuple{get<i>(x) + get<i>(y)...};
429 }
430 
438 template <typename... S, typename... T>
439 SMITH_HOST_DEVICE constexpr auto operator+(const tuple<S...>& x, const tuple<T...>& y)
440 {
441  static_assert(sizeof...(S) == sizeof...(T));
442  return plus_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
443 }
444 
453 template <typename... T, int... i>
455  std::integer_sequence<int, i...>)
456 {
457  ((get<i>(x) += get<i>(y)), ...);
458 }
459 
466 template <typename... T>
468 {
469  return plus_equals_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
470 }
471 
480 template <typename... T, int... i>
482  std::integer_sequence<int, i...>)
483 {
484  ((get<i>(x) -= get<i>(y)), ...);
485 }
486 
493 template <typename... T>
495 {
496  return minus_equals_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
497 }
498 
509 template <typename... S, typename... T, int... i>
510 SMITH_HOST_DEVICE constexpr auto minus_helper(const tuple<S...>& x, const tuple<T...>& y,
511  std::integer_sequence<int, i...>)
512 {
513  return tuple{get<i>(x) - get<i>(y)...};
514 }
515 
523 template <typename... S, typename... T>
524 SMITH_HOST_DEVICE constexpr auto operator-(const tuple<S...>& x, const tuple<T...>& y)
525 {
526  static_assert(sizeof...(S) == sizeof...(T));
527  return minus_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
528 }
529 
538 template <typename... T, int... i>
539 SMITH_HOST_DEVICE constexpr auto unary_minus_helper(const tuple<T...>& x, std::integer_sequence<int, i...>)
540 {
541  return tuple{-get<i>(x)...};
542 }
543 
549 template <typename... T>
550 SMITH_HOST_DEVICE constexpr auto operator-(const tuple<T...>& x)
551 {
552  return unary_minus_helper(x, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
553 }
554 
565 template <typename... S, typename... T, int... i>
566 SMITH_HOST_DEVICE constexpr auto div_helper(const tuple<S...>& x, const tuple<T...>& y,
567  std::integer_sequence<int, i...>)
568 {
569  return tuple{get<i>(x) / get<i>(y)...};
570 }
571 
579 template <typename... S, typename... T>
580 SMITH_HOST_DEVICE constexpr auto operator/(const tuple<S...>& x, const tuple<T...>& y)
581 {
582  static_assert(sizeof...(S) == sizeof...(T));
583  return div_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
584 }
585 
595 template <typename... T, int... i>
596 SMITH_HOST_DEVICE constexpr auto div_helper(const double a, const tuple<T...>& x, std::integer_sequence<int, i...>)
597 {
598  return tuple{a / get<i>(x)...};
599 }
600 
610 template <typename... T, int... i>
611 SMITH_HOST_DEVICE constexpr auto div_helper(const tuple<T...>& x, const double a, std::integer_sequence<int, i...>)
612 {
613  return tuple{get<i>(x) / a...};
614 }
615 
622 template <typename... T>
623 SMITH_HOST_DEVICE constexpr auto operator/(const double a, const tuple<T...>& x)
624 {
625  return div_helper(a, x, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
626 }
627 
634 template <typename... T>
635 SMITH_HOST_DEVICE constexpr auto operator/(const tuple<T...>& x, const double a)
636 {
637  return div_helper(x, a, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
638 }
639 
650 template <typename... S, typename... T, int... i>
651 SMITH_HOST_DEVICE constexpr auto mult_helper(const tuple<S...>& x, const tuple<T...>& y,
652  std::integer_sequence<int, i...>)
653 {
654  return tuple{get<i>(x) * get<i>(y)...};
655 }
656 
664 template <typename... S, typename... T>
665 SMITH_HOST_DEVICE constexpr auto operator*(const tuple<S...>& x, const tuple<T...>& y)
666 {
667  static_assert(sizeof...(S) == sizeof...(T));
668  return mult_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
669 }
670 
680 template <typename... T, int... i>
681 SMITH_HOST_DEVICE constexpr auto mult_helper(const double a, const tuple<T...>& x, std::integer_sequence<int, i...>)
682 {
683  return tuple{a * get<i>(x)...};
684 }
685 
695 template <typename... T, int... i>
696 SMITH_HOST_DEVICE constexpr auto mult_helper(const tuple<T...>& x, const double a, std::integer_sequence<int, i...>)
697 {
698  return tuple{get<i>(x) * a...};
699 }
700 
707 template <typename... T>
708 SMITH_HOST_DEVICE constexpr auto operator*(const double a, const tuple<T...>& x)
709 {
710  return mult_helper(a, x, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
711 }
712 
719 template <typename... T>
720 SMITH_HOST_DEVICE constexpr auto operator*(const tuple<T...>& x, const double a)
721 {
722  return mult_helper(x, a, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
723 }
724 
732 template <typename... T, std::size_t... i>
733 auto& print_helper(std::ostream& out, const smith::tuple<T...>& A, std::integer_sequence<size_t, i...>)
734 {
735  out << "tuple{";
736  (..., (out << (i == 0 ? "" : ", ") << smith::get<i>(A)));
737  out << "}";
738  return out;
739 }
740 
747 template <typename... T>
748 auto& operator<<(std::ostream& out, const smith::tuple<T...>& A)
749 {
750  return print_helper(out, A, std::make_integer_sequence<size_t, sizeof...(T)>());
751 }
752 
763 template <typename lambda, typename... T, int... i>
764 SMITH_HOST_DEVICE auto apply_helper(lambda f, tuple<T...>& args, std::integer_sequence<int, i...>)
765 {
766  return f(get<i>(args)...);
767 }
768 
778 template <typename lambda, typename... T>
779 SMITH_HOST_DEVICE auto apply(lambda f, tuple<T...>& args)
780 {
781  return apply_helper(f, std::move(args), std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
782 }
783 
787 template <typename lambda, typename... T, int... i>
788 SMITH_HOST_DEVICE auto apply_helper(lambda f, const tuple<T...>& args, std::integer_sequence<int, i...>)
789 {
790  return f(get<i>(args)...);
791 }
792 
802 template <typename lambda, typename... T>
803 SMITH_HOST_DEVICE auto apply(lambda f, const tuple<T...>& args)
804 {
805  return apply_helper(f, std::move(args), std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
806 }
807 
816 template <size_t I, class T>
818 
819 // recursive case
821 template <size_t I, class Head, class... Tail>
822 struct tuple_element<I, tuple<Head, Tail...>> : tuple_element<I - 1, tuple<Tail...>> {};
823 
824 // base case
826 template <class Head, class... Tail>
827 struct tuple_element<0, tuple<Head, Tail...>> {
828  using type = Head;
829 };
830 
834 template <typename T>
835 struct is_tuple : std::false_type {};
836 
838 template <typename... T>
839 struct is_tuple<smith::tuple<T...>> : std::true_type {};
840 
844 template <typename T>
845 struct is_tuple_of_tuples : std::false_type {};
846 
850 template <typename... T>
852  static constexpr bool value = (is_tuple<T>::value && ...);
853 };
854 
855 } // namespace smith
856 
857 #include "smith/numerics/functional/tuple_tensor_dual_functions.hpp"
This file contains the interface used for initializing/terminating any hardware accelerator-related f...
#define SMITH_HOST_DEVICE
Macro that evaluates to __host__ __device__ when compiling with nvcc or amdclang and does nothing on ...
Definition: accelerator.hpp:37
Accelerator functionality.
Definition: smith.cpp:36
constexpr SMITH_HOST_DEVICE void plus_equals_helper(tuple< T... > &x, const tuple< T... > &y, std::integer_sequence< int, i... >)
A helper function for the += operator of tuples.
Definition: tuple.hpp:454
tuple(T...) -> tuple< T... >
Class template argument deduction rule for tuples.
constexpr SMITH_HOST_DEVICE auto & operator+=(dual< gradient_type > &a, const dual< gradient_type > &b)
compound assignment (+) for dual numbers
Definition: dual.hpp:182
SMITH_HOST_DEVICE auto apply(lambda f, tuple< T... > &args)
a way of passing an n-tuple to a function that expects n separate arguments
Definition: tuple.hpp:779
constexpr T & get(variant< T0, T1 > &v)
Returns the variant member of specified type.
Definition: variant.hpp:338
constexpr SMITH_HOST_DEVICE auto minus_helper(const tuple< S... > &x, const tuple< T... > &y, std::integer_sequence< int, i... >)
A helper function for the - operator of tuples.
Definition: tuple.hpp:510
FieldStateWeightedSum operator+(const FieldState &x, const FieldState &y)
add two FieldState
constexpr SMITH_HOST_DEVICE auto unary_minus_helper(const tuple< T... > &x, std::integer_sequence< int, i... >)
A helper function for the - operator of tuples.
Definition: tuple.hpp:539
SMITH_HOST_DEVICE auto apply_helper(lambda f, tuple< T... > &args, std::integer_sequence< int, i... >)
A helper to apply a lambda to a tuple.
Definition: tuple.hpp:764
std::ostream & operator<<(std::ostream &out, DoF dof)
stream output for DoF
constexpr SMITH_HOST_DEVICE auto type(const tuple< T... > &values)
a function intended to be used for extracting the ith type from a tuple.
Definition: tuple.hpp:376
constexpr SMITH_HOST_DEVICE auto mult_helper(const tuple< S... > &x, const tuple< T... > &y, std::integer_sequence< int, i... >)
A helper function for the * operator of tuples.
Definition: tuple.hpp:651
constexpr SMITH_HOST_DEVICE auto div_helper(const tuple< S... > &x, const tuple< T... > &y, std::integer_sequence< int, i... >)
A helper function for the / operator of tuples.
Definition: tuple.hpp:566
constexpr SMITH_HOST_DEVICE auto plus_helper(const tuple< S... > &x, const tuple< T... > &y, std::integer_sequence< int, i... >)
A helper function for the + operator of tuples.
Definition: tuple.hpp:425
constexpr SMITH_HOST_DEVICE void minus_equals_helper(tuple< T... > &x, const tuple< T... > &y, std::integer_sequence< int, i... >)
A helper function for the -= operator of tuples.
Definition: tuple.hpp:481
SMITH_HOST_DEVICE tuple< T... > make_tuple(const T &... args)
helper function for combining a list of values into a tuple
Definition: tuple.hpp:266
auto & print_helper(std::ostream &out, const smith::tuple< T... > &A, std::integer_sequence< size_t, i... >)
helper used to implement printing a tuple of values
Definition: tuple.hpp:733
FieldStateWeightedSum operator*(double a, const FieldState &b)
multiply scalar by a FieldState to get a temporary FieldStateWeightedSum which can cast back to a Fie...
constexpr SMITH_HOST_DEVICE auto & operator-=(dual< gradient_type > &a, const dual< gradient_type > &b)
compound assignment (-) for dual numbers
Definition: dual.hpp:191
FieldStateWeightedSum operator-(const FieldState &x, const FieldState &y)
subtract two FieldState
constexpr SMITH_HOST_DEVICE auto operator/(const dual< gradient_type > &a, double b)
division of a dual number by a non-dual number
Definition: dual.hpp:129
Trait for checking if a type if a smith::tuple containing only smith::tuple.
Definition: tuple.hpp:845
Trait for checking if a type is a smith::tuple.
Definition: tuple.hpp:835
T10 v10
The eleventh member of the tuple.
Definition: tuple.hpp:250
T7 v7
The eighth member of the tuple.
Definition: tuple.hpp:217
T6 v6
The seventh member of the tuple.
Definition: tuple.hpp:216
T1 v1
The second member of the tuple.
Definition: tuple.hpp:211
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:213
T1 v1
The second member of the tuple.
Definition: tuple.hpp:183
T7 v7
The eighth member of the tuple.
Definition: tuple.hpp:189
T5 v5
The sixth member of the tuple.
Definition: tuple.hpp:187
T6 v6
The seventh member of the tuple.
Definition: tuple.hpp:188
T0 v0
The first member of the tuple.
Definition: tuple.hpp:182
T2 v2
The third member of the tuple.
Definition: tuple.hpp:184
T8 v8
The ninth member of the tuple.
Definition: tuple.hpp:190
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:185
T4 v4
The fifth member of the tuple.
Definition: tuple.hpp:186
T4 v4
The fifth member of the tuple.
Definition: tuple.hpp:160
T6 v6
The seventh member of the tuple.
Definition: tuple.hpp:162
T0 v0
The first member of the tuple.
Definition: tuple.hpp:156
T2 v2
The third member of the tuple.
Definition: tuple.hpp:158
T7 v7
The eighth member of the tuple.
Definition: tuple.hpp:163
T1 v1
The second member of the tuple.
Definition: tuple.hpp:157
T5 v5
The sixth member of the tuple.
Definition: tuple.hpp:161
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:159
T6 v6
The seventh member of the tuple.
Definition: tuple.hpp:139
T4 v4
The fifth member of the tuple.
Definition: tuple.hpp:137
T5 v5
The sixth member of the tuple.
Definition: tuple.hpp:138
T2 v2
The third member of the tuple.
Definition: tuple.hpp:135
T0 v0
The first member of the tuple.
Definition: tuple.hpp:133
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:136
T1 v1
The second member of the tuple.
Definition: tuple.hpp:134
T2 v2
The third member of the tuple.
Definition: tuple.hpp:114
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:115
T1 v1
The second member of the tuple.
Definition: tuple.hpp:113
T5 v5
The sixth member of the tuple.
Definition: tuple.hpp:117
T0 v0
The first member of the tuple.
Definition: tuple.hpp:112
T4 v4
The fifth member of the tuple.
Definition: tuple.hpp:116
T0 v0
The first member of the tuple.
Definition: tuple.hpp:93
T2 v2
The third member of the tuple.
Definition: tuple.hpp:95
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:96
T1 v1
The second member of the tuple.
Definition: tuple.hpp:94
T4 v4
The fifth member of the tuple.
Definition: tuple.hpp:97
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:79
T0 v0
The first member of the tuple.
Definition: tuple.hpp:76
T1 v1
The second member of the tuple.
Definition: tuple.hpp:77
T2 v2
The third member of the tuple.
Definition: tuple.hpp:78
T2 v2
The third member of the tuple.
Definition: tuple.hpp:63
T1 v1
The second member of the tuple.
Definition: tuple.hpp:62
T0 v0
The first member of the tuple.
Definition: tuple.hpp:61
T1 v1
The second member of the tuple.
Definition: tuple.hpp:49
T0 v0
The first member of the tuple.
Definition: tuple.hpp:48
T0 v0
The first member of the tuple.
Definition: tuple.hpp:37
Head type
the type at the specified index
Definition: tuple.hpp:828
a struct used to determine the type at index I of a tuple
Definition: tuple.hpp:817
This is a class that mimics most of std::tuple's interface, except that it is usable in CUDA kernels ...
Definition: tuple.hpp:28