1 //Copyright (c) 2008-2016 Emil Dotchevski and Reverge Studios, Inc.
3 //Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 #ifndef UUID_E831FAD6B38F11DE8CECBF0D56D89593
7 #define UUID_E831FAD6B38F11DE8CECBF0D56D89593
9 #include <boost/qvm/inline.hpp>
10 #include <boost/qvm/deduce_vec.hpp>
11 #include <boost/qvm/enable_if.hpp>
12 #include <boost/qvm/assert.hpp>
23 BOOST_QVM_INLINE_CRITICAL
27 static int const obj=0;
31 template <int A,class Next=void> struct swizzle_idx { static int const value=A; typedef Next next; };
33 template <class V,int Idx>
38 BOOST_QVM_INLINE_TRIVIAL
39 typename vec_traits<V>::scalar_type
43 return typename vec_traits<V>::scalar_type();
52 BOOST_QVM_INLINE_TRIVIAL
53 typename vec_traits<V>::scalar_type
56 return scalar_traits<typename vec_traits<V>::scalar_type>::value(0);
65 BOOST_QVM_INLINE_TRIVIAL
66 typename vec_traits<V>::scalar_type
69 return scalar_traits<typename vec_traits<V>::scalar_type>::value(1);
73 template <int Index,bool Neg=(Index<0)>
80 static int const value=0;
87 static int const value=Index;
90 template <class SwizzleList,int Index,int C=0>
94 static int const value=swizzle<typename SwizzleList::next,Index,C+1>::value;
97 template <class SwizzleList,int Match>
99 swizzle<SwizzleList,Match,Match>
101 static int const value=SwizzleList::value;
104 template <int Index,int C>
105 struct swizzle<void,Index,C>;
107 template <class SwizzleList,int C=0>
111 static int const value=swizzle_list_length<typename SwizzleList::next,C+1>::value;
116 swizzle_list_length<void,C>
118 static int const value=C;
121 template <class SwizzleList,int D>
123 validate_swizzle_list
125 static bool const value =
126 ((SwizzleList::value)<D) && //don't touch extra (), MSVC parsing bug.
127 validate_swizzle_list<typename SwizzleList::next,D>::value;
132 validate_swizzle_list<void,D>
134 static bool const value=true;
137 template <class OriginalType,class SwizzleList>
142 sw_ & operator=( sw_ const & );
145 BOOST_QVM_STATIC_ASSERT((validate_swizzle_list<SwizzleList,vec_traits<OriginalType>::dim>::value));
150 BOOST_QVM_INLINE_TRIVIAL
152 operator=( T const & x )
159 BOOST_QVM_INLINE_TRIVIAL
168 template <class SwizzleList>
172 sw01_( sw01_ const & );
173 sw01_ & operator=( sw01_ const & );
179 BOOST_QVM_INLINE_TRIVIAL
188 template <class OriginalType,class SwizzleList>
192 sws_( sws_ const & );
193 sws_ & operator=( sws_ const & );
196 BOOST_QVM_STATIC_ASSERT((validate_swizzle_list<SwizzleList,1>::value));
201 BOOST_QVM_INLINE_TRIVIAL
211 template <class OriginalVector,class SwizzleList>
213 vec_traits<qvm_detail::sw_<OriginalVector,SwizzleList> >
215 typedef qvm_detail::sw_<OriginalVector,SwizzleList> this_vector;
216 typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
217 static int const dim=qvm_detail::swizzle_list_length<SwizzleList>::value;
221 BOOST_QVM_INLINE_CRITICAL
223 read_element( this_vector const & x )
225 BOOST_QVM_STATIC_ASSERT(I>=0);
226 BOOST_QVM_STATIC_ASSERT(I<dim);
227 int const idx=qvm_detail::swizzle<SwizzleList,I>::value;
228 BOOST_QVM_STATIC_ASSERT(idx<vec_traits<OriginalVector>::dim);
230 vec_traits<OriginalVector>::template read_element<qvm_detail::neg_zero<idx>::value>(reinterpret_cast<OriginalVector const &>(x)) :
231 qvm_detail::const_value<this_vector,idx>::value();
236 BOOST_QVM_INLINE_CRITICAL
238 write_element( this_vector & x )
240 BOOST_QVM_STATIC_ASSERT(I>=0);
241 BOOST_QVM_STATIC_ASSERT(I<dim);
242 int const idx=qvm_detail::swizzle<SwizzleList,I>::value;
243 BOOST_QVM_STATIC_ASSERT(idx>=0);
244 BOOST_QVM_STATIC_ASSERT(idx<vec_traits<OriginalVector>::dim);
245 return vec_traits<OriginalVector>::template write_element<idx>(reinterpret_cast<OriginalVector &>(x));
249 template <class SwizzleList>
251 vec_traits<qvm_detail::sw01_<SwizzleList> >
253 typedef qvm_detail::sw01_<SwizzleList> this_vector;
254 typedef int scalar_type;
255 static int const dim=qvm_detail::swizzle_list_length<SwizzleList>::value;
259 BOOST_QVM_INLINE_CRITICAL
261 read_element( this_vector const & )
263 BOOST_QVM_STATIC_ASSERT(I>=0);
264 BOOST_QVM_STATIC_ASSERT(I<dim);
265 int const idx=qvm_detail::swizzle<SwizzleList,I>::value;
266 BOOST_QVM_STATIC_ASSERT(idx<0);
267 return qvm_detail::const_value<this_vector,idx>::value();
271 template <class OriginalScalar,class SwizzleList>
273 vec_traits<qvm_detail::sws_<OriginalScalar,SwizzleList> >
275 typedef qvm_detail::sws_<OriginalScalar,SwizzleList> this_vector;
276 typedef OriginalScalar scalar_type;
277 static int const dim=qvm_detail::swizzle_list_length<SwizzleList>::value;
281 BOOST_QVM_INLINE_CRITICAL
283 read_element( this_vector const & x )
285 BOOST_QVM_STATIC_ASSERT(I>=0);
286 BOOST_QVM_STATIC_ASSERT(I<dim);
287 int const idx=qvm_detail::swizzle<SwizzleList,I>::value;
288 BOOST_QVM_STATIC_ASSERT(idx<1);
290 reinterpret_cast<OriginalScalar const &>(x) :
291 qvm_detail::const_value<this_vector,idx>::value();
296 BOOST_QVM_INLINE_CRITICAL
298 write_element( this_vector & x )
300 BOOST_QVM_STATIC_ASSERT(I>=0);
301 BOOST_QVM_STATIC_ASSERT(I<dim);
302 int const idx=qvm_detail::swizzle<SwizzleList,I>::value;
303 BOOST_QVM_STATIC_ASSERT(idx==0);
304 return reinterpret_cast<OriginalScalar &>(x);
308 template <class OriginalVector,class SwizzleList,int D>
310 deduce_vec<qvm_detail::sw_<OriginalVector,SwizzleList>,D>
312 typedef vec<typename vec_traits<OriginalVector>::scalar_type,D> type;
315 template <class OriginalVector,class SwizzleList,int D>
317 deduce_vec2<qvm_detail::sw_<OriginalVector,SwizzleList>,qvm_detail::sw_<OriginalVector,SwizzleList>,D>
319 typedef vec<typename vec_traits<OriginalVector>::scalar_type,D> type;
322 template <class Scalar,class SwizzleList,int D>
324 deduce_vec<qvm_detail::sws_<Scalar,SwizzleList>,D>
326 typedef vec<Scalar,D> type;
329 template <class Scalar,class SwizzleList,int D>
331 deduce_vec2<qvm_detail::sws_<Scalar,SwizzleList>,qvm_detail::sws_<Scalar,SwizzleList>,D>
333 typedef vec<Scalar,D> type;