Ensure BaseHandle class move noexcept (core public-api)
[platform/core/uifw/dali-core.git] / dali / public-api / math / int-pair.h
1 #ifndef DALI_INT_PAIR_H
2 #define DALI_INT_PAIR_H
3
4 /*
5  * Copyright (c) 2022 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 <cstdint>
23 #include <type_traits>
24
25 // INTERNAL INCLUDES
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/common/type-traits.h>
28
29 namespace Dali
30 {
31 /**
32  * @addtogroup dali_core_math
33  * @{
34  */
35
36 /**
37  * @brief Simple class for passing around pairs of small integers.
38  *
39  * Use this for integer dimensions and points with limited range such as image
40  * sizes and pixel coordinates where a pair of floating point numbers is
41  * inefficient and illogical (i.e. the data is inherently integer).
42  *
43  * For example in IntPair<uint16_t>
44  * one of these can be passed in a single 32 bit integer register on
45  * common architectures.
46  *
47  * @SINCE_2_1.45
48  * @tparam Bits The number of bits. It should be 8, 16, or 32.
49  * @tparam IsSigned Determine whether we use signed integer or not.
50  */
51 template<unsigned Bits, bool IsSigned, typename = std::enable_if_t<(Bits == 8 || Bits == 16 || Bits == 32)>>
52 class IntPair
53 {
54 public:
55   // Type definition.
56
57   /**
58    * @brief Integer type for get/set access.
59    * @SINCE_2_1.45
60    */
61   using IntType = typename std::conditional<Bits == 8, typename std::conditional<IsSigned, int8_t, uint8_t>::type, typename std::conditional<Bits == 16, typename std::conditional<IsSigned, int16_t, uint16_t>::type, typename std::conditional<IsSigned, int32_t, uint32_t>::type>::type>::type;
62
63   /**
64    * @brief Unsigned integer type that will be stored.
65    * Signed integer bit shift is implementation-defined behaviour.
66    * To more safty works, we need to cast from IntType to UintType before store data.
67    * @SINCE_2_1.45
68    */
69   using UintType = typename std::conditional<Bits == 8, uint8_t, typename std::conditional<Bits == 16, uint16_t, uint32_t>::type>::type;
70
71   /**
72    * @brief 2-tuple stored integer type.
73    * @SINCE_2_1.45
74    */
75   using DataType = typename std::conditional<Bits == 8, uint16_t, typename std::conditional<Bits == 16, uint32_t, uint64_t>::type>::type;
76
77 public:
78   /**
79    * @brief Default constructor for the (0, 0) tuple.
80    * @SINCE_2_1.45
81    */
82   constexpr IntPair()
83   : mData(0)
84   {
85   }
86
87   /**
88    * @brief Constructor taking separate x and y (width and height) parameters.
89    * @SINCE_2_1.45
90    * @param[in] width The width or X dimension of the tuple.
91    * @param[in] height The height or Y dimension of the tuple.
92    */
93   constexpr IntPair(IntType width, IntType height)
94   {
95     /* Do equivalent of the code below with one aligned memory access:
96      * mComponents[0] = width;
97      * mComponents[1] = height;
98      * Unit tests make sure this is equivalent.
99      **/
100     mData = (static_cast<DataType>(static_cast<UintType>(height)) << Bits) | static_cast<DataType>(static_cast<UintType>(width));
101   }
102
103   /**
104    * @brief Sets the width.
105    * @SINCE_2_1.45
106    * @param[in] width The x dimension to be stored in this 2-tuple
107    */
108   void SetWidth(IntType width)
109   {
110     mComponents[0] = width;
111   }
112
113   /**
114    * @brief Get the width.
115    * @SINCE_2_1.45
116    * @return the x dimension stored in this 2-tuple
117    */
118   IntType GetWidth() const
119   {
120     return mComponents[0];
121   }
122
123   /**
124    * @brief Sets the height.
125    * @SINCE_2_1.45
126    * @param[in] height The y dimension to be stored in this 2-tuple
127    */
128   void SetHeight(IntType height)
129   {
130     mComponents[1] = height;
131   }
132
133   /**
134    * @brief Returns the y dimension stored in this 2-tuple.
135    * @SINCE_2_1.45
136    * @return Height
137    */
138   IntType GetHeight() const
139   {
140     return mComponents[1];
141   }
142
143   /**
144    * @brief Sets the x dimension (same as width).
145    * @SINCE_2_1.45
146    * @param[in] x The x dimension to be stored in this 2-tuple
147    */
148   void SetX(IntType x)
149   {
150     mComponents[0] = x;
151   }
152
153   /**
154    * @brief Returns the x dimension stored in this 2-tuple.
155    * @SINCE_2_1.45
156    * @return X
157    */
158   IntType GetX() const
159   {
160     return mComponents[0];
161   }
162
163   /**
164    * @brief Sets the y dimension (same as height).
165    * @SINCE_2_1.45
166    * @param[in] y The y dimension to be stored in this 2-tuple
167    */
168   void SetY(IntType y)
169   {
170     mComponents[1] = y;
171   }
172
173   /**
174    * @brief Returns the y dimension stored in this 2-tuple.
175    * @SINCE_2_1.45
176    * @return Y
177    */
178   IntType GetY() const
179   {
180     return mComponents[1];
181   }
182
183   /**
184    * @brief Equality operator.
185    * @SINCE_2_1.45
186    * @param[in] rhs A reference for comparison
187    * @return True if same
188    */
189   bool operator==(const IntPair& rhs) const
190   {
191     return mData == rhs.mData;
192   }
193
194   /**
195    * @brief Inequality operator.
196    * @SINCE_2_1.45
197    * @param[in] rhs A reference for comparison
198    * @return True if different
199    */
200   bool operator!=(const IntPair& rhs) const
201   {
202     return mData != rhs.mData;
203   }
204
205   /**
206    * @brief Less than comparison operator for storing in collections (not geometrically
207    * meaningful).
208    * @SINCE_2_1.45
209    * @param[in] rhs A reference for comparison
210    * @return True if less
211    */
212   bool operator<(const IntPair& rhs) const
213   {
214     return mData < rhs.mData;
215   }
216
217   /**
218    * @brief Greater than comparison operator for storing in collections (not
219    * geometrically meaningful).
220    * @SINCE_2_1.45
221    * @param[in] rhs A reference for comparison
222    * @return True if greater
223    */
224   bool operator>(const IntPair& rhs) const
225   {
226     return mData > rhs.mData;
227   }
228
229 public:
230   IntPair(const IntPair&)     = default;            ///< Default copy constructor
231   IntPair(IntPair&&) noexcept = default;            ///< Default move constructor
232   IntPair& operator=(const IntPair&) = default;     ///< Default copy assignment operator
233   IntPair& operator=(IntPair&&) noexcept = default; ///< Default move assignment operator
234
235 private:
236   union
237   {
238     // Addressable view of X and Y:
239     IntType mComponents[2];
240     // Packed view of X and Y to force alignment and allow a faster copy:
241     DataType mData;
242   };
243 };
244
245 /**
246  * @brief Simple class for passing around pairs of signed integers.
247  *
248  * Use this for integer dimensions and points with limited range such as window
249  * position and screen coordinates where a pair of floating point numbers is
250  * inefficient and illogical (i.e. the data is inherently integer).
251  * One of these can be passed in a single 64 bit integer.
252  * @SINCE_2_1.45
253  */
254 class Int32Pair : public IntPair<32, true>
255 {
256 public:
257   /**
258    * @brief Default constructor for the (0, 0) tuple.
259    * @SINCE_2_1.45
260    */
261   constexpr Int32Pair() = default;
262
263   /**
264    * @brief Constructor taking separate x and y (width and height) parameters.
265    * @SINCE_2_1.45
266    * @param[in] x The width or X dimension of the tuple.
267    * @param[in] y The height or Y dimension of the tuple.
268    */
269   constexpr Int32Pair(uint32_t x, uint32_t y)
270   : IntPair(x, y)
271   {
272   }
273
274 public:
275   Int32Pair(const Int32Pair&)     = default;            ///< Default copy constructor
276   Int32Pair(Int32Pair&&) noexcept = default;            ///< Default move constructor
277   Int32Pair& operator=(const Int32Pair&) = default;     ///< Default copy assignment operator
278   Int32Pair& operator=(Int32Pair&&) noexcept = default; ///< Default move assignment operator
279 };
280
281 // Allow Int32Pair to be treated as a POD type
282 template<>
283 struct TypeTraits<Int32Pair> : public BasicTypes<Int32Pair>
284 {
285   enum
286   {
287     IS_TRIVIAL_TYPE = true
288   };
289 };
290
291 /**
292  * @}
293  */
294 } // namespace Dali
295
296 #endif // DALI_INT_PAIR_H