Developer documentation
Version 3.0.3-105-gd3941f44
apply.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __apply_h__
18#define __apply_h__
19
20#include <tuple>
21#include <type_traits>
22
23#include "types.h" // For FORCE_INLINE
24
25namespace MR {
26 namespace {
27
28 template<size_t N>
29 struct Apply { NOMEMALIGN
30 template<typename F, typename T>
31 static FORCE_INLINE void apply (F && f, T && t)
32 {
33 Apply<N-1>::apply (::std::forward<F>(f), ::std::forward<T>(t));
34 ::std::forward<F>(f) (::std::get<N> (::std::forward<T>(t)));
35 }
36 };
37
38 template<>
39 struct Apply<0> { NOMEMALIGN
40 template<typename F, typename T>
41 static FORCE_INLINE void apply (F && f, T && t)
42 {
43 ::std::forward<F>(f) (::std::get<0> (::std::forward<T>(t)));
44 }
45 };
46
47
48
49
50 template<size_t N>
51 struct Unpack { NOMEMALIGN
52 template<typename F, typename T, typename... A>
53 static FORCE_INLINE auto unpack (F && f, T && t, A &&... a)
54 -> decltype(Unpack<N-1>::unpack (
55 ::std::forward<F>(f), ::std::forward<T>(t),
56 ::std::get<N-1>(::std::forward<T>(t)), ::std::forward<A>(a)...
57 ))
58 {
59 return Unpack<N-1>::unpack (::std::forward<F>(f), ::std::forward<T>(t),
60 ::std::get<N-1>(::std::forward<T>(t)), ::std::forward<A>(a)...
61 );
62 }
63 };
64
65 template<>
66 struct Unpack<0> { NOMEMALIGN
67 template<typename F, typename T, typename... A>
68 static FORCE_INLINE auto unpack (F && f, T &&, A &&... a)
69 -> decltype(::std::forward<F>(f)(::std::forward<A>(a)...))
70 {
71 return ::std::forward<F>(f)(::std::forward<A>(a)...);
72 }
73 };
74
75 }
76
77
78
79
81 template <class F, class T>
82 FORCE_INLINE void apply (F && f, T && t)
83 {
84 Apply< ::std::tuple_size<
85 typename ::std::decay<T>::type
86 >::value-1>::apply (::std::forward<F>(f), ::std::forward<T>(t));
87 }
88
90 template<typename F, typename T>
91 FORCE_INLINE auto unpack (F && f, T && t)
92 -> decltype(Unpack< ::std::tuple_size<
93 typename ::std::decay<T>::type
94 >::value>::unpack (::std::forward<F>(f), ::std::forward<T>(t)))
95 {
96 return Unpack< ::std::tuple_size<
97 typename ::std::decay<T>::type
98 >::value>::unpack (::std::forward<F>(f), ::std::forward<T>(t));
99 }
100}
101
102#endif
103
VectorType::Scalar value(const VectorType &coefs, typename VectorType::Scalar cos_elevation, typename VectorType::Scalar cos_azimuth, typename VectorType::Scalar sin_azimuth, int lmax)
Definition: SH.h:233
#define NOMEMALIGN
Definition: memory.h:22
Definition: base.h:24
void apply(F &&f, T &&t)
invoke f(x) for each entry in t
Definition: apply.h:82
auto unpack(F &&f, T &&t) -> decltype(Unpack< ::std::tuple_size< typename ::std::decay< T >::type >::value >::unpack(::std::forward< F >(f), ::std::forward< T >(t)))
if t is a tuple of elements a..., invoke f(a...)
Definition: apply.h:91
#define FORCE_INLINE
Definition: types.h:156