Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:49:23

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