neoGFX
Cross-platform C++ app/game engine
Loading...
Searching...
No Matches
swizzle.hpp
Go to the documentation of this file.
1// swizzle.hpp
2/*
3 * Copyright (c) 2015, 2020 Leigh Johnston.
4 *
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * * Neither the name of Leigh Johnston nor the names of any
19 * other contributors to this software may be used to endorse or
20 * promote products derived from this software without specific prior
21 * written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
26 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
27 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36#pragma once
37
38#include <neolib/neolib.hpp>
39
40namespace neolib
41{
42 namespace math
43 {
44 template<uint32_t... Rest>
46 {
47 // Will replace this enum hack with constexpr when I upgrade my compiler from VS2013 :/
48 enum { result = true };
49 };
50
51 template<uint32_t Lhs, uint32_t Rhs, uint32_t... Rest>
52 struct greater_than<Lhs, Rhs, Rest...>
53 {
54 // Will replace this enum hack with constexpr when I upgrade my compiler from VS2013 :/
55 enum { result = Lhs > Rhs && greater_than<Lhs, Rest...>::result };
56 };
57
58 template <typename V, uint32_t S>
60 {
61 typedef typename V::template rebind<S>::type type;
62 };
63
64 template <typename V>
65 struct swizzle_rebind<V, 1>
66 {
67 typedef typename V::value_type type;
68 };
69
70 template <typename V, uint32_t S>
72
73 template <typename V, typename A, uint32_t S, uint32_t... Indexes>
74 struct swizzle
75 {
76 public:
77 typedef V vector_type;
78 typedef A array_type;
79 typedef typename array_type::value_type value_type;
80 private:
81 template <uint32_t Index, uint32_t...>
82 struct first
83 {
84 static constexpr uint32_t value = Index;
85 };
86 public:
88 {
89 static_assert(greater_than<vector_type::Size, Indexes...>::result, "Swizzle too big");
90 assign(aRhs, &v[Indexes]...);
91 return *this;
92 }
93 template <typename T, typename SFINAE = std::enable_if_t<std::is_same_v<std::decay_t<T>, swizzle_rebind_t<vector_type, S>>, sfinae>>
94 swizzle& operator=(const T& aRhs)
95 {
96 static_assert(greater_than<vector_type::Size, Indexes...>::result, "Swizzle too big");
97 assign(std::begin(aRhs.v), &v[Indexes]...);
98 return *this;
99 }
100 public:
101 template <typename DestIter>
102 void copy(DestIter aDestination) const
103 {
104 do_copy(aDestination, &v[Indexes]...);
105 }
106 private:
107 template <typename Next, typename... Rest>
108 void assign(value_type aValue, Next aNext, Rest... aRest)
109 {
110 *aNext = aValue;
111 assign(aValue, aRest...);
112 }
113 template <typename... Rest>
114 void assign(value_type, Rest...)
115 {
116 /* finished */
117 }
118 template <typename SourceIter, typename Next, typename... Rest>
119 void assign(SourceIter aSource, Next aNext, Rest... aRest)
120 {
121 *aNext = *aSource++;
122 assign(aSource, aRest...);
123 }
124 template <typename SourceIter, typename... Rest>
125 void assign(SourceIter, Rest...)
126 {
127 /* finished */
128 }
129 template <typename DestIter, typename Next, typename... Rest>
130 void do_copy(DestIter aDestination, Next aNext, Rest... aRest) const
131 {
132 *aDestination++ = *aNext;
133 do_copy(aDestination, aRest...);
134 }
135 template <typename DestIter, typename... Rest>
136 void do_copy(DestIter, Rest...) const
137 {
138 /* finished */
139 }
140 public:
142 };
143
144 namespace operators
145 {
146 template <typename V, typename A, uint32_t S, uint32_t... Indexes1>
148 {
150 aArg.copy(&result.v[0]);
151 return result;
152 }
153
154 template <typename V, typename A, uint32_t S, uint32_t... Indexes1, uint32_t... Indexes2>
156 {
157 return ~aLhs + ~aRhs;
158 }
159
160 template <typename V, typename A, uint32_t S, uint32_t... Indexes1, uint32_t... Indexes2>
162 {
163 return ~aLhs - ~aRhs;
164 }
165
166 template <typename V, typename A, uint32_t S, uint32_t... Indexes1, uint32_t... Indexes2>
171
172 template <typename V, typename A, uint32_t S, uint32_t... Indexes1, uint32_t... Indexes2>
174 {
175 return ~aLhs / ~aRhs;
176 }
177
178 template <typename V, typename A, uint32_t S, uint32_t... Indexes1, uint32_t... Indexes2>
180 {
181 return ~aLhs < ~aRhs;
182 }
183
184 template <typename V, typename A, uint32_t S, uint32_t... Indexes1, uint32_t... Indexes2>
186 {
187 return ~aLhs <= ~aRhs;
188 }
189
190 template <typename V, typename A, uint32_t S, uint32_t... Indexes1, uint32_t... Indexes2>
192 {
193 return ~aLhs > ~aRhs;
194 }
195
196 template <typename V, typename A, uint32_t S, uint32_t... Indexes1, uint32_t... Indexes2>
198 {
199 return ~aLhs >= ~aRhs;
200 }
201
202 template <typename V, typename A, uint32_t S, uint32_t... Indexes1, uint32_t... Indexes2>
204 {
205 return ~aLhs == ~aRhs;
206 }
207
208 template <typename V, typename A, uint32_t S, uint32_t... Indexes1, uint32_t... Indexes2>
210 {
211 return ~aLhs != ~aRhs;
212 }
213 }
214 }
215}
216
217using neolib::math::operators::operator~;
218using neolib::math::operators::operator+;
219using neolib::math::operators::operator-;
220using neolib::math::operators::operator*;
221using neolib::math::operators::operator/;
222using neolib::math::operators::operator<;
223using neolib::math::operators::operator>;
224using neolib::math::operators::operator<=;
225using neolib::math::operators::operator>=;
226using neolib::math::operators::operator==;
227using neolib::math::operators::operator!=;
228
bool operator>=(const neolib::math::swizzle< V, A, S, Indexes1... > &aLhs, const neolib::math::swizzle< V, A, S, Indexes2... > &aRhs)
Definition swizzle.hpp:197
bool operator>(const neolib::math::swizzle< V, A, S, Indexes1... > &aLhs, const neolib::math::swizzle< V, A, S, Indexes2... > &aRhs)
Definition swizzle.hpp:191
neolib::math::swizzle_rebind_t< V, S > operator*(const neolib::math::swizzle< V, A, S, Indexes1... > &aLhs, const neolib::math::swizzle< V, A, S, Indexes2... > &aRhs)
Definition swizzle.hpp:167
typename swizzle_rebind< V, S >::type swizzle_rebind_t
Definition swizzle.hpp:71
V::template rebind< S >::type type
Definition swizzle.hpp:61
swizzle & operator=(const T &aRhs)
Definition swizzle.hpp:94
array_type::value_type value_type
Definition swizzle.hpp:79
swizzle & operator=(const value_type &aRhs)
Definition swizzle.hpp:87
void copy(DestIter aDestination) const
Definition swizzle.hpp:102