Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:42

0001 #ifndef BOOST_QVM_DETAIL_SWIZZLE_TRAITS_HPP_INCLUDED
0002 #define BOOST_QVM_DETAIL_SWIZZLE_TRAITS_HPP_INCLUDED
0003 
0004 // Copyright 2008-2022 Emil Dotchevski and Reverge Studios, Inc.
0005 
0006 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0007 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0008 
0009 #include <boost/qvm/config.hpp>
0010 #include <boost/qvm/deduce_vec.hpp>
0011 #include <boost/qvm/enable_if.hpp>
0012 #include <boost/qvm/assert.hpp>
0013 
0014 namespace boost { namespace qvm {
0015 
0016 namespace
0017 qvm_detail
0018     {
0019     BOOST_QVM_INLINE_CRITICAL
0020     void const *
0021     get_null()
0022         {
0023         static int const obj=0;
0024         return &obj;
0025         }
0026 
0027     template <int A,class Next=void> struct swizzle_idx { static int const value=A; typedef Next next; };
0028 
0029     template <class V,int Idx>
0030     struct
0031     const_value
0032         {
0033         static
0034         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0035         typename vec_traits<V>::scalar_type
0036         value()
0037             {
0038             BOOST_QVM_ASSERT(0);
0039             return typename vec_traits<V>::scalar_type();
0040             }
0041         };
0042 
0043     template <class V>
0044     struct
0045     const_value<V,-1>
0046         {
0047         static
0048         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0049         typename vec_traits<V>::scalar_type
0050         value()
0051             {
0052             return scalar_traits<typename vec_traits<V>::scalar_type>::value(0);
0053             }
0054         };
0055 
0056     template <class V>
0057     struct
0058     const_value<V,-2>
0059         {
0060         static
0061         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0062         typename vec_traits<V>::scalar_type
0063         value()
0064             {
0065             return scalar_traits<typename vec_traits<V>::scalar_type>::value(1);
0066             }
0067         };
0068 
0069     template <int Index,bool Neg=(Index<0)>
0070     struct neg_zero;
0071 
0072     template <int Index>
0073     struct
0074     neg_zero<Index,true>
0075         {
0076         static int const value=0;
0077         };
0078 
0079     template <int Index>
0080     struct
0081     neg_zero<Index,false>
0082         {
0083         static int const value=Index;
0084         };
0085 
0086     template <class SwizzleList,int Index,int C=0>
0087     struct
0088     swizzle
0089         {
0090         static int const value=swizzle<typename SwizzleList::next,Index,C+1>::value;
0091         };
0092 
0093     template <class SwizzleList,int Match>
0094     struct
0095     swizzle<SwizzleList,Match,Match>
0096         {
0097         static int const value=SwizzleList::value;
0098         };
0099 
0100     template <int Index,int C>
0101     struct swizzle<void,Index,C>;
0102 
0103     template <class SwizzleList,int C=0>
0104     struct
0105     swizzle_list_length
0106         {
0107         static int const value=swizzle_list_length<typename SwizzleList::next,C+1>::value;
0108         };
0109 
0110     template <int C>
0111     struct
0112     swizzle_list_length<void,C>
0113         {
0114         static int const value=C;
0115         };
0116 
0117     template <class SwizzleList,int D>
0118     struct
0119     validate_swizzle_list
0120         {
0121         static bool const value =
0122             ((SwizzleList::value)<D) && //don't touch extra (), MSVC parsing bug.
0123             validate_swizzle_list<typename SwizzleList::next,D>::value;
0124         };
0125 
0126     template <int D>
0127     struct
0128     validate_swizzle_list<void,D>
0129         {
0130         static bool const value=true;
0131         };
0132 
0133     template <class OriginalType,class SwizzleList>
0134     class
0135     sw_
0136         {
0137         sw_( sw_ const & );
0138         sw_ & operator=( sw_ const & );
0139         ~sw_();
0140 
0141         BOOST_QVM_STATIC_ASSERT((validate_swizzle_list<SwizzleList,vec_traits<OriginalType>::dim>::value));
0142 
0143         public:
0144 
0145         template <class T>
0146         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0147         sw_ &
0148         operator=( T const & x )
0149             {
0150             assign(*this,x);
0151             return *this;
0152             }
0153 
0154         template <class R
0155 #if __cplusplus >= 201103L
0156             , class = typename enable_if<is_vec<R> >::type
0157 #endif
0158         >
0159         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0160         operator R() const
0161             {
0162             R r;
0163             assign(r,*this);
0164             return r;
0165             }
0166         };
0167 
0168     template <class OriginalVector,class SwizzleList,bool WriteElementRef=vec_write_element_ref<OriginalVector>::value>
0169     struct sw_write_traits;
0170 
0171     template <class OriginalVector,class SwizzleList>
0172     struct
0173     sw_write_traits<OriginalVector,SwizzleList,true>
0174         {
0175         typedef qvm_detail::sw_<OriginalVector,SwizzleList> this_vector;
0176         typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0177         static int const dim=qvm_detail::swizzle_list_length<SwizzleList>::value;
0178 
0179         template <int I>
0180         static
0181         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0182         scalar_type &
0183         write_element( this_vector & x )
0184             {
0185             BOOST_QVM_STATIC_ASSERT(I>=0);
0186             BOOST_QVM_STATIC_ASSERT(I<dim);
0187             int const idx=qvm_detail::swizzle<SwizzleList,I>::value;
0188             BOOST_QVM_STATIC_ASSERT(idx>=0);
0189             BOOST_QVM_STATIC_ASSERT(idx<vec_traits<OriginalVector>::dim);
0190             return vec_traits<OriginalVector>::template write_element<idx>(reinterpret_cast<OriginalVector &>(x));
0191             }
0192         };
0193 
0194     template <class OriginalVector,class SwizzleList>
0195     struct
0196     sw_write_traits<OriginalVector,SwizzleList,false>
0197         {
0198         typedef qvm_detail::sw_<OriginalVector,SwizzleList> this_vector;
0199         typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0200         static int const dim=qvm_detail::swizzle_list_length<SwizzleList>::value;
0201 
0202         template <int I>
0203         static
0204         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0205         void
0206         write_element( this_vector & x, scalar_type s )
0207             {
0208             BOOST_QVM_STATIC_ASSERT(I>=0);
0209             BOOST_QVM_STATIC_ASSERT(I<dim);
0210             int const idx=qvm_detail::swizzle<SwizzleList,I>::value;
0211             BOOST_QVM_STATIC_ASSERT(idx>=0);
0212             BOOST_QVM_STATIC_ASSERT(idx<vec_traits<OriginalVector>::dim);
0213             vec_traits<OriginalVector>::template write_element<idx>(reinterpret_cast<OriginalVector &>(x), s);
0214             }
0215         };
0216 
0217     template <class SwizzleList>
0218     class
0219     sw01_
0220         {
0221         sw01_( sw01_ const & );
0222         sw01_ & operator=( sw01_ const & );
0223         ~sw01_();
0224 
0225         public:
0226 
0227         template <class R
0228 #if __cplusplus >= 201103L
0229             , class = typename enable_if<is_vec<R> >::type
0230 #endif
0231         >
0232         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0233         operator R() const
0234             {
0235             R r;
0236             assign(r,*this);
0237             return r;
0238             }
0239         };
0240 
0241     template <class OriginalType,class SwizzleList>
0242     class
0243     sws_
0244         {
0245         sws_( sws_ const & );
0246         sws_ & operator=( sws_ const & );
0247         ~sws_();
0248 
0249         BOOST_QVM_STATIC_ASSERT((validate_swizzle_list<SwizzleList,1>::value));
0250 
0251         public:
0252 
0253         template <class R
0254 #if __cplusplus >= 201103L
0255             , class = typename enable_if<is_vec<R> >::type
0256 #endif
0257         >
0258         BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_TRIVIAL
0259         operator R() const
0260             {
0261             R r;
0262             assign(r,*this);
0263             return r;
0264             }
0265         };
0266     }
0267 
0268 template <class OriginalVector,class SwizzleList>
0269 struct
0270 vec_traits<qvm_detail::sw_<OriginalVector,SwizzleList> >:
0271     qvm_detail::sw_write_traits<OriginalVector,SwizzleList>
0272     {
0273     typedef qvm_detail::sw_<OriginalVector,SwizzleList> this_vector;
0274     typedef typename vec_traits<OriginalVector>::scalar_type scalar_type;
0275     static int const dim=qvm_detail::swizzle_list_length<SwizzleList>::value;
0276 
0277     template <int I>
0278     static
0279     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0280     scalar_type
0281     read_element( this_vector const & x )
0282         {
0283         BOOST_QVM_STATIC_ASSERT(I>=0);
0284         BOOST_QVM_STATIC_ASSERT(I<dim);
0285         int const idx=qvm_detail::swizzle<SwizzleList,I>::value;
0286         BOOST_QVM_STATIC_ASSERT(idx<vec_traits<OriginalVector>::dim);
0287         return idx>=0?
0288             vec_traits<OriginalVector>::template read_element<qvm_detail::neg_zero<idx>::value>(reinterpret_cast<OriginalVector const &>(x)) :
0289             qvm_detail::const_value<this_vector,idx>::value();
0290         }
0291     };
0292 
0293 template <class SwizzleList>
0294 struct
0295 vec_traits<qvm_detail::sw01_<SwizzleList> >
0296     {
0297     typedef qvm_detail::sw01_<SwizzleList> this_vector;
0298     typedef int scalar_type;
0299     static int const dim=qvm_detail::swizzle_list_length<SwizzleList>::value;
0300 
0301     template <int I>
0302     static
0303     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0304     scalar_type
0305     read_element( this_vector const & )
0306         {
0307         BOOST_QVM_STATIC_ASSERT(I>=0);
0308         BOOST_QVM_STATIC_ASSERT(I<dim);
0309         int const idx=qvm_detail::swizzle<SwizzleList,I>::value;
0310         BOOST_QVM_STATIC_ASSERT(idx<0);
0311         return qvm_detail::const_value<this_vector,idx>::value();
0312         }
0313     };
0314 
0315 template <class OriginalScalar,class SwizzleList>
0316 struct
0317 vec_traits<qvm_detail::sws_<OriginalScalar,SwizzleList> >
0318     {
0319     typedef qvm_detail::sws_<OriginalScalar,SwizzleList> this_vector;
0320     typedef OriginalScalar scalar_type;
0321     static int const dim=qvm_detail::swizzle_list_length<SwizzleList>::value;
0322 
0323     template <int I>
0324     static
0325     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0326     scalar_type
0327     read_element( this_vector const & x )
0328         {
0329         BOOST_QVM_STATIC_ASSERT(I>=0);
0330         BOOST_QVM_STATIC_ASSERT(I<dim);
0331         int const idx=qvm_detail::swizzle<SwizzleList,I>::value;
0332         BOOST_QVM_STATIC_ASSERT(idx<1);
0333         return idx==0?
0334             reinterpret_cast<OriginalScalar const &>(x) :
0335             qvm_detail::const_value<this_vector,idx>::value();
0336         }
0337 
0338     template <int I>
0339     static
0340     BOOST_QVM_CONSTEXPR BOOST_QVM_INLINE_CRITICAL
0341     scalar_type &
0342     write_element( this_vector & x )
0343         {
0344         BOOST_QVM_STATIC_ASSERT(I>=0);
0345         BOOST_QVM_STATIC_ASSERT(I<dim);
0346         int const idx=qvm_detail::swizzle<SwizzleList,I>::value;
0347         BOOST_QVM_STATIC_ASSERT(idx<1);
0348         return reinterpret_cast<OriginalScalar &>(x);
0349         }
0350     };
0351 
0352 template <class OriginalVector,class SwizzleList,int D>
0353 struct
0354 deduce_vec<qvm_detail::sw_<OriginalVector,SwizzleList>,D>
0355     {
0356     typedef vec<typename vec_traits<OriginalVector>::scalar_type,D> type;
0357     };
0358 
0359 template <class OriginalVector,class SwizzleList,int D>
0360 struct
0361 deduce_vec2<qvm_detail::sw_<OriginalVector,SwizzleList>,qvm_detail::sw_<OriginalVector,SwizzleList>,D>
0362     {
0363     typedef vec<typename vec_traits<OriginalVector>::scalar_type,D> type;
0364     };
0365 
0366 template <class Scalar,class SwizzleList,int D>
0367 struct
0368 deduce_vec<qvm_detail::sws_<Scalar,SwizzleList>,D>
0369     {
0370     typedef vec<Scalar,D> type;
0371     };
0372 
0373 template <class Scalar,class SwizzleList,int D>
0374 struct
0375 deduce_vec2<qvm_detail::sws_<Scalar,SwizzleList>,qvm_detail::sws_<Scalar,SwizzleList>,D>
0376     {
0377     typedef vec<Scalar,D> type;
0378     };
0379 
0380 } }
0381 
0382 #endif