tu: Implement fallback linear staging blit for CopyImage
[mesa.git] / src / gallium / state_trackers / clover / util / algebra.hpp
1 //
2 // Copyright 2013 Francisco Jerez
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
21 //
22
23 #ifndef CLOVER_UTIL_ALGEBRA_HPP
24 #define CLOVER_UTIL_ALGEBRA_HPP
25
26 #include <type_traits>
27
28 #include "util/range.hpp"
29 #include "util/functional.hpp"
30
31 namespace clover {
32 ///
33 /// Class that identifies vectors (in the linear-algebraic sense).
34 ///
35 /// There should be a definition of this class for each type that
36 /// makes sense as vector arithmetic operand.
37 ///
38 template<typename V, typename = void>
39 struct vector_traits;
40
41 ///
42 /// References of vectors are vectors.
43 ///
44 template<typename T>
45 struct vector_traits<T &, typename vector_traits<T>::enable> {
46 typedef void enable;
47 };
48
49 ///
50 /// Constant vectors are vectors.
51 ///
52 template<typename T>
53 struct vector_traits<const T, typename vector_traits<T>::enable> {
54 typedef void enable;
55 };
56
57 ///
58 /// Arrays of arithmetic types are vectors.
59 ///
60 template<typename T, std::size_t N>
61 struct vector_traits<std::array<T, N>,
62 typename std::enable_if<
63 std::is_arithmetic<T>::value>::type> {
64 typedef void enable;
65 };
66
67 namespace detail {
68 template<typename... Ts>
69 struct are_defined {
70 typedef void enable;
71 };
72 }
73
74 ///
75 /// The result of mapping a vector is a vector.
76 ///
77 template<typename F, typename... Vs>
78 struct vector_traits<adaptor_range<F, Vs...>,
79 typename detail::are_defined<
80 typename vector_traits<Vs>::enable...>::enable> {
81 typedef void enable;
82 };
83
84 ///
85 /// Vector sum.
86 ///
87 template<typename U, typename V,
88 typename = typename vector_traits<U>::enable,
89 typename = typename vector_traits<V>::enable>
90 adaptor_range<plus, U, V>
91 operator+(U &&u, V &&v) {
92 return map(plus(), std::forward<U>(u), std::forward<V>(v));
93 }
94
95 ///
96 /// Vector difference.
97 ///
98 template<typename U, typename V,
99 typename = typename vector_traits<U>::enable,
100 typename = typename vector_traits<V>::enable>
101 adaptor_range<minus, U, V>
102 operator-(U &&u, V &&v) {
103 return map(minus(), std::forward<U>(u), std::forward<V>(v));
104 }
105
106 ///
107 /// Scalar multiplication.
108 ///
109 template<typename U, typename T,
110 typename = typename vector_traits<U>::enable>
111 adaptor_range<multiplies_by_t<T>, U>
112 operator*(U &&u, T &&a) {
113 return map(multiplies_by<T>(std::forward<T>(a)), std::forward<U>(u));
114 }
115
116 ///
117 /// Scalar multiplication.
118 ///
119 template<typename U, typename T,
120 typename = typename vector_traits<U>::enable>
121 adaptor_range<multiplies_by_t<T>, U>
122 operator*(T &&a, U &&u) {
123 return map(multiplies_by<T>(std::forward<T>(a)), std::forward<U>(u));
124 }
125
126 ///
127 /// Additive inverse.
128 ///
129 template<typename U,
130 typename = typename vector_traits<U>::enable>
131 adaptor_range<negate, U>
132 operator-(U &&u) {
133 return map(negate(), std::forward<U>(u));
134 }
135
136 namespace detail {
137 template<typename U, typename V>
138 using dot_type = typename std::common_type<
139 typename std::remove_reference<U>::type::value_type,
140 typename std::remove_reference<V>::type::value_type
141 >::type;
142 }
143
144 ///
145 /// Dot product of two vectors.
146 ///
147 /// It can also do matrix multiplication if \a u or \a v is a
148 /// vector of vectors.
149 ///
150 template<typename U, typename V,
151 typename = typename vector_traits<U>::enable,
152 typename = typename vector_traits<V>::enable>
153 detail::dot_type<U, V>
154 dot(U &&u, V &&v) {
155 return fold(plus(), detail::dot_type<U, V>(),
156 map(multiplies(), u, v));
157 }
158 }
159
160 #endif