1 #ifndef DALI_INT_PAIR_H
2 #define DALI_INT_PAIR_H
5 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include <type_traits>
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/common/type-traits.h>
32 * @addtogroup dali_core_math
37 * @brief Simple class for passing around pairs of small integers.
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).
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.
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.
51 template<unsigned Bits, bool IsSigned, typename = std::enable_if_t<(Bits == 8 || Bits == 16 || Bits == 32)>>
58 * @brief Integer type for get/set access.
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;
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.
69 using UintType = typename std::conditional<Bits == 8, uint8_t, typename std::conditional<Bits == 16, uint16_t, uint32_t>::type>::type;
72 * @brief 2-tuple stored integer type.
75 using DataType = typename std::conditional<Bits == 8, uint16_t, typename std::conditional<Bits == 16, uint32_t, uint64_t>::type>::type;
79 * @brief Default constructor for the (0, 0) tuple.
88 * @brief Constructor taking separate x and y (width and height) parameters.
90 * @param[in] width The width or X dimension of the tuple.
91 * @param[in] height The height or Y dimension of the tuple.
93 constexpr IntPair(IntType width, IntType height)
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.
100 mData = (static_cast<DataType>(static_cast<UintType>(height)) << Bits) | static_cast<DataType>(static_cast<UintType>(width));
104 * @brief Sets the width.
106 * @param[in] width The x dimension to be stored in this 2-tuple
108 void SetWidth(IntType width)
110 mComponents[0] = width;
114 * @brief Get the width.
116 * @return the x dimension stored in this 2-tuple
118 IntType GetWidth() const
120 return mComponents[0];
124 * @brief Sets the height.
126 * @param[in] height The y dimension to be stored in this 2-tuple
128 void SetHeight(IntType height)
130 mComponents[1] = height;
134 * @brief Returns the y dimension stored in this 2-tuple.
138 IntType GetHeight() const
140 return mComponents[1];
144 * @brief Sets the x dimension (same as width).
146 * @param[in] x The x dimension to be stored in this 2-tuple
154 * @brief Returns the x dimension stored in this 2-tuple.
160 return mComponents[0];
164 * @brief Sets the y dimension (same as height).
166 * @param[in] y The y dimension to be stored in this 2-tuple
174 * @brief Returns the y dimension stored in this 2-tuple.
180 return mComponents[1];
184 * @brief Equality operator.
186 * @param[in] rhs A reference for comparison
187 * @return True if same
189 bool operator==(const IntPair& rhs) const
191 return mData == rhs.mData;
195 * @brief Inequality operator.
197 * @param[in] rhs A reference for comparison
198 * @return True if different
200 bool operator!=(const IntPair& rhs) const
202 return mData != rhs.mData;
206 * @brief Less than comparison operator for storing in collections (not geometrically
209 * @param[in] rhs A reference for comparison
210 * @return True if less
212 bool operator<(const IntPair& rhs) const
214 return mData < rhs.mData;
218 * @brief Greater than comparison operator for storing in collections (not
219 * geometrically meaningful).
221 * @param[in] rhs A reference for comparison
222 * @return True if greater
224 bool operator>(const IntPair& rhs) const
226 return mData > rhs.mData;
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
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:
246 * @brief Simple class for passing around pairs of signed integers.
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.
254 class Int32Pair : public IntPair<32, true>
258 * @brief Default constructor for the (0, 0) tuple.
261 constexpr Int32Pair() = default;
264 * @brief Constructor taking separate x and y (width and height) parameters.
266 * @param[in] x The width or X dimension of the tuple.
267 * @param[in] y The height or Y dimension of the tuple.
269 constexpr Int32Pair(uint32_t x, uint32_t y)
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
281 // Allow Int32Pair to be treated as a POD type
283 struct TypeTraits<Int32Pair> : public BasicTypes<Int32Pair>
287 IS_TRIVIAL_TYPE = true
296 #endif // DALI_INT_PAIR_H