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
28namespace android {
29// -------------------------------------------------------------------------------------
30
31namespace details {
32
33template <typename T>
34class  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> {
40public:
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;
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
86    constexpr TVec4(no_init) { }
87
88    // default constructor
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>
93    constexpr TVec4(A v) : x(v), y(v), z(v), w(v) { }
94
95    template<typename A, typename B, typename C, typename D>
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>
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>
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
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
113typedef details::TVec4<double> double4;
114typedef details::TVec4<float> float4;
115typedef details::TVec4<float> vec4;
116typedef details::TVec4<half> half4;
117typedef details::TVec4<int32_t> int4;
118typedef details::TVec4<uint32_t> uint4;
119typedef details::TVec4<int16_t> short4;
120typedef details::TVec4<uint16_t> ushort4;
121typedef details::TVec4<int8_t> byte4;
122typedef details::TVec4<uint8_t> ubyte4;
123typedef details::TVec4<bool> bool4;
124
125// ----------------------------------------------------------------------------------------
126}  // namespace android
127
128#pragma clang diagnostic pop
129