TVecHelpers.h revision 1d4d8f94e2989b7c8667602304df9059d2701653
1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/*
27b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines * Copyright 2013 The Android Open Source Project
3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License.
6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at
7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *      http://www.apache.org/licenses/LICENSE-2.0
9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang *
10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software
11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and
14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License.
15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */
16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang
176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#ifndef TVEC_IMPLEMENTATION
18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#error "Don't include TVecHelpers.h directly. use ui/vec*.h instead"
196315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#else
20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#undef TVEC_IMPLEMENTATION
21e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#endif
22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
24462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao#ifndef UI_TVEC_HELPERS_H
259ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#define UI_TVEC_HELPERS_H
269ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
279ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include <stdint.h>
28e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <sys/types.h>
29e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#define PURE __attribute__((pure))
31462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
326315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonrnamespace android {
336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr// -------------------------------------------------------------------------------------
346e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines
35592a954aae4cb946970b557e94afd5ee453fd57eZonr Chang/*
366315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr * No user serviceable parts here.
374ccf75e55fe460a8daa49247d7e5a797329c71a6Stephen Hines *
386315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr * Don't use this file directly, instead include ui/vec{2|3|4}.h
396315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr */
40e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
41e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines/*
42462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * This class casts itself into anything and assign itself from anything!
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines * Use with caution!
44462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */
459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaotemplate <typename TYPE>
469207a2e495c8363606861e4f034504ec5c153dabLogan Chienstruct Impersonator {
479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    Impersonator& operator = (const TYPE& rhs) {
489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        reinterpret_cast<TYPE&>(*this) = rhs;
493fd0a94a5cf1656569b1aea07043cc63939dcb46Stephen Hines        return *this;
509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
513a9ca1f0d6bd8f12c2bb2adea51f95c255996180Zonr Chang    operator TYPE& () {
529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return reinterpret_cast<TYPE&>(*this);
534a4bf92a8add68629a7e6e59ef81c3c3fe603a75Stephen Hines    }
549207a2e495c8363606861e4f034504ec5c153dabLogan Chien    operator TYPE const& () const {
559207a2e495c8363606861e4f034504ec5c153dabLogan Chien        return reinterpret_cast<TYPE const&>(*this);
569207a2e495c8363606861e4f034504ec5c153dabLogan Chien    }
579207a2e495c8363606861e4f034504ec5c153dabLogan Chien};
589207a2e495c8363606861e4f034504ec5c153dabLogan Chien
599207a2e495c8363606861e4f034504ec5c153dabLogan Chien/*
607b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments
617b51b55e4467605a599e868a0dde7cb95c5ab76eStephen Hines * operators on a vector of type BASE<T>.
629207a2e495c8363606861e4f034504ec5c153dabLogan Chien *
639207a2e495c8363606861e4f034504ec5c153dabLogan Chien * BASE only needs to implement operator[] and size().
649207a2e495c8363606861e4f034504ec5c153dabLogan Chien * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically
65462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * get all the functionality here.
66462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao */
67cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines
68cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinestemplate <template<typename T> class BASE, typename T>
69cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinesclass TVecAddOperators {
70cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hinespublic:
71cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    /* compound assignment from a another vector of the same size but different
72d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines     * element type.
734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines     */
74cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    template <typename OTHER>
75cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    BASE<T>& operator += (const BASE<OTHER>& v) {
76cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
77cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
78fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chien            rhs[i] += v[i];
79cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        }
80cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        return rhs;
81cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    }
82cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    template <typename OTHER>
83cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    BASE<T>& operator -= (const BASE<OTHER>& v) {
84ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
85cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
86cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines            rhs[i] -= v[i];
87cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        }
88cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        return rhs;
89cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    }
909207a2e495c8363606861e4f034504ec5c153dabLogan Chien
919207a2e495c8363606861e4f034504ec5c153dabLogan Chien    /* compound assignment from a another vector of the same type.
929207a2e495c8363606861e4f034504ec5c153dabLogan Chien     * These operators can be used for implicit conversion and  handle operations
939207a2e495c8363606861e4f034504ec5c153dabLogan Chien     * like "vector *= scalar" by letting the compiler implicitly convert a scalar
949207a2e495c8363606861e4f034504ec5c153dabLogan Chien     * to a vector (assuming the BASE<T> allows it).
959207a2e495c8363606861e4f034504ec5c153dabLogan Chien     */
96cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    BASE<T>& operator += (const BASE<T>& v) {
97cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
98cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
99cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines            rhs[i] += v[i];
100cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        }
101ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien        return rhs;
102eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    }
103eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    BASE<T>& operator -= (const BASE<T>& v) {
104eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
105cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
106cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines            rhs[i] -= v[i];
107fa6ef56a6ca3dc3061218a75a7e68e5357fcb82cLogan Chien        }
108cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines        return rhs;
109cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines    }
110c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
111c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    /*
11278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines     * NOTE: the functions below ARE NOT member methods. They are friend functions
11378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines     * with they definition inlined with their declaration. This makes these
11478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines     * template functions available to the compiler when (and only when) this class
11578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines     * is instantiated, at which point they're only templated on the 2nd parameter
11678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines     * (the first one, BASE<T> being known).
11778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines     */
118c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines
11978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    /* The operators below handle operation between vectors of the same side
12078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines     * but of a different element type.
12178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines     */
12278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    template<typename RT>
12378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    friend inline
12478e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    BASE<T> PURE operator +(const BASE<T>& lv, const BASE<RT>& rv) {
12578e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines        return BASE<T>(lv) += rv;
126c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    }
12778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    template<typename RT>
12878e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    friend inline
12978e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    BASE<T> PURE operator -(const BASE<T>& lv, const BASE<RT>& rv) {
130c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines        return BASE<T>(lv) -= rv;
131c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    }
13278e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines
133c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    /* The operators below (which are not templates once this class is instanced,
134fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines     * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
135c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines     * These handle operations like "vector * scalar" and "scalar * vector" by
136c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines     * letting the compiler implicitly convert a scalar to a vector (assuming
137c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines     * the BASE<T> allows it).
138c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines     */
139ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien    friend inline
14078e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines    BASE<T> PURE operator +(const BASE<T>& lv, const BASE<T>& rv) {
14178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines        return BASE<T>(lv) += rv;
142c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    }
143c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    friend inline
144c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    BASE<T> PURE operator -(const BASE<T>& lv, const BASE<T>& rv) {
145c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines        return BASE<T>(lv) -= rv;
146c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    }
147c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines};
148e5e64432476a44b59c61ded233b1149109c7a7c3Stephen Hines
149c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinestemplate <template<typename T> class BASE, typename T>
150c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinesclass TVecProductOperators {
151c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hinespublic:
152c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    /* compound assignment from a another vector of the same size but different
15378e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines     * element type.
154c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines     */
155c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines    template <typename OTHER>
156fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    BASE<T>& operator *= (const BASE<OTHER>& v) {
15796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
15896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
15996ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines            rhs[i] *= v[i];
1607aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        }
1617aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        return rhs;
1627aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    }
1637aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    template <typename OTHER>
1647aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines    BASE<T>& operator /= (const BASE<OTHER>& v) {
1657aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
1667aff4a0a124209fdf93ecbcd7aed701d39ba094bStephen Hines        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
16796ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines            rhs[i] /= v[i];
16896ab06cbe40b2d73c0eb614f814cd761d8962b6bStephen Hines        }
169688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines        return rhs;
170688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    }
171688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines
172688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines    /* compound assignment from a another vector of the same type.
173688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines     * These operators can be used for implicit conversion and  handle operations
174688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines     * like "vector *= scalar" by letting the compiler implicitly convert a scalar
175688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines     * to a vector (assuming the BASE<T> allows it).
176cfae0f350e4e0d8f7b4c71780b3f74f58fa23afbStephen Hines     */
177fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines    BASE<T>& operator *= (const BASE<T>& v) {
178fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
179fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
180fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines            rhs[i] *= v[i];
181ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien        }
182eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines        return rhs;
183eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    }
184eb2eec96b5f19778ac1b7aebe6a91bbcb8d4df96Stephen Hines    BASE<T>& operator /= (const BASE<T>& v) {
185fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
186fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
187fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines            rhs[i] /= v[i];
188fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        }
189fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines        return rhs;
190462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao    }
191fcda2352b9e140529f8f3c89f05b10a70c0048b2Stephen Hines
19268fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang    /*
193c808a99831115928b4648f4c8b86dc682594217aStephen Hines     * NOTE: the functions below ARE NOT member methods. They are friend functions
194c97a333bc84ce8c28c96d07734cbded75c914639Stephen Hines     * with they definition inlined with their declaration. This makes these
195c808a99831115928b4648f4c8b86dc682594217aStephen Hines     * template functions available to the compiler when (and only when) this class
1969ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * is instantiated, at which point they're only templated on the 2nd parameter
1979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * (the first one, BASE<T> being known).
1989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     */
199b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
2009ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    /* The operators below handle operation between vectors of the same side
20168fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang     * but of a different element type.
2029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     */
2039ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    template<typename RT>
204b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    friend inline
205b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    BASE<T> PURE operator *(const BASE<T>& lv, const BASE<RT>& rv) {
206b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        return BASE<T>(lv) *= rv;
2079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2086315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    template<typename RT>
2096315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    friend inline
2106315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    BASE<T> PURE operator /(const BASE<T>& lv, const BASE<RT>& rv) {
2116315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr        return BASE<T>(lv) /= rv;
2126315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    }
2136315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
214b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    /* The operators below (which are not templates once this class is instanced,
2159ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
2169ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * These handle operations like "vector * scalar" and "scalar * vector" by
2179ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * letting the compiler implicitly convert a scalar to a vector (assuming
2189ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * the BASE<T> allows it).
2199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     */
2209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    friend inline
221a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang    BASE<T> PURE operator *(const BASE<T>& lv, const BASE<T>& rv) {
222a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        return BASE<T>(lv) *= rv;
223b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    }
224b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    friend inline
225a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang    BASE<T> PURE operator /(const BASE<T>& lv, const BASE<T>& rv) {
226a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        return BASE<T>(lv) /= rv;
227b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    }
228b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines};
229b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
230b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines/*
231a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang * TVecUnaryOperators implements unary operators on a vector of type BASE<T>.
232a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang *
233a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang * BASE only needs to implement operator[] and size().
234a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically
235a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang * get all the functionality here.
2369ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao *
237a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T>
238a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang */
239a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Changtemplate <template<typename T> class BASE, typename T>
240a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Changclass TVecUnaryOperators {
241a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Changpublic:
242a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang    BASE<T>& operator ++ () {
243a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
244a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
245a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang            ++rhs[i];
246a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
247a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        return rhs;
248a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang    }
249a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang    BASE<T>& operator -- () {
250a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
251a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
252a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang            --rhs[i];
253a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        }
254a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang        return rhs;
255a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang    }
256a65ec168e41e3ee9c6e8ac04cde694bbbfc2590aZonr Chang    BASE<T> operator - () const {
2579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        BASE<T> r(BASE<T>::NO_INIT);
2589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        BASE<T> const& rv(static_cast<BASE<T> const&>(*this));
259d27a74edb932580d224a7186731aa6be098ad02eStephen Hines        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
2609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            r[i] = -rv[i];
261b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        }
262b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines        return r;
263b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines    }
264b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines};
265b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
266b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines
267b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines/*
268d27a74edb932580d224a7186731aa6be098ad02eStephen Hines * TVecComparisonOperators implements relational/comparison operators
269d27a74edb932580d224a7186731aa6be098ad02eStephen Hines * on a vector of type BASE<T>.
270b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines *
271b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines * BASE only needs to implement operator[] and size().
272b3a12fe7c18a06f99201dc491a932a90ab7d975cStephen Hines * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically
273462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao * get all the functionality here.
2749ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao */
2759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaotemplate <template<typename T> class BASE, typename T>
2769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaoclass TVecComparisonOperators {
2779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liaopublic:
2789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    /*
2799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * NOTE: the functions below ARE NOT member methods. They are friend functions
28068fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang     * with they definition inlined with their declaration. This makes these
2819ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * template functions available to the compiler when (and only when) this class
2829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * is instantiated, at which point they're only templated on the 2nd parameter
2839ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * (the first one, BASE<T> being known).
2846315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr     */
2856315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    template<typename RT>
2866315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    friend inline
2879ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    bool PURE operator ==(const BASE<T>& lv, const BASE<RT>& rv) {
2889ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        for (size_t i = 0; i < BASE<T>::size(); i++)
2896315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr            if (lv[i] != rv[i])
2909ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                return false;
2919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return true;
2926315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    }
2936315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr
2946315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    template<typename RT>
2956315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr    friend inline
29668fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang    bool PURE operator !=(const BASE<T>& lv, const BASE<RT>& rv) {
2979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return !operator ==(lv, rv);
2989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
2999ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3006e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines    template<typename RT>
3019ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    friend inline
3029ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    bool PURE operator >(const BASE<T>& lv, const BASE<RT>& rv) {
303462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao        for (size_t i = 0; i < BASE<T>::size(); i++)
3040da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (lv[i] <= rv[i])
3050da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                return false;
3060da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang        return true;
3077c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao    }
3080da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3090da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    template<typename RT>
3100da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    friend inline
3110da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    bool PURE operator <=(const BASE<T>& lv, const BASE<RT>& rv) {
3120da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang        return !(lv > rv);
313a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines    }
3140da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3150da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    template<typename RT>
3160da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    friend inline
3170da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    bool PURE operator <(const BASE<T>& lv, const BASE<RT>& rv) {
3180da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang        for (size_t i = 0; i < BASE<T>::size(); i++)
3190da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang            if (lv[i] >= rv[i])
3200da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang                return false;
3210da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang        return true;
3220da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    }
3230da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3240da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    template<typename RT>
3250da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    friend inline
3260da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    bool PURE operator >=(const BASE<T>& lv, const BASE<RT>& rv) {
3270da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang        return !(lv < rv);
3280da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    }
3290da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang};
3300da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3310da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3327c67e578c760408dba0c2f64da6e074dd8b56fd9Shih-wei Liao/*
3330da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang * TVecFunctions implements functions on a vector of type BASE<T>.
3340da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang *
3350da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang * BASE only needs to implement operator[] and size().
3360da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically
3370da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang * get all the functionality here.
3389ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao */
3390da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Changtemplate <template<typename T> class BASE, typename T>
3400da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Changclass TVecFunctions {
341a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hinespublic:
3420da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang    /*
3439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * NOTE: the functions below ARE NOT member methods. They are friend functions
3449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * with they definition inlined with their declaration. This makes these
3459ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * template functions available to the compiler when (and only when) this class
3469ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * is instantiated, at which point they're only templated on the 2nd parameter
3479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao     * (the first one, BASE<T> being known).
34868fc02ca4a7235e2981be5eee4ad968a9d3928c0Zonr Chang     */
3499ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    template<typename RT>
3509ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    friend inline
3519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    T PURE dot(const BASE<T>& lv, const BASE<RT>& rv) {
3529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        T r(0);
3539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        for (size_t i = 0; i < BASE<T>::size(); i++)
3549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao            r += lv[i]*rv[i];
3559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return r;
3569ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3589ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    friend inline
3599ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    T PURE length(const BASE<T>& lv) {
3609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return sqrt( dot(lv, lv) );
3619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3629ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3639ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    template<typename RT>
3649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    friend inline
3659ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    T PURE distance(const BASE<T>& lv, const BASE<RT>& rv) {
3669ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao        return length(rv - lv);
3679ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    }
3680da0a7dc51c25943fe31d0bfccbdfee326a3199cZonr Chang
3699ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    friend inline
3709207a2e495c8363606861e4f034504ec5c153dabLogan Chien    BASE<T> PURE normalize(const BASE<T>& lv) {
3719207a2e495c8363606861e4f034504ec5c153dabLogan Chien        return lv * (1 / length(lv));
3729207a2e495c8363606861e4f034504ec5c153dabLogan Chien    }
3739207a2e495c8363606861e4f034504ec5c153dabLogan Chien};
3749207a2e495c8363606861e4f034504ec5c153dabLogan Chien
3759ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#undef PURE
3769ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
3779ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao// -------------------------------------------------------------------------------------
3789ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao}; // namespace android
3799ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao
380462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao
381a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines#endif /* UI_TVEC_HELPERS_H */
382a67e4451d0d03b4ab7866b64807d95a8399c73a0Stephen Hines