MFEM v4.9.0
Finite element discretization library
Loading...
Searching...
No Matches
tuple.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11#pragma once
12
13// This is serac's tuple implementation
14
15#include <ostream>
17#include <utility>
18
19// Define a portable unreachable macro
20#if defined(__GNUC__) || defined(__clang__)
21#if defined(__CUDACC_VER_MAJOR__)
22#if __CUDACC_VER_MAJOR__ <= 11 && __CUDACC_VER_MINOR__ < 3
23// nvcc didn't add __builtin_unreachable() until cuda 11.3
24#define MFEM_UNREACHABLE()
25#else
26// nvcc >= 11.3
27#define MFEM_UNREACHABLE() __builtin_unreachable()
28#endif
29#else
30// host-only version
31#define MFEM_UNREACHABLE() __builtin_unreachable()
32#endif
33#elif defined(_MSC_VER)
34#define MFEM_UNREACHABLE() __assume(0)
35#endif
36
37namespace mfem::future
38{
39
40/**
41 * @tparam T the types stored in the tuple
42 * @brief This is a class that mimics most of std::tuple's interface,
43 * except that it is usable in CUDA kernels and admits some arithmetic operator overloads.
44 *
45 * see https://en.cppreference.com/w/cpp/utility/tuple for more information about std::tuple
46 */
47template <typename... T>
48struct tuple
49{
50};
51
52/**
53 * @brief Type that mimics std::tuple
54 *
55 * @tparam T0 The first type stored in the tuple
56 */
57template <typename T0>
58struct tuple<T0>
59{
60 T0 v0; ///< The first member of the tuple
61};
62
63/**
64 * @brief Type that mimics std::tuple
65 *
66 * @tparam T0 The first type stored in the tuple
67 * @tparam T1 The second type stored in the tuple
68 */
69template <typename T0, typename T1>
70struct tuple<T0, T1>
71{
72 T0 v0; ///< The first member of the tuple
73 T1 v1; ///< The second member of the tuple
74};
75
76/**
77 * @brief Type that mimics std::tuple
78 *
79 * @tparam T0 The first type stored in the tuple
80 * @tparam T1 The second type stored in the tuple
81 * @tparam T2 The third type stored in the tuple
82 */
83template <typename T0, typename T1, typename T2>
84struct tuple<T0, T1, T2>
85{
86 T0 v0; ///< The first member of the tuple
87 T1 v1; ///< The second member of the tuple
88 T2 v2; ///< The third member of the tuple
89};
90
91/**
92 * @brief Type that mimics std::tuple
93 *
94 * @tparam T0 The first type stored in the tuple
95 * @tparam T1 The second type stored in the tuple
96 * @tparam T2 The third type stored in the tuple
97 * @tparam T3 The fourth type stored in the tuple
98 */
99template <typename T0, typename T1, typename T2, typename T3>
100struct tuple<T0, T1, T2, T3>
101{
102 T0 v0; ///< The first member of the tuple
103 T1 v1; ///< The second member of the tuple
104 T2 v2; ///< The third member of the tuple
105 T3 v3; ///< The fourth member of the tuple
106};
107
108/**
109 * @brief Type that mimics std::tuple
110 *
111 * @tparam T0 The first type stored in the tuple
112 * @tparam T1 The second type stored in the tuple
113 * @tparam T2 The third type stored in the tuple
114 * @tparam T3 The fourth type stored in the tuple
115 * @tparam T4 The fifth type stored in the tuple
116 */
117template <typename T0, typename T1, typename T2, typename T3, typename T4>
118struct tuple<T0, T1, T2, T3, T4>
119{
120 T0 v0; ///< The first member of the tuple
121 T1 v1; ///< The second member of the tuple
122 T2 v2; ///< The third member of the tuple
123 T3 v3; ///< The fourth member of the tuple
124 T4 v4; ///< The fifth member of the tuple
125};
126
127/**
128 * @brief Type that mimics std::tuple
129 *
130 * @tparam T0 The first type stored in the tuple
131 * @tparam T1 The second type stored in the tuple
132 * @tparam T2 The third type stored in the tuple
133 * @tparam T3 The fourth type stored in the tuple
134 * @tparam T4 The fifth type stored in the tuple
135 * @tparam T5 The sixth type stored in the tuple
136 */
137template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
138struct tuple<T0, T1, T2, T3, T4, T5>
139{
140 T0 v0; ///< The first member of the tuple
141 T1 v1; ///< The second member of the tuple
142 T2 v2; ///< The third member of the tuple
143 T3 v3; ///< The fourth member of the tuple
144 T4 v4; ///< The fifth member of the tuple
145 T5 v5; ///< The sixth member of the tuple
146};
147
148/**
149 * @brief Type that mimics std::tuple
150 *
151 * @tparam T0 The first type stored in the tuple
152 * @tparam T1 The second type stored in the tuple
153 * @tparam T2 The third type stored in the tuple
154 * @tparam T3 The fourth type stored in the tuple
155 * @tparam T4 The fifth type stored in the tuple
156 * @tparam T5 The sixth type stored in the tuple
157 * @tparam T6 The seventh type stored in the tuple
158 */
159template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
160struct tuple<T0, T1, T2, T3, T4, T5, T6>
161{
162 T0 v0; ///< The first member of the tuple
163 T1 v1; ///< The second member of the tuple
164 T2 v2; ///< The third member of the tuple
165 T3 v3; ///< The fourth member of the tuple
166 T4 v4; ///< The fifth member of the tuple
167 T5 v5; ///< The sixth member of the tuple
168 T6 v6; ///< The seventh member of the tuple
169};
170
171/**
172 * @brief Type that mimics std::tuple
173 *
174 * @tparam T0 The first type stored in the tuple
175 * @tparam T1 The second type stored in the tuple
176 * @tparam T2 The third type stored in the tuple
177 * @tparam T3 The fourth type stored in the tuple
178 * @tparam T4 The fifth type stored in the tuple
179 * @tparam T5 The sixth type stored in the tuple
180 * @tparam T6 The seventh type stored in the tuple
181 * @tparam T7 The eighth type stored in the tuple
182 */
183template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
184struct tuple<T0, T1, T2, T3, T4, T5, T6, T7>
185{
186 T0 v0; ///< The first member of the tuple
187 T1 v1; ///< The second member of the tuple
188 T2 v2; ///< The third member of the tuple
189 T3 v3; ///< The fourth member of the tuple
190 T4 v4; ///< The fifth member of the tuple
191 T5 v5; ///< The sixth member of the tuple
192 T6 v6; ///< The seventh member of the tuple
193 T7 v7; ///< The eighth member of the tuple
194};
195
196template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
197struct tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8>
198{
199 T0 v0; ///< The first member of the tuple
200 T1 v1; ///< The second member of the tuple
201 T2 v2; ///< The third member of the tuple
202 T3 v3; ///< The fourth member of the tuple
203 T4 v4; ///< The fifth member of the tuple
204 T5 v5; ///< The sixth member of the tuple
205 T6 v6; ///< The seventh member of the tuple
206 T7 v7; ///< The eighth member of the tuple
207 T8 v8;
208};
209
210/**
211 * @brief Class template argument deduction rule for tuples
212 * @tparam T The variadic template parameter for tuple types
213 */
214template <typename... T>
215MFEM_HOST_DEVICE
216tuple(T...) -> tuple<T...>;
217
218/**
219 * @brief helper function for combining a list of values into a tuple
220 * @tparam T types of the values to be tuple-d
221 * @param args the actual values to be put into a tuple
222 */
223template <typename... T>
224MFEM_HOST_DEVICE tuple<T...> make_tuple(const T&... args)
225{
226 return tuple<T...> {args...};
227}
228
229template <class... Types>
231{
232};
233
234template <class... Types>
235struct tuple_size<tuple<Types...>> :
236 std::integral_constant<std::size_t, sizeof...(Types)>
237{
238};
239
240/**
241 * @tparam i the tuple index to access
242 * @tparam T the types stored in the tuple
243 * @brief return a reference to the ith tuple entry
244 */
245template <int i, typename... T>
246MFEM_HOST_DEVICE constexpr auto& get(tuple<T...>& values)
247{
248 static_assert(i < sizeof...(T));
249 if constexpr (i == 0)
250 {
251 return values.v0;
252 }
253 if constexpr (i == 1)
254 {
255 return values.v1;
256 }
257 if constexpr (i == 2)
258 {
259 return values.v2;
260 }
261 if constexpr (i == 3)
262 {
263 return values.v3;
264 }
265 if constexpr (i == 4)
266 {
267 return values.v4;
268 }
269 if constexpr (i == 5)
270 {
271 return values.v5;
272 }
273 if constexpr (i == 6)
274 {
275 return values.v6;
276 }
277 if constexpr (i == 7)
278 {
279 return values.v7;
280 }
281 if constexpr (i == 8)
282 {
283 return values.v8;
284 }
285 MFEM_UNREACHABLE();
286}
287
288/**
289 * @tparam i the tuple index to access
290 * @tparam T the types stored in the tuple
291 * @brief return a copy of the ith tuple entry
292 */
293template <int i, typename... T>
294MFEM_HOST_DEVICE constexpr const auto& get(const tuple<T...>& values)
295{
296 static_assert(i < sizeof...(T));
297 if constexpr (i == 0)
298 {
299 return values.v0;
300 }
301 if constexpr (i == 1)
302 {
303 return values.v1;
304 }
305 if constexpr (i == 2)
306 {
307 return values.v2;
308 }
309 if constexpr (i == 3)
310 {
311 return values.v3;
312 }
313 if constexpr (i == 4)
314 {
315 return values.v4;
316 }
317 if constexpr (i == 5)
318 {
319 return values.v5;
320 }
321 if constexpr (i == 6)
322 {
323 return values.v6;
324 }
325 if constexpr (i == 7)
326 {
327 return values.v7;
328 }
329 if constexpr (i == 8)
330 {
331 return values.v8;
332 }
333 MFEM_UNREACHABLE();
334}
335
336/**
337 * @brief a function intended to be used for extracting the ith type from a tuple.
338 *
339 * @note type<i>(my_tuple) returns a value, whereas get<i>(my_tuple) returns a reference
340 *
341 * @tparam i the index of the tuple to query
342 * @tparam T the types stored in the tuple
343 * @param values the tuple of values
344 * @return a copy of the ith entry of the input
345 */
346template <int i, typename... T>
347MFEM_HOST_DEVICE constexpr auto type(const tuple<T...>& values)
348{
349 static_assert(i < sizeof...(T));
350 if constexpr (i == 0)
351 {
352 return values.v0;
353 }
354 if constexpr (i == 1)
355 {
356 return values.v1;
357 }
358 if constexpr (i == 2)
359 {
360 return values.v2;
361 }
362 if constexpr (i == 3)
363 {
364 return values.v3;
365 }
366 if constexpr (i == 4)
367 {
368 return values.v4;
369 }
370 if constexpr (i == 5)
371 {
372 return values.v5;
373 }
374 if constexpr (i == 6)
375 {
376 return values.v6;
377 }
378 if constexpr (i == 7)
379 {
380 return values.v7;
381 }
382 if constexpr (i == 8)
383 {
384 return values.v8;
385 }
386}
387
388/**
389 * @brief A helper function for the + operator of tuples
390 *
391 * @tparam S the types stored in the tuple x
392 * @tparam T the types stored in the tuple y
393 * @tparam i The integer sequence to i
394 * @param x tuple of values
395 * @param y tuple of values
396 * @return the returned tuple sum
397 */
398template <typename... S, typename... T, int... i>
399MFEM_HOST_DEVICE constexpr auto plus_helper(const tuple<S...>& x,
400 const tuple<T...>& y,
401 std::integer_sequence<int, i...>)
402{
403 return tuple{get<i>(x) + get<i>(y)...};
404}
405
406/**
407 * @tparam S the types stored in the tuple x
408 * @tparam T the types stored in the tuple y
409 * @param x a tuple of values
410 * @param y a tuple of values
411 * @brief return a tuple of values defined by elementwise sum of x and y
412 */
413template <typename... S, typename... T>
414MFEM_HOST_DEVICE constexpr auto operator+(const tuple<S...>& x,
415 const tuple<T...>& y)
416{
417 static_assert(sizeof...(S) == sizeof...(T));
418 return plus_helper(x, y,
419 std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
420}
421
422/**
423 * @brief A helper function for the += operator of tuples
424 *
425 * @tparam T the types stored in the tuples x and y
426 * @tparam i integer sequence used to index the tuples
427 * @param x tuple of values to be incremented
428 * @param y tuple of increment values
429 */
430template <typename... T, int... i>
431MFEM_HOST_DEVICE constexpr void plus_equals_helper(tuple<T...>& x,
432 const tuple<T...>& y,
433 std::integer_sequence<int, i...>)
434{
435 ((get<i>(x) += get<i>(y)), ...);
436}
437
438/**
439 * @tparam T the types stored in the tuples x and y
440 * @param x a tuple of values
441 * @param y a tuple of values
442 * @brief add values contained in y, to the tuple x
443 */
444template <typename... T>
445MFEM_HOST_DEVICE constexpr auto operator+=(tuple<T...>& x,
446 const tuple<T...>& y)
447{
448 return plus_equals_helper(x, y,
449 std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
450}
451
452/**
453 * @brief A helper function for the -= operator of tuples
454 *
455 * @tparam T the types stored in the tuples x and y
456 * @tparam i integer sequence used to index the tuples
457 * @param x tuple of values to be subtracted from
458 * @param y tuple of values to subtract from x
459 */
460template <typename... T, int... i>
461MFEM_HOST_DEVICE constexpr void minus_equals_helper(tuple<T...>& x,
462 const tuple<T...>& y,
463 std::integer_sequence<int, i...>)
464{
465 ((get<i>(x) -= get<i>(y)), ...);
466}
467
468/**
469 * @tparam T the types stored in the tuples x and y
470 * @param x a tuple of values
471 * @param y a tuple of values
472 * @brief add values contained in y, to the tuple x
473 */
474template <typename... T>
475MFEM_HOST_DEVICE constexpr auto operator-=(tuple<T...>& x,
476 const tuple<T...>& y)
477{
478 return minus_equals_helper(x, y,
479 std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
480}
481
482/**
483 * @brief A helper function for the - operator of tuples
484 *
485 * @tparam S the types stored in the tuple x
486 * @tparam T the types stored in the tuple y
487 * @tparam i The integer sequence to i
488 * @param x tuple of values
489 * @param y tuple of values
490 * @return the returned tuple difference
491 */
492template <typename... S, typename... T, int... i>
493MFEM_HOST_DEVICE constexpr auto minus_helper(const tuple<S...>& x,
494 const tuple<T...>& y,
495 std::integer_sequence<int, i...>)
496{
497 return tuple{get<i>(x) - get<i>(y)...};
498}
499
500/**
501 * @tparam S the types stored in the tuple x
502 * @tparam T the types stored in the tuple y
503 * @param x a tuple of values
504 * @param y a tuple of values
505 * @brief return a tuple of values defined by elementwise difference of x and y
506 */
507template <typename... S, typename... T>
508MFEM_HOST_DEVICE constexpr auto operator-(const tuple<S...>& x,
509 const tuple<T...>& y)
510{
511 static_assert(sizeof...(S) == sizeof...(T));
512 return minus_helper(x, y,
513 std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
514}
515
516/**
517 * @brief A helper function for the - operator of tuples
518 *
519 * @tparam T the types stored in the tuple y
520 * @tparam i The integer sequence to i
521 * @param x tuple of values
522 * @return the returned tuple difference
523 */
524template <typename... T, int... i>
525MFEM_HOST_DEVICE constexpr auto unary_minus_helper(const tuple<T...>& x,
526 std::integer_sequence<int, i...>)
527{
528 return tuple{-get<i>(x)...};
529}
530
531/**
532 * @tparam T the types stored in the tuple y
533 * @param x a tuple of values
534 * @brief return a tuple of values defined by applying the unary minus operator to each element of x
535 */
536template <typename... T>
537MFEM_HOST_DEVICE constexpr auto operator-(const tuple<T...>& x)
538{
539 return unary_minus_helper(x,
540 std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
541}
542
543/**
544 * @brief A helper function for the / operator of tuples
545 *
546 * @tparam S the types stored in the tuple x
547 * @tparam T the types stored in the tuple y
548 * @tparam i The integer sequence to i
549 * @param x tuple of values
550 * @param y tuple of values
551 * @return the returned tuple ratio
552 */
553template <typename... S, typename... T, int... i>
554MFEM_HOST_DEVICE constexpr auto div_helper(const tuple<S...>& x,
555 const tuple<T...>& y,
556 std::integer_sequence<int, i...>)
557{
558 return tuple{get<i>(x) / get<i>(y)...};
559}
560
561/**
562 * @tparam S the types stored in the tuple x
563 * @tparam T the types stored in the tuple y
564 * @param x a tuple of values
565 * @param y a tuple of values
566 * @brief return a tuple of values defined by elementwise division of x by y
567 */
568template <typename... S, typename... T>
569MFEM_HOST_DEVICE constexpr auto operator/(const tuple<S...>& x,
570 const tuple<T...>& y)
571{
572 static_assert(sizeof...(S) == sizeof...(T));
573 return div_helper(x, y,
574 std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
575}
576
577/**
578 * @brief A helper function for the / operator of tuples
579 *
580 * @tparam T the types stored in the tuple y
581 * @tparam i The integer sequence to i
582 * @param x tuple of values
583 * @param a the constant numerator
584 * @return the returned tuple ratio
585 */
586template <typename... T, int... i>
587MFEM_HOST_DEVICE constexpr auto div_helper(const real_t a,
588 const tuple<T...>& x, std::integer_sequence<int, i...>)
589{
590 return tuple{a / get<i>(x)...};
591}
592
593/**
594 * @brief A helper function for the / operator of tuples
595 *
596 * @tparam T the types stored in the tuple y
597 * @tparam i The integer sequence to i
598 * @param x tuple of values
599 * @param a the constant denominator
600 * @return the returned tuple ratio
601 */
602template <typename... T, int... i>
603MFEM_HOST_DEVICE constexpr auto div_helper(const tuple<T...>& x,
604 const real_t a, std::integer_sequence<int, i...>)
605{
606 return tuple{get<i>(x) / a...};
607}
608
609/**
610 * @tparam T the types stored in the tuple x
611 * @param a the numerator
612 * @param x a tuple of denominator values
613 * @brief return a tuple of values defined by division of a by the elements of x
614 */
615template <typename... T>
616MFEM_HOST_DEVICE constexpr auto operator/(const real_t a, const tuple<T...>& x)
617{
618 return div_helper(a, x,
619 std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
620}
621
622/**
623 * @tparam T the types stored in the tuple y
624 * @param x a tuple of numerator values
625 * @param a a denominator
626 * @brief return a tuple of values defined by elementwise division of x by a
627 */
628template <typename... T>
629MFEM_HOST_DEVICE constexpr auto operator/(const tuple<T...>& x, const real_t a)
630{
631 return div_helper(x, a,
632 std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
633}
634
635/**
636 * @brief A helper function for the * operator of tuples
637 *
638 * @tparam S the types stored in the tuple x
639 * @tparam T the types stored in the tuple y
640 * @tparam i The integer sequence to i
641 * @param x tuple of values
642 * @param y tuple of values
643 * @return the returned tuple product
644 */
645template <typename... S, typename... T, int... i>
646MFEM_HOST_DEVICE constexpr auto mult_helper(const tuple<S...>& x,
647 const tuple<T...>& y,
648 std::integer_sequence<int, i...>)
649{
650 return tuple{get<i>(x) * get<i>(y)...};
651}
652
653/**
654 * @tparam S the types stored in the tuple x
655 * @tparam T the types stored in the tuple y
656 * @param x a tuple of values
657 * @param y a tuple of values
658 * @brief return a tuple of values defined by elementwise multiplication of x and y
659 */
660template <typename... S, typename... T>
661MFEM_HOST_DEVICE constexpr auto operator*(const tuple<S...>& x,
662 const tuple<T...>& y)
663{
664 static_assert(sizeof...(S) == sizeof...(T));
665 return mult_helper(x, y,
666 std::make_integer_sequence<int, static_cast<int>(sizeof...(S))>());
667}
668
669/**
670 * @brief A helper function for the * operator of tuples
671 *
672 * @tparam T the types stored in the tuple y
673 * @tparam i The integer sequence to i
674 * @param x tuple of values
675 * @param a a constant multiplier
676 * @return the returned tuple product
677 */
678template <typename... T, int... i>
679MFEM_HOST_DEVICE constexpr auto mult_helper(const real_t a,
680 const tuple<T...>& x, std::integer_sequence<int, i...>)
681{
682 return tuple{a * get<i>(x)...};
683}
684
685/**
686 * @brief A helper function for the * operator of tuples
687 *
688 * @tparam T the types stored in the tuple y
689 * @tparam i The integer sequence to i
690 * @param x tuple of values
691 * @param a a constant multiplier
692 * @return the returned tuple product
693 */
694template <typename... T, int... i>
695MFEM_HOST_DEVICE constexpr auto mult_helper(const tuple<T...>& x,
696 const real_t a, std::integer_sequence<int, i...>)
697{
698 return tuple{get<i>(x) * a...};
699}
700
701/**
702 * @tparam T the types stored in the tuple
703 * @param a a scaling factor
704 * @param x the tuple object
705 * @brief multiply each component of x by the value a on the left
706 */
707template <typename... T>
708MFEM_HOST_DEVICE constexpr auto operator*(const real_t a, const tuple<T...>& x)
709{
710 return mult_helper(a, x,
711 std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
712}
713
714/**
715 * @tparam T the types stored in the tuple
716 * @param x the tuple object
717 * @param a a scaling factor
718 * @brief multiply each component of x by the value a on the right
719 */
720template <typename... T>
721MFEM_HOST_DEVICE constexpr auto operator*(const tuple<T...>& x, const real_t a)
722{
723 return mult_helper(x, a,
724 std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
725}
726
727/**
728 * @tparam T the types stored in the tuple
729 * @tparam i a list of indices used to access each element of the tuple
730 * @param out the ostream to write the output to
731 * @param A the tuple of values
732 * @brief helper used to implement printing a tuple of values
733 */
734template <typename... T, std::size_t... i>
735auto& print_helper(std::ostream& out, const tuple<T...>& A,
736 std::integer_sequence<size_t, i...>)
737{
738 out << "tuple{";
739 (..., (out << (i == 0 ? "" : ", ") << get<i>(A)));
740 out << "}";
741 return out;
742}
743
744/**
745 * @tparam T the types stored in the tuple
746 * @param out the ostream to write the output to
747 * @param A the tuple of values
748 * @brief print a tuple of values
749 */
750template <typename... T>
751auto& operator<<(std::ostream& out, const tuple<T...>& A)
752{
753 return print_helper(out, A, std::make_integer_sequence<size_t, sizeof...(T)>());
754}
755
756/**
757 * @brief A helper to apply a lambda to a tuple
758 *
759 * @tparam lambda The functor type
760 * @tparam T The tuple types
761 * @tparam i The integer sequence to i
762 * @param f The functor to apply to the tuple
763 * @param args The input tuple
764 * @return The functor output
765 */
766template <typename lambda, typename... T, int... i>
767MFEM_HOST_DEVICE auto apply_helper(lambda f, tuple<T...>& args,
768 std::integer_sequence<int, i...>)
769{
770 return f(get<i>(args)...);
771}
772
773/**
774 * @tparam lambda a callable type
775 * @tparam T the types of arguments to be passed in to f
776 * @param f the callable object
777 * @param args a tuple of arguments
778 * @brief a way of passing an n-tuple to a function that expects n separate arguments
779 *
780 * e.g. foo(bar, baz) is equivalent to apply(foo, mfem::tuple(bar,baz));
781 */
782template <typename lambda, typename... T>
783MFEM_HOST_DEVICE auto apply(lambda f, tuple<T...>& args)
784{
785 return apply_helper(f, std::move(args),
786 std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
787}
788
789/**
790 * @overload
791 */
792template <typename lambda, typename... T, int... i>
793MFEM_HOST_DEVICE auto apply_helper(lambda f, const tuple<T...>& args,
794 std::integer_sequence<int, i...>)
795{
796 return f(get<i>(args)...);
797}
798
799/**
800 * @tparam lambda a callable type
801 * @tparam T the types of arguments to be passed in to f
802 * @param f the callable object
803 * @param args a tuple of arguments
804 * @brief a way of passing an n-tuple to a function that expects n separate arguments
805 *
806 * e.g. foo(bar, baz) is equivalent to apply(foo, mfem::tuple(bar,baz));
807 */
808template <typename lambda, typename... T>
809MFEM_HOST_DEVICE auto apply(lambda f, const tuple<T...>& args)
810{
811 return apply_helper(f, std::move(args),
812 std::make_integer_sequence<int, static_cast<int>(sizeof...(T))>());
813}
814
815/**
816 * @brief a struct used to determine the type at index I of a tuple
817 *
818 * @note see: https://en.cppreference.com/w/cpp/utility/tuple/tuple_element
819 *
820 * @tparam I the index of the desired type
821 * @tparam T a tuple of different types
822 */
823template <size_t I, class T>
825
826// recursive case
827/// @overload
828template <size_t I, class Head, class... Tail>
829struct tuple_element<I, tuple<Head, Tail...>> : tuple_element<I - 1,
830 tuple<Tail...>>
831{
832};
833
834// base case
835/// @overload
836template <class Head, class... Tail>
837struct tuple_element<0, tuple<Head, Tail...>>
838{
839 using type = Head; ///< the type at the specified index
840};
841
842/**
843 * @brief Trait for checking if a type is a @p mfem::tuple
844 */
845template <typename T>
846struct is_tuple : std::false_type
847{
848};
849
850/// @overload
851template <typename... T>
852struct is_tuple<tuple<T...>> : std::true_type
853{
854};
855
856/**
857 * @brief Trait for checking if a type if a @p mfem::tuple containing only @p mfem::tuple
858 */
859template <typename T>
860struct is_tuple_of_tuples : std::false_type
861{
862};
863
864/**
865 * @brief Trait for checking if a type if a @p mfem::tuple containing only @p mfem::tuple
866 */
867template <typename... T>
869{
870 static constexpr bool value = (is_tuple<T>::value &&
871 ...); ///< true/false result of type check
872};
873
874/** @brief Auxiliary template function that merges (concatenates) two
875 mfem::future::tuple types into a single std::tuple that is empty, i.e. it is
876 value initialized. */
877template <typename... T1s, typename... T2s>
881{
882 return std::tuple<T1s..., T2s...> {};
883}
884
885} // namespace mfem::future
real_t a
Definition lissajous.cpp:41
MFEM_HOST_DEVICE constexpr 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:399
MFEM_HOST_DEVICE constexpr auto operator-(dual< value_type, gradient_type > x) -> dual< value_type, gradient_type >
unary negation of a dual number
Definition dual.hpp:112
MFEM_HOST_DEVICE constexpr auto operator+(dual< value_type, gradient_type > a, other_type b) -> dual< value_type, gradient_type >
addition of a dual number and a non-dual number
Definition dual.hpp:74
constexpr auto merge_mfem_tuples_as_empty_std_tuple(const mfem::future::tuple< T1s... > &, const mfem::future::tuple< T2s... > &)
Auxiliary template function that merges (concatenates) two mfem::future::tuple types into a single st...
Definition tuple.hpp:878
MFEM_HOST_DEVICE tuple< T... > make_tuple(const T &... args)
helper function for combining a list of values into a tuple
Definition tuple.hpp:224
gradient_type MFEM_HOST_DEVICE dual< value_type, gradient_type > & operator+=(dual< value_type, gradient_type > &a, const dual< value_type, gradient_type > &b)
Definition dual.hpp:243
MFEM_HOST_DEVICE constexpr 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:554
MFEM_HOST_DEVICE constexpr auto unary_minus_helper(const tuple< T... > &x, std::integer_sequence< int, i... >)
A helper function for the - operator of tuples.
Definition tuple.hpp:525
auto & print_helper(std::ostream &out, const tuple< T... > &A, std::integer_sequence< size_t, i... >)
helper used to implement printing a tuple of values
Definition tuple.hpp:735
MFEM_HOST_DEVICE constexpr 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:431
MFEM_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
MFEM_HOST_DEVICE tuple(T...) -> tuple< T... >
Class template argument deduction rule for tuples.
MFEM_HOST_DEVICE dual< value_type, gradient_type > & operator-=(dual< value_type, gradient_type > &a, const dual< value_type, gradient_type > &b)
compound assignment (-) for dual numbers
Definition dual.hpp:253
std::ostream & operator<<(std::ostream &os, dual< value_type, gradient_type > A)
overload of operator<< for dual to work with work with standard output streams
Definition dual.hpp:412
MFEM_HOST_DEVICE constexpr 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:646
MFEM_HOST_DEVICE constexpr auto type(const tuple< T... > &values)
a function intended to be used for extracting the ith type from a tuple.
Definition tuple.hpp:347
MFEM_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:783
MFEM_HOST_DEVICE constexpr 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:461
MFEM_HOST_DEVICE constexpr 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:493
MFEM_HOST_DEVICE constexpr auto operator*(const dual< value_type, gradient_type > &a, real_t b) -> dual< decltype(a.value *b), decltype(a.gradient *b)>
multiplication of a dual number and a non-dual number
Definition dual.hpp:146
MFEM_HOST_DEVICE constexpr auto operator/(const dual< value_type, gradient_type > &a, real_t b) -> dual< decltype(a.value/b), decltype(a.gradient/b)>
division of a dual number by a non-dual number
Definition dual.hpp:173
MFEM_HOST_DEVICE zero & get(zero &x)
let zero be accessed like a tuple
Definition tensor.hpp:281
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
float real_t
Definition config.hpp:46
std::function< real_t(const Vector &)> f(real_t mass_coeff)
Definition lor_mms.hpp:30
Trait for checking if a type if a mfem::tuple containing only mfem::tuple.
Definition tuple.hpp:861
Trait for checking if a type is a mfem::tuple.
Definition tuple.hpp:847
T7 v7
The eighth member of the tuple.
Definition tuple.hpp:193
T6 v6
The seventh member of the tuple.
Definition tuple.hpp:192
T3 v3
The fourth member of the tuple.
Definition tuple.hpp:189
T1 v1
The second member of the tuple.
Definition tuple.hpp:187
T6 v6
The seventh member of the tuple.
Definition tuple.hpp:168
T0 v0
The first member of the tuple.
Definition tuple.hpp:162
T1 v1
The second member of the tuple.
Definition tuple.hpp:163
T2 v2
The third member of the tuple.
Definition tuple.hpp:164
T4 v4
The fifth member of the tuple.
Definition tuple.hpp:166
T5 v5
The sixth member of the tuple.
Definition tuple.hpp:167
T3 v3
The fourth member of the tuple.
Definition tuple.hpp:165
T4 v4
The fifth member of the tuple.
Definition tuple.hpp:144
T5 v5
The sixth member of the tuple.
Definition tuple.hpp:145
T2 v2
The third member of the tuple.
Definition tuple.hpp:142
T0 v0
The first member of the tuple.
Definition tuple.hpp:140
T3 v3
The fourth member of the tuple.
Definition tuple.hpp:143
T1 v1
The second member of the tuple.
Definition tuple.hpp:141
T4 v4
The fifth member of the tuple.
Definition tuple.hpp:124
T2 v2
The third member of the tuple.
Definition tuple.hpp:122
T3 v3
The fourth member of the tuple.
Definition tuple.hpp:123
T1 v1
The second member of the tuple.
Definition tuple.hpp:121
T0 v0
The first member of the tuple.
Definition tuple.hpp:120
T1 v1
The second member of the tuple.
Definition tuple.hpp:103
T0 v0
The first member of the tuple.
Definition tuple.hpp:102
T3 v3
The fourth member of the tuple.
Definition tuple.hpp:105
T2 v2
The third member of the tuple.
Definition tuple.hpp:104
T0 v0
The first member of the tuple.
Definition tuple.hpp:86
T2 v2
The third member of the tuple.
Definition tuple.hpp:88
T1 v1
The second member of the tuple.
Definition tuple.hpp:87
T1 v1
The second member of the tuple.
Definition tuple.hpp:73
T0 v0
The first member of the tuple.
Definition tuple.hpp:72
T0 v0
The first member of the tuple.
Definition tuple.hpp:60
Head type
the type at the specified index
Definition tuple.hpp:839
a struct used to determine the type at index I of a tuple
Definition tuple.hpp:824
This is a class that mimics most of std::tuple's interface, except that it is usable in CUDA kernels ...
Definition tuple.hpp:49