Doxygen grouping
[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  * @addtogroup dali-core-math
31  * @{
32  */
33
34 /**
35  * @brief Simple class for passing around pairs of small unsigned integers.
36  *
37  * Use this for integer dimensions and points with limited range such as image
38  * sizes and pixel coordinates where a pair of floating point numbers is
39  * inefficient and illogical (i.e. the data is inherently integer).
40  * These are immutable. If you want to change a value, make a whole new object.
41  * One of these can be passed in a single 32 bit integer register on
42  * common architectures.
43  */
44 class Uint16Pair
45 {
46 public:
47   /**
48    * @brief Default constructor for the (0, 0) vector.
49    */
50   Uint16Pair() : mData(0) {}
51
52   /**
53    * @brief Constructor taking separate x and y (width and height) parameters.
54    * @param[in] width The width or X dimension of the vector. Make sure it is less than 65536,
55    * @param[in] height The height or Y dimension of the vector. Make sure it is less than 65536,
56    */
57   Uint16Pair( uint32_t width, uint32_t height )
58   {
59     DALI_ASSERT_DEBUG( width < ( 1u << 16 ) && "Width parameter not representable." );
60     DALI_ASSERT_DEBUG( height < ( 1u << 16 ) && "Height parameter not representable." );
61
62     /* Do equivalent of the code below with one aligned memory access:
63      * mComponents[0] = width;
64      * mComponents[1] = height;
65      * Unit tests make sure this is equivalent.
66      **/
67     mData = (height << 16u) + width;
68   }
69
70   /**
71    * @brief Copy constructor.
72    */
73   Uint16Pair( const Uint16Pair& rhs )
74   {
75     mData = rhs.mData;
76   }
77
78   /**
79    * @returns the x dimension stored in this 2-tuple.
80    */
81   uint16_t GetWidth() const
82   {
83     return mComponents[0];
84   }
85
86   /**
87    * @returns the y dimension stored in this 2-tuple.
88    */
89   uint16_t GetHeight() const
90   {
91     return mComponents[1];
92   }
93
94   /**
95    * @returns the x dimension stored in this 2-tuple.
96    */
97   uint16_t GetX()  const
98   {
99     return mComponents[0];
100   }
101
102   /**
103    * @returns the y dimension stored in this 2-tuple.
104    */
105   uint16_t GetY() const
106   {
107     return mComponents[1];
108   }
109
110   /**
111    * Equality operator.
112    */
113   bool operator==( const Uint16Pair& rhs ) const
114   {
115     return mData == rhs.mData;
116   }
117
118   /**
119    * Inequality operator.
120    */
121   bool operator!=( const Uint16Pair& rhs ) const
122   {
123     return mData != rhs.mData;
124   }
125
126   /**
127    * Less than comparison operator for storing in collections (not geometrically
128    * meaningful).
129    */
130   bool operator<( const Uint16Pair& rhs ) const
131   {
132     return mData < rhs.mData;
133   }
134
135   /**
136    * Greater than comparison operator for storing in collections (not
137    * geometrically meaningful).
138    */
139   bool operator>( const Uint16Pair& rhs ) const
140   {
141     return mData > rhs.mData;
142   }
143
144   /**
145    * @brief Create an instance by rounding a floating point vector to closest
146    * integers.
147    *
148    * Uses a template for loose coupling, to save a header include, and allow any
149    * vector type with .x and .y members to be converted.
150    */
151   template<typename FLOAT_VECTOR_N_TYPE>
152   static Uint16Pair FromFloatVec2( const FLOAT_VECTOR_N_TYPE& from )
153   {
154     DALI_ASSERT_DEBUG( from.x + 0.5f < 65536.0f );
155     DALI_ASSERT_DEBUG( from.y + 0.5f < 65536.0f );
156     return Uint16Pair( from.x + 0.5f, from.y + 0.5f );
157   }
158
159   /**
160    * @brief Create an instance by rounding a floating point array to closest
161    * integers.
162    *
163    * Uses a template to allow any vector type with operator [] to be converted
164    * in addition to plain arrays.
165    */
166   template<typename FLOAT_ARRAY>
167   static Uint16Pair FromFloatArray( const FLOAT_ARRAY& from )
168   {
169     DALI_ASSERT_DEBUG( from[0] + 0.5f < 65536.0f );
170     DALI_ASSERT_DEBUG( from[1] + 0.5f < 65536.0f );
171     return Uint16Pair( from[0] + 0.5f, from[1] + 0.5f );
172   }
173
174 private:
175   union
176   {
177     // Addressable view of X and Y:
178     uint16_t mComponents[2];
179     // Packed view of X and Y to force alignment and allow a faster copy:
180     uint32_t mData;
181   };
182 };
183
184 /**
185  * @}
186  */
187 } // namespace Dali
188
189 #endif // __DALI_UINT_16_PAIR_H__