1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_UTILS_UTILS_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_UTILS_UTILS_H
18 
19 #include <chrono>
20 #include <cmath>
21 #include <cstdint>
22 
23 #include "base/log/log.h"
24 
25 #define CHECK_NULL_VOID(ptr) \
26     do {                           \
27         if (!(ptr)) {              \
28             return;                \
29         }                          \
30     } while (0)                    \
31 
32 #define CHECK_NULL_RETURN(ptr, ret) \
33     do {                                  \
34         if (!(ptr)) {                     \
35             return ret;                   \
36         }                                 \
37     } while (0)                           \
38 
39 #define CHECK_ERROR_CODE_RETURN(code) \
40     do {                                  \
41         if ((code) > 0) {                     \
42             return code;                   \
43         }                                 \
44     } while (0)                           \
45 
46 #define CHECK_EQUAL_VOID(var, value) \
47     do {                             \
48         if ((var) == (value)) {      \
49             return;                  \
50         }                            \
51     } while (0)                      \
52 
53 #define CHECK_EQUAL_RETURN(var, value, ret) \
54     do {                                    \
55         if ((var) == (value)) {             \
56             return ret;                     \
57         }                                   \
58     } while (0)                             \
59 
60 #define CHECK_NULL_CONTINUE(ptr)                                    \
61     if (!(ptr)) {                                                   \
62         continue;                                                   \
63     }
64 
65 #define PRIMITIVE_CAT(x, y) x##y
66 #define CAT(x, y) PRIMITIVE_CAT(x, y)
67 
68 #define COPY_SENTENCE(x) x = other.x;
69 #define LOOP_COPY(x) CAT(LOOP_COPY1 x, _END)
70 #define LOOP_COPY1(x) COPY_SENTENCE(x) LOOP_COPY2
71 #define LOOP_COPY2(x) COPY_SENTENCE(x) LOOP_COPY1
72 #define LOOP_COPY1_END
73 #define LOOP_COPY2_END
74 
75 #define COMPARE_SENTENCE(x) (x == other.x)
76 #define LOOP_COMPARE(x) CAT(LOOP_COMPARE0 x, _END)
77 #define LOOP_COMPARE0(x) COMPARE_SENTENCE(x) LOOP_COMPARE1
78 #define LOOP_COMPARE1(x) &&COMPARE_SENTENCE(x) LOOP_COMPARE2
79 #define LOOP_COMPARE2(x) &&COMPARE_SENTENCE(x) LOOP_COMPARE1
80 #define LOOP_COMPARE1_END
81 #define LOOP_COMPARE2_END
82 
83 #define DEFINE_COPY_CONSTRUCTOR(type) \
84     type(const type& other)           \
85     {                                 \
86         *this = other;                \
87     }
88 
89 #define DEFINE_COPY_OPERATOR_WITH_PROPERTIES(type, PROPS) \
90     type& operator=(const type& other)                    \
91     {                                                     \
92         if (&other != this) {                             \
93             LOOP_COPY(PROPS)                              \
94         }                                                 \
95         return *this;                                     \
96     }
97 
98 #define DEFINE_COMPARE_OPERATOR_WITH_PROPERTIES(type, PROPS) \
99     bool operator==(const type& other) const                 \
100     {                                                        \
101         if (&other == this) {                                \
102             return true;                                     \
103         }                                                    \
104         return LOOP_COMPARE(PROPS);                          \
105     }
106 
107 #define DEFINE_COPY_CONSTRUCTOR_AND_COPY_OPERATOR_AND_COMPARE_OPERATOR_WITH_PROPERTIES(type, PROPS) \
108     DEFINE_COPY_CONSTRUCTOR(type)                                                                   \
109     DEFINE_COPY_OPERATOR_WITH_PROPERTIES(type, PROPS) DEFINE_COMPARE_OPERATOR_WITH_PROPERTIES(type, PROPS)
110 
111 namespace OHOS::Ace {
112 
113 template<typename T, std::size_t N>
114 constexpr std::size_t ArraySize(T (&)[N]) noexcept
115 {
116     return N;
117 }
118 
119 template<typename T, int32_t N>
ConvertIntToEnum(int32_t index, const T (&values)[N], T defaultValue)120 T ConvertIntToEnum(int32_t index, const T (&values)[N], T defaultValue)
121 {
122     if (index >= 0 && index < N) {
123         return values[index];
124     }
125     return defaultValue;
126 }
127 
128 template<typename T>
Infinity()129 constexpr T Infinity()
130 {
131     return static_cast<const T>(1000000.0);
132 }
133 
134 namespace {
135 constexpr float INF_APPROACH = Infinity<float>() * 0.5f;
136 }
137 
NearEqual(const double left, const double right, const double epsilon)138 inline bool NearEqual(const double left, const double right, const double epsilon)
139 {
140     return (std::abs(left - right) <= epsilon);
141 }
142 
143 template<typename T>
144 constexpr bool NearEqual(const T& left, const T& right);
145 
146 template<>
NearEqual(const float& left, const float& right)147 inline bool NearEqual<float>(const float& left, const float& right)
148 {
149     constexpr double epsilon = 0.001f;
150     return NearEqual(left, right, epsilon);
151 }
152 
153 template<>
NearEqual(const double& left, const double& right)154 inline bool NearEqual<double>(const double& left, const double& right)
155 {
156     constexpr double epsilon = 0.00001f;
157     return NearEqual(left, right, epsilon);
158 }
159 
160 template<typename T>
NearEqual(const T& left, const T& right)161 constexpr bool NearEqual(const T& left, const T& right)
162 {
163     return left == right;
164 }
165 
NearZero(const double value, const double epsilon)166 inline bool NearZero(const double value, const double epsilon)
167 {
168     return NearEqual(value, 0.0, epsilon);
169 }
170 
NearEqual(const double left, const double right)171 inline bool NearEqual(const double left, const double right)
172 {
173     constexpr double epsilon = 0.001f;
174     return NearEqual(left, right, epsilon);
175 }
176 
NearZero(const double left)177 inline bool NearZero(const double left)
178 {
179     constexpr double epsilon = 0.001f;
180     return NearZero(left, epsilon);
181 }
182 
LessOrEqual(double left, double right)183 inline bool LessOrEqual(double left, double right)
184 {
185     constexpr double epsilon = 0.001f;
186     return (left - right) < epsilon;
187 }
188 
LessOrEqualCustomPrecision(double left, double right, double epsilon = 0.000001f)189 inline bool LessOrEqualCustomPrecision(double left, double right, double epsilon = 0.000001f)
190 {
191     return (left - right) < epsilon;
192 }
193 
LessNotEqual(double left, double right)194 inline bool LessNotEqual(double left, double right)
195 {
196     constexpr double epsilon = -0.001f;
197     return (left - right) < epsilon;
198 }
199 
LessNotEqualCustomPrecision(double left, double right, double epsilon = -0.000001f)200 inline bool LessNotEqualCustomPrecision(double left, double right, double epsilon = -0.000001f)
201 {
202     return (left - right) < epsilon;
203 }
204 
GreatOrEqual(double left, double right)205 inline bool GreatOrEqual(double left, double right)
206 {
207     constexpr double epsilon = -0.001f;
208     return (left - right) > epsilon;
209 }
210 
GreatOrEqualCustomPrecision(double left, double right, double epsilon = -0.000001f)211 inline bool GreatOrEqualCustomPrecision(double left, double right, double epsilon = -0.000001f)
212 {
213     return (left - right) > epsilon;
214 }
215 
GreatNotEqual(double left, double right)216 inline bool GreatNotEqual(double left, double right)
217 {
218     constexpr double epsilon = 0.001f;
219     return (left - right) > epsilon;
220 }
221 
GreatNotEqualCustomPrecision(double left, double right, double epsilon = 0.000001f)222 inline bool GreatNotEqualCustomPrecision(double left, double right, double epsilon = 0.000001f)
223 {
224     return (left - right) > epsilon;
225 }
226 
Round(double rawNum)227 inline double Round(double rawNum)
228 {
229     constexpr double epsilon = 0.001f;
230     return std::round(rawNum + epsilon);
231 }
232 
Negative(double value)233 inline bool Negative(double value)
234 {
235     return LessNotEqual(value, 0);
236 }
237 
NonNegative(double value)238 inline bool NonNegative(double value)
239 {
240     return GreatOrEqual(value, 0);
241 }
242 
Positive(double value)243 inline bool Positive(double value)
244 {
245     return GreatNotEqual(value, 0);
246 }
247 
NonPositive(double value)248 inline bool NonPositive(double value)
249 {
250     return LessOrEqual(value, 0);
251 }
252 
InRegion(double lowerBound, double upperBound, double destNum)253 inline bool InRegion(double lowerBound, double upperBound, double destNum)
254 {
255     return LessOrEqual(lowerBound, destNum) && LessOrEqual(destNum, upperBound);
256 }
257 
GreaterOrEqualToInfinity(float num)258 inline bool GreaterOrEqualToInfinity(float num)
259 {
260     return GreatOrEqual(num, INF_APPROACH);
261 }
262 
GetMilliseconds()263 inline uint64_t GetMilliseconds()
264 {
265     auto now = std::chrono::system_clock::now();
266     auto millisecs = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
267     return millisecs.count();
268 }
269 
GetNanoseconds()270 inline uint64_t GetNanoseconds()
271 {
272     auto now = std::chrono::system_clock::now();
273     auto nanoseconds = std::chrono::duration_cast<std::chrono::nanoseconds>(now.time_since_epoch());
274     return nanoseconds.count();
275 }
276 
CalculateFriction(float gamma)277 inline float CalculateFriction(float gamma)
278 {
279     constexpr float SCROLL_RATIO = 0.72f;
280     if (GreatOrEqual(gamma, 1.0)) {
281         gamma = 1.0;
282     }
283     return SCROLL_RATIO * static_cast<float>(std::pow(1.0 - gamma, 2));
284 }
285 
IsDarkColor(uint32_t color)286 inline bool IsDarkColor(uint32_t color)
287 {
288     constexpr int lightThresholds = 128;
289     int r = (color >> 16) & 0xFF;
290     int g = (color >> 8) & 0xFF;
291     int b = color & 0xFF;
292     int gray = (r * 299 + g * 587 + b * 114) / 1000;
293     return gray < lightThresholds;
294 }
295 
296 bool RealPath(const std::string& fileName, char* realPath);
297 
298 } // namespace OHOS::Ace
299 
300 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_UTILS_UTILS_H
301