Update copyright year to 2015 for public api: core
[platform/core/uifw/dali-core.git] / dali / public-api / math / uint-16-pair.h
1 #ifndef __DALI_UINT_16_PAIR_H__
2 #define __DALI_UINT_16_PAIR_H__
3
4 /*
5  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <stdint.h>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-common.h>
26
27 namespace Dali
28 {
29
30 /**
31  * @brief Simple class for passing around pairs of small unsigned integers.
32  *
33  * Use this for integer dimensions and points with limited range such as image
34  * sizes and pixel coordinates where a pair of floating point numbers is
35  * inefficient and illogical (i.e. the data is inherently integer).
36  * These are immutable. If you want to change a value, make a whole new object.
37  * One of these can be passed in a single 32 bit integer register on
38  * common architectures.
39  */
40 class Uint16Pair
41 {
42 public:
43   /**
44    * @brief Default constructor for the (0, 0) vector.
45    */
46   Uint16Pair() : mData(0) {}
47
48   /**
49    * @brief Constructor taking separate x and y (width and height) parameters.
50    * @param[in] width The width or X dimension of the vector. Make sure it is less than 65536,
51    * @param[in] height The height or Y dimension of the vector. Make sure it is less than 65536,
52    */
53   Uint16Pair( uint32_t width, uint32_t height )
54   {
55     DALI_ASSERT_DEBUG( width < ( 1u << 16 ) && "Width parameter not representable." );
56     DALI_ASSERT_DEBUG( height < ( 1u << 16 ) && "Height parameter not representable." );
57
58     /* Do equivalent of the code below with one aligned memory access:
59      * mComponents[0] = width;
60      * mComponents[1] = height;
61      * Unit tests make sure this is equivalent.
62      **/
63     mData = (height << 16u) + width;
64   }
65
66   /**
67    * @brief Copy constructor.
68    */
69   Uint16Pair( const Uint16Pair& rhs )
70   {
71     mData = rhs.mData;
72   }
73
74   /**
75    * @returns the x dimension stored in this 2-tuple.
76    */
77   uint16_t GetWidth() const
78   {
79     return mComponents[0];
80   }
81
82   /**
83    * @returns the y dimension stored in this 2-tuple.
84    */
85   uint16_t GetHeight() const
86   {
87     return mComponents[1];
88   }
89
90   /**
91    * @returns the x dimension stored in this 2-tuple.
92    */
93   uint16_t GetX()  const
94   {
95     return mComponents[0];
96   }
97
98   /**
99    * @returns the y dimension stored in this 2-tuple.
100    */
101   uint16_t GetY() const
102   {
103     return mComponents[1];
104   }
105
106   /**
107    * Equality operator.
108    */
109   bool operator==( const Uint16Pair& rhs ) const
110   {
111     return mData == rhs.mData;
112   }
113
114   /**
115    * Inequality operator.
116    */
117   bool operator!=( const Uint16Pair& rhs ) const
118   {
119     return mData != rhs.mData;
120   }
121
122   /**
123    * Less than comparison operator for storing in collections (not geometrically
124    * meaningful).
125    */
126   bool operator<( const Uint16Pair& rhs ) const
127   {
128     return mData < rhs.mData;
129   }
130
131   /**
132    * Greater than comparison operator for storing in collections (not
133    * geometrically meaningful).
134    */
135   bool operator>( const Uint16Pair& rhs ) const
136   {
137     return mData > rhs.mData;
138   }
139
140   /**
141    * @brief Create an instance by rounding a floating point vector to closest
142    * integers.
143    *
144    * Uses a template for loose coupling, to save a header include, and allow any
145    * vector type with .x and .y members to be converted.
146    */
147   template<typename FLOAT_VECTOR_N_TYPE>
148   static Uint16Pair FromFloatVec2( const FLOAT_VECTOR_N_TYPE& from )
149   {
150     DALI_ASSERT_DEBUG( from.x + 0.5f < 65536.0f );
151     DALI_ASSERT_DEBUG( from.y + 0.5f < 65536.0f );
152     return Uint16Pair( from.x + 0.5f, from.y + 0.5f );
153   }
154
155   /**
156    * @brief Create an instance by rounding a floating point array to closest
157    * integers.
158    *
159    * Uses a template to allow any vector type with operator [] to be converted
160    * in addition to plain arrays.
161    */
162   template<typename FLOAT_ARRAY>
163   static Uint16Pair FromFloatArray( const FLOAT_ARRAY& from )
164   {
165     DALI_ASSERT_DEBUG( from[0] + 0.5f < 65536.0f );
166     DALI_ASSERT_DEBUG( from[1] + 0.5f < 65536.0f );
167     return Uint16Pair( from[0] + 0.5f, from[1] + 0.5f );
168   }
169
170 private:
171   union
172   {
173     // Addressable view of X and Y:
174     uint16_t mComponents[2];
175     // Packed view of X and Y to force alignment and allow a faster copy:
176     uint32_t mData;
177   };
178 };
179
180 } // namespace Dali
181
182 #endif // __DALI_UINT_16_PAIR_H__