Serac  0.1
Serac is an implicit thermal strucural mechanics simulation code.
tuple.hpp
Go to the documentation of this file.
1 // Copyright (c) Lawrence Livermore National Security, LLC and
2 // other Serac 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 serac {
19 
27 template <typename... T>
28 struct tuple {
29 };
30 
36 template <typename T0>
37 struct tuple<T0> {
38  T0 v0;
39 };
40 
47 template <typename T0, typename T1>
48 struct tuple<T0, T1> {
49  T0 v0;
50  T1 v1;
51 };
52 
60 template <typename T0, typename T1, typename T2>
61 struct tuple<T0, T1, T2> {
62  T0 v0;
63  T1 v1;
64  T2 v2;
65 };
66 
75 template <typename T0, typename T1, typename T2, typename T3>
76 struct tuple<T0, T1, T2, T3> {
77  T0 v0;
78  T1 v1;
79  T2 v2;
80  T3 v3;
81 };
82 
92 template <typename T0, typename T1, typename T2, typename T3, typename T4>
93 struct tuple<T0, T1, T2, T3, T4> {
94  T0 v0;
95  T1 v1;
96  T2 v2;
97  T3 v3;
98  T4 v4;
99 };
100 
111 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
112 struct tuple<T0, T1, T2, T3, T4, T5> {
113  T0 v0;
114  T1 v1;
115  T2 v2;
116  T3 v3;
117  T4 v4;
118  T5 v5;
119 };
120 
132 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
133 struct tuple<T0, T1, T2, T3, T4, T5, T6> {
134  T0 v0;
135  T1 v1;
136  T2 v2;
137  T3 v3;
138  T4 v4;
139  T5 v5;
140  T6 v6;
141 };
142 
155 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
156 struct tuple<T0, T1, T2, T3, T4, T5, T6, T7> {
157  T0 v0;
158  T1 v1;
159  T2 v2;
160  T3 v3;
161  T4 v4;
162  T5 v5;
163  T6 v6;
164  T7 v7;
165 };
166 
180 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
181  typename T8>
182 struct tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> {
183  T0 v0;
184  T1 v1;
185  T2 v2;
186  T3 v3;
187  T4 v4;
188  T5 v5;
189  T6 v6;
190  T7 v7;
191  T8 v8;
192 };
193 
208 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
209  typename T8, typename T9>
210 struct tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> {
211  T0 v0;
212  T1 v1;
213  T2 v2;
214  T3 v3;
215  T4 v4;
216  T5 v5;
217  T6 v6;
218  T7 v7;
219  T8 v8;
220  T9 v9;
221 };
222 
238 template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7,
239  typename T8, typename T9, typename T10>
240 struct tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> {
241  T0 v0;
242  T1 v1;
243  T2 v2;
244  T3 v3;
245  T4 v4;
246  T5 v5;
247  T6 v6;
248  T7 v7;
249  T8 v8;
250  T9 v9;
251  T10 v10;
252 };
253 
258 template <typename... T>
259 tuple(T...) -> tuple<T...>;
260 
266 template <typename... T>
267 SERAC_HOST_DEVICE tuple<T...> make_tuple(const T&... args)
268 {
269  return tuple<T...>{args...};
270 }
271 
272 template <class... Types>
273 struct tuple_size {
274 };
275 
276 template <class... Types>
277 struct tuple_size<serac::tuple<Types...>> : std::integral_constant<std::size_t, sizeof...(Types)> {
278 };
279 
285 template <int i, typename... T>
286 SERAC_HOST_DEVICE constexpr auto& get(tuple<T...>& values)
287 {
288  static_assert(i < sizeof...(T), "");
289  if constexpr (i == 0) {
290  return values.v0;
291  }
292  if constexpr (i == 1) {
293  return values.v1;
294  }
295  if constexpr (i == 2) {
296  return values.v2;
297  }
298  if constexpr (i == 3) {
299  return values.v3;
300  }
301  if constexpr (i == 4) {
302  return values.v4;
303  }
304  if constexpr (i == 5) {
305  return values.v5;
306  }
307  if constexpr (i == 6) {
308  return values.v6;
309  }
310  if constexpr (i == 7) {
311  return values.v7;
312  }
313  if constexpr (i == 8) {
314  return values.v8;
315  }
316  if constexpr (i == 9) {
317  return values.v9;
318  }
319  if constexpr (i == 10) {
320  return values.v10;
321  }
322 }
323 
329 template <int i, typename... T>
330 SERAC_HOST_DEVICE constexpr const auto& get(const tuple<T...>& values)
331 {
332  static_assert(i < sizeof...(T), "");
333  if constexpr (i == 0) {
334  return values.v0;
335  }
336  if constexpr (i == 1) {
337  return values.v1;
338  }
339  if constexpr (i == 2) {
340  return values.v2;
341  }
342  if constexpr (i == 3) {
343  return values.v3;
344  }
345  if constexpr (i == 4) {
346  return values.v4;
347  }
348  if constexpr (i == 5) {
349  return values.v5;
350  }
351  if constexpr (i == 6) {
352  return values.v6;
353  }
354  if constexpr (i == 7) {
355  return values.v7;
356  }
357  if constexpr (i == 8) {
358  return values.v8;
359  }
360  if constexpr (i == 9) {
361  return values.v9;
362  }
363  if constexpr (i == 10) {
364  return values.v10;
365  }
366 }
367 
378 template <int i, typename... T>
379 SERAC_HOST_DEVICE constexpr auto type(const tuple<T...>& values)
380 {
381  static_assert(i < sizeof...(T), "");
382  if constexpr (i == 0) {
383  return values.v0;
384  }
385  if constexpr (i == 1) {
386  return values.v1;
387  }
388  if constexpr (i == 2) {
389  return values.v2;
390  }
391  if constexpr (i == 3) {
392  return values.v3;
393  }
394  if constexpr (i == 4) {
395  return values.v4;
396  }
397  if constexpr (i == 5) {
398  return values.v5;
399  }
400  if constexpr (i == 6) {
401  return values.v6;
402  }
403  if constexpr (i == 7) {
404  return values.v7;
405  }
406  if constexpr (i == 8) {
407  return values.v8;
408  }
409  if constexpr (i == 9) {
410  return values.v9;
411  }
412  if constexpr (i == 10) {
413  return values.v10;
414  }
415 }
416 
427 template <typename... S, typename... T, int... i>
428 SERAC_HOST_DEVICE constexpr auto plus_helper(const tuple<S...>& x, const tuple<T...>& y,
429  std::integer_sequence<int, i...>)
430 {
431  return tuple{get<i>(x) + get<i>(y)...};
432 }
433 
441 template <typename... S, typename... T>
442 SERAC_HOST_DEVICE constexpr auto operator+(const tuple<S...>& x, const tuple<T...>& y)
443 {
444  static_assert(sizeof...(S) == sizeof...(T));
445  return plus_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
446 }
447 
456 template <typename... T, int... i>
458  std::integer_sequence<int, i...>)
459 {
460  ((get<i>(x) += get<i>(y)), ...);
461 }
462 
469 template <typename... T>
471 {
472  return plus_equals_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
473 }
474 
483 template <typename... T, int... i>
485  std::integer_sequence<int, i...>)
486 {
487  ((get<i>(x) -= get<i>(y)), ...);
488 }
489 
496 template <typename... T>
498 {
499  return minus_equals_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
500 }
501 
512 template <typename... S, typename... T, int... i>
513 SERAC_HOST_DEVICE constexpr auto minus_helper(const tuple<S...>& x, const tuple<T...>& y,
514  std::integer_sequence<int, i...>)
515 {
516  return tuple{get<i>(x) - get<i>(y)...};
517 }
518 
526 template <typename... S, typename... T>
527 SERAC_HOST_DEVICE constexpr auto operator-(const tuple<S...>& x, const tuple<T...>& y)
528 {
529  static_assert(sizeof...(S) == sizeof...(T));
530  return minus_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
531 }
532 
541 template <typename... T, int... i>
542 SERAC_HOST_DEVICE constexpr auto unary_minus_helper(const tuple<T...>& x, std::integer_sequence<int, i...>)
543 {
544  return tuple{-get<i>(x)...};
545 }
546 
552 template <typename... T>
553 SERAC_HOST_DEVICE constexpr auto operator-(const tuple<T...>& x)
554 {
555  return unary_minus_helper(x, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
556 }
557 
568 template <typename... S, typename... T, int... i>
569 SERAC_HOST_DEVICE constexpr auto div_helper(const tuple<S...>& x, const tuple<T...>& y,
570  std::integer_sequence<int, i...>)
571 {
572  return tuple{get<i>(x) / get<i>(y)...};
573 }
574 
582 template <typename... S, typename... T>
583 SERAC_HOST_DEVICE constexpr auto operator/(const tuple<S...>& x, const tuple<T...>& y)
584 {
585  static_assert(sizeof...(S) == sizeof...(T));
586  return div_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
587 }
588 
598 template <typename... T, int... i>
599 SERAC_HOST_DEVICE constexpr auto div_helper(const double a, const tuple<T...>& x, std::integer_sequence<int, i...>)
600 {
601  return tuple{a / get<i>(x)...};
602 }
603 
613 template <typename... T, int... i>
614 SERAC_HOST_DEVICE constexpr auto div_helper(const tuple<T...>& x, const double a, std::integer_sequence<int, i...>)
615 {
616  return tuple{get<i>(x) / a...};
617 }
618 
625 template <typename... T>
626 SERAC_HOST_DEVICE constexpr auto operator/(const double a, const tuple<T...>& x)
627 {
628  return div_helper(a, x, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
629 }
630 
637 template <typename... T>
638 SERAC_HOST_DEVICE constexpr auto operator/(const tuple<T...>& x, const double a)
639 {
640  return div_helper(x, a, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
641 }
642 
653 template <typename... S, typename... T, int... i>
654 SERAC_HOST_DEVICE constexpr auto mult_helper(const tuple<S...>& x, const tuple<T...>& y,
655  std::integer_sequence<int, i...>)
656 {
657  return tuple{get<i>(x) * get<i>(y)...};
658 }
659 
667 template <typename... S, typename... T>
668 SERAC_HOST_DEVICE constexpr auto operator*(const tuple<S...>& x, const tuple<T...>& y)
669 {
670  static_assert(sizeof...(S) == sizeof...(T));
671  return mult_helper(x, y, std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
672 }
673 
683 template <typename... T, int... i>
684 SERAC_HOST_DEVICE constexpr auto mult_helper(const double a, const tuple<T...>& x, std::integer_sequence<int, i...>)
685 {
686  return tuple{a * get<i>(x)...};
687 }
688 
698 template <typename... T, int... i>
699 SERAC_HOST_DEVICE constexpr auto mult_helper(const tuple<T...>& x, const double a, std::integer_sequence<int, i...>)
700 {
701  return tuple{get<i>(x) * a...};
702 }
703 
710 template <typename... T>
711 SERAC_HOST_DEVICE constexpr auto operator*(const double a, const tuple<T...>& x)
712 {
713  return mult_helper(a, x, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
714 }
715 
722 template <typename... T>
723 SERAC_HOST_DEVICE constexpr auto operator*(const tuple<T...>& x, const double a)
724 {
725  return mult_helper(x, a, std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
726 }
727 
735 template <typename... T, std::size_t... i>
736 auto& print_helper(std::ostream& out, const serac::tuple<T...>& A, std::integer_sequence<size_t, i...>)
737 {
738  out << "tuple{";
739  (..., (out << (i == 0 ? "" : ", ") << serac::get<i>(A)));
740  out << "}";
741  return out;
742 }
743 
750 template <typename... T>
751 auto& operator<<(std::ostream& out, const serac::tuple<T...>& A)
752 {
753  return print_helper(out, A, std::make_integer_sequence<size_t, sizeof...(T)>());
754 }
755 
766 template <typename lambda, typename... T, int... i>
767 SERAC_HOST_DEVICE auto apply_helper(lambda f, tuple<T...>& args, std::integer_sequence<int, i...>)
768 {
769  return f(get<i>(args)...);
770 }
771 
781 template <typename lambda, typename... T>
782 SERAC_HOST_DEVICE auto apply(lambda f, tuple<T...>& args)
783 {
784  return apply_helper(f, std::move(args), std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
785 }
786 
790 template <typename lambda, typename... T, int... i>
791 SERAC_HOST_DEVICE auto apply_helper(lambda f, const tuple<T...>& args, std::integer_sequence<int, i...>)
792 {
793  return f(get<i>(args)...);
794 }
795 
805 template <typename lambda, typename... T>
806 SERAC_HOST_DEVICE auto apply(lambda f, const tuple<T...>& args)
807 {
808  return apply_helper(f, std::move(args), std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
809 }
810 
819 template <size_t I, class T>
821 
822 // recursive case
824 template <size_t I, class Head, class... Tail>
825 struct tuple_element<I, tuple<Head, Tail...>> : tuple_element<I - 1, tuple<Tail...>> {
826 };
827 
828 // base case
830 template <class Head, class... Tail>
831 struct tuple_element<0, tuple<Head, Tail...>> {
832  using type = Head;
833 };
834 
838 template <typename T>
839 struct is_tuple : std::false_type {
840 };
841 
843 template <typename... T>
844 struct is_tuple<serac::tuple<T...>> : std::true_type {
845 };
846 
850 template <typename T>
851 struct is_tuple_of_tuples : std::false_type {
852 };
853 
857 template <typename... T>
859  static constexpr bool value = (is_tuple<T>::value && ...);
860 };
861 
862 } // namespace serac
863 
864 #include "serac/numerics/functional/tuple_tensor_dual_functions.hpp"
This file contains the interface used for initializing/terminating any hardware accelerator-related f...
#define SERAC_HOST_DEVICE
Macro that evaluates to __host__ __device__ when compiling with nvcc and does nothing on a host compi...
Definition: accelerator.hpp:38
Accelerator functionality.
Definition: serac.cpp:36
SERAC_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:782
constexpr SERAC_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:428
constexpr SERAC_HOST_DEVICE auto operator*(const dual< gradient_type > &a, double b)
multiplication of a dual number and a non-dual number
Definition: dual.hpp:108
Domain operator-(const Domain &a, const Domain &b)
create a new domain that is the set difference of a and b
Definition: domain.cpp:761
constexpr T & get(variant< T0, T1 > &v)
Returns the variant member of specified type.
Definition: variant.hpp:338
constexpr SERAC_HOST_DEVICE auto operator+(dual< gradient_type > a, double b)
addition of a dual number and a non-dual number
Definition: dual.hpp:59
constexpr SERAC_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:457
auto & print_helper(std::ostream &out, const serac::tuple< T... > &A, std::integer_sequence< size_t, i... >)
helper used to implement printing a tuple of values
Definition: tuple.hpp:736
constexpr SERAC_HOST_DEVICE auto & operator-=(dual< gradient_type > &a, const dual< gradient_type > &b)
compound assignment (-) for dual numbers
Definition: dual.hpp:191
constexpr SERAC_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:542
SERAC_HOST_DEVICE tuple< T... > make_tuple(const T &... args)
helper function for combining a list of values into a tuple
Definition: tuple.hpp:267
constexpr SERAC_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:484
tuple(T...) -> tuple< T... >
Class template argument deduction rule for tuples.
constexpr SERAC_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:379
SERAC_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:767
constexpr SERAC_HOST_DEVICE auto & operator+=(dual< gradient_type > &a, const dual< gradient_type > &b)
compound assignment (+) for dual numbers
Definition: dual.hpp:182
constexpr SERAC_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:569
std::ostream & operator<<(std::ostream &out, DoF dof)
stream output for DoF
constexpr SERAC_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:513
constexpr SERAC_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:654
constexpr SERAC_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 serac::tuple containing only serac::tuple.
Definition: tuple.hpp:851
Trait for checking if a type is a serac::tuple.
Definition: tuple.hpp:839
T10 v10
The eleventh member of the tuple.
Definition: tuple.hpp:251
T6 v6
The seventh member of the tuple.
Definition: tuple.hpp:217
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:214
T1 v1
The second member of the tuple.
Definition: tuple.hpp:212
T7 v7
The eighth member of the tuple.
Definition: tuple.hpp:218
T8 v8
The ninth member of the tuple.
Definition: tuple.hpp:191
T4 v4
The fifth member of the tuple.
Definition: tuple.hpp:187
T0 v0
The first member of the tuple.
Definition: tuple.hpp:183
T7 v7
The eighth member of the tuple.
Definition: tuple.hpp:190
T6 v6
The seventh member of the tuple.
Definition: tuple.hpp:189
T2 v2
The third member of the tuple.
Definition: tuple.hpp:185
T1 v1
The second member of the tuple.
Definition: tuple.hpp:184
T5 v5
The sixth member of the tuple.
Definition: tuple.hpp:188
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:186
T2 v2
The third member of the tuple.
Definition: tuple.hpp:159
T4 v4
The fifth member of the tuple.
Definition: tuple.hpp:161
T7 v7
The eighth member of the tuple.
Definition: tuple.hpp:164
T0 v0
The first member of the tuple.
Definition: tuple.hpp:157
T1 v1
The second member of the tuple.
Definition: tuple.hpp:158
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:160
T5 v5
The sixth member of the tuple.
Definition: tuple.hpp:162
T6 v6
The seventh member of the tuple.
Definition: tuple.hpp:163
T0 v0
The first member of the tuple.
Definition: tuple.hpp:134
T1 v1
The second member of the tuple.
Definition: tuple.hpp:135
T5 v5
The sixth member of the tuple.
Definition: tuple.hpp:139
T4 v4
The fifth member of the tuple.
Definition: tuple.hpp:138
T2 v2
The third member of the tuple.
Definition: tuple.hpp:136
T6 v6
The seventh member of the tuple.
Definition: tuple.hpp:140
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:137
T1 v1
The second member of the tuple.
Definition: tuple.hpp:114
T4 v4
The fifth member of the tuple.
Definition: tuple.hpp:117
T0 v0
The first member of the tuple.
Definition: tuple.hpp:113
T2 v2
The third member of the tuple.
Definition: tuple.hpp:115
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:116
T5 v5
The sixth member of the tuple.
Definition: tuple.hpp:118
T2 v2
The third member of the tuple.
Definition: tuple.hpp:96
T4 v4
The fifth member of the tuple.
Definition: tuple.hpp:98
T1 v1
The second member of the tuple.
Definition: tuple.hpp:95
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:97
T0 v0
The first member of the tuple.
Definition: tuple.hpp:94
T3 v3
The fourth member of the tuple.
Definition: tuple.hpp:80
T2 v2
The third member of the tuple.
Definition: tuple.hpp:79
T0 v0
The first member of the tuple.
Definition: tuple.hpp:77
T1 v1
The second member of the tuple.
Definition: tuple.hpp:78
T2 v2
The third member of the tuple.
Definition: tuple.hpp:64
T1 v1
The second member of the tuple.
Definition: tuple.hpp:63
T0 v0
The first member of the tuple.
Definition: tuple.hpp:62
T1 v1
The second member of the tuple.
Definition: tuple.hpp:50
T0 v0
The first member of the tuple.
Definition: tuple.hpp:49
T0 v0
The first member of the tuple.
Definition: tuple.hpp:38
Head type
the type at the specified index
Definition: tuple.hpp:832
a struct used to determine the type at index I of a tuple
Definition: tuple.hpp:820
This is a class that mimics most of std::tuple's interface, except that it is usable in CUDA kernels ...
Definition: tuple.hpp:28