-
Notifications
You must be signed in to change notification settings - Fork 1
/
array_arith.hpp
123 lines (108 loc) · 3.26 KB
/
array_arith.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/** This header defines simple arithmetics for @c std::array<T,N> treating
* them as vectors of fixed size. The following operators are supported:
* - operator+( const std::array<T,N> &, const std::array<T,N> & )
* - operator-( const std::array<T,N> &, const std::array<T,N> & )
* - operator*( const T2 &, const std::array<T1,N> & )
* - operator/( const std::array<T1,N> &, const T2 & )
* To enable these operators conveniently write
* @code
* using namespace cu::array_arith;
* @endcode
* into your code.
*/
#pragma once
#include <array>
#include <utility>
namespace cu
{
namespace array_arith
{
namespace detail
{
template <typename T,
std::size_t N,
std::size_t ...idxs>
std::array<T,N> add_impl( const std::array<T,N> & lhs,
const std::array<T,N> & rhs,
std::index_sequence<idxs...> )
{
return { lhs[idxs]+rhs[idxs]... };
}
} // namespace detail
template <typename T,
std::size_t N>
std::array<T,N> operator+( const std::array<T,N> & lhs,
const std::array<T,N> & rhs )
{
return detail::add_impl( lhs, rhs, std::make_index_sequence<N>{} );
}
namespace detail
{
template <typename T,
std::size_t N,
std::size_t ...idxs>
std::array<T,N> sub_impl( const std::array<T,N> & lhs,
const std::array<T,N> & rhs,
std::index_sequence<idxs...> )
{
return { lhs[idxs]-rhs[idxs]... };
}
} // namespace detail
template <typename T,
std::size_t N>
std::array<T,N> operator-( const std::array<T,N> & lhs,
const std::array<T,N> & rhs )
{
return detail::sub_impl( lhs, rhs, std::make_index_sequence<N>{} );
}
namespace detail
{
template <typename T1,
typename T2,
std::size_t N,
std::size_t ...idxs>
std::array<T1,N> mul_impl( const T2 & lhs,
const std::array<T1,N> & rhs,
std::index_sequence<idxs...> )
{
return { lhs*rhs[idxs]... };
}
} // namespace detail
template <typename T1,
typename T2,
std::size_t N>
std::array<T1,N> operator*( const T2 & lhs,
const std::array<T1,N> & rhs )
{
return detail::mul_impl( lhs, rhs, std::make_index_sequence<N>{} );
}
namespace detail
{
template <typename T1,
typename T2,
std::size_t N,
std::size_t ...idxs>
std::array<T1,N> div_impl( const std::array<T1,N> & lhs,
const T2 & rhs,
std::index_sequence<idxs...> )
{
const auto reciprocal = T1(1) / rhs;
return { lhs[idxs]*reciprocal... };
}
} // namespace detail
template <typename T1,
typename T2,
std::size_t N>
std::array<T1,N> operator/( const std::array<T1,N> & lhs,
const T2 & rhs )
{
return detail::div_impl( lhs, rhs, std::make_index_sequence<N>{} );
}
template <typename T,
std::size_t N>
void assign( std::array<T,N> & lhs, std::array<T,N> && rhs )
{
lhs = std::move(rhs);
}
} // namespace array_arith
} // namespace cu