1 /*
2  * Copyright 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <math/vec3.h>
20 #include <math/half.h>
21 #include <stdint.h>
22 #include <sys/types.h>
23 
24 #pragma clang diagnostic push
25 #pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
26 #pragma clang diagnostic ignored "-Wnested-anon-types"
27 
28 namespace android {
29 // -------------------------------------------------------------------------------------
30 
31 namespace details {
32 
33 template <typename T>
34 class  TVec4 :  public TVecProductOperators<TVec4, T>,
35                 public TVecAddOperators<TVec4, T>,
36                 public TVecUnaryOperators<TVec4, T>,
37                 public TVecComparisonOperators<TVec4, T>,
38                 public TVecFunctions<TVec4, T>,
39                 public TVecDebug<TVec4, T> {
40 public:
41     enum no_init { NO_INIT };
42     typedef T value_type;
43     typedef T& reference;
44     typedef T const& const_reference;
45     typedef size_t size_type;
46 
47     union {
48         struct { T x, y, z, w; };
49         struct { T s, t, p, q; };
50         struct { T r, g, b, a; };
51         TVec2<T> xy;
52         TVec2<T> st;
53         TVec2<T> rg;
54         TVec3<T> xyz;
55         TVec3<T> stp;
56         TVec3<T> rgb;
57     };
58 
59     static constexpr size_t SIZE = 4;
size()60     inline constexpr size_type size() const { return SIZE; }
61 
62     // array access
63     inline constexpr T const& operator[](size_t i) const {
64 #if __cplusplus >= 201402L
65         // only possible in C++0x14 with constexpr
66         assert(i < SIZE);
67 #endif
68         return (&x)[i];
69     }
70 
71     inline T& operator[](size_t i) {
72         assert(i < SIZE);
73         return (&x)[i];
74     }
75 
76     // -----------------------------------------------------------------------
77     // we want the compiler generated versions for these...
78     TVec4(const TVec4&) = default;
79     ~TVec4() = default;
80     TVec4& operator = (const TVec4&) = default;
81 
82     // constructors
83 
84     // leaves object uninitialized. use with caution.
85     explicit
TVec4(no_init)86     constexpr TVec4(no_init) { }
87 
88     // default constructor
TVec4()89     constexpr TVec4() : x(0), y(0), z(0), w(0) { }
90 
91     // handles implicit conversion to a tvec4. must not be explicit.
92     template<typename A, typename = typename std::enable_if<std::is_arithmetic<A>::value >::type>
TVec4(A v)93     constexpr TVec4(A v) : x(v), y(v), z(v), w(v) { }
94 
95     template<typename A, typename B, typename C, typename D>
TVec4(A x,B y,C z,D w)96     constexpr TVec4(A x, B y, C z, D w) : x(x), y(y), z(z), w(w) { }
97 
98     template<typename A, typename B, typename C>
TVec4(const TVec2<A> & v,B z,C w)99     constexpr TVec4(const TVec2<A>& v, B z, C w) : x(v.x), y(v.y), z(z), w(w) { }
100 
101     template<typename A, typename B>
TVec4(const TVec3<A> & v,B w)102     constexpr TVec4(const TVec3<A>& v, B w) : x(v.x), y(v.y), z(v.z), w(w) { }
103 
104     template<typename A>
105     explicit
TVec4(const TVec4<A> & v)106     constexpr TVec4(const TVec4<A>& v) : x(v.x), y(v.y), z(v.z), w(v.w) { }
107 };
108 
109 }  // namespace details
110 
111 // ----------------------------------------------------------------------------------------
112 
113 typedef details::TVec4<double> double4;
114 typedef details::TVec4<float> float4;
115 typedef details::TVec4<float> vec4;
116 typedef details::TVec4<half> half4;
117 typedef details::TVec4<int32_t> int4;
118 typedef details::TVec4<uint32_t> uint4;
119 typedef details::TVec4<int16_t> short4;
120 typedef details::TVec4<uint16_t> ushort4;
121 typedef details::TVec4<int8_t> byte4;
122 typedef details::TVec4<uint8_t> ubyte4;
123 typedef details::TVec4<bool> bool4;
124 
125 // ----------------------------------------------------------------------------------------
126 }  // namespace android
127 
128 #pragma clang diagnostic pop
129