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
111namespace OHOS::Ace {
112
113template<typename T, std::size_t N>
114constexpr std::size_t ArraySize(T (&)[N]) noexcept
115{
116    return N;
117}
118
119template<typename T, int32_t N>
120T 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
128template<typename T>
129constexpr T Infinity()
130{
131    return static_cast<const T>(1000000.0);
132}
133
134namespace {
135constexpr float INF_APPROACH = Infinity<float>() * 0.5f;
136}
137
138inline bool NearEqual(const double left, const double right, const double epsilon)
139{
140    return (std::abs(left - right) <= epsilon);
141}
142
143template<typename T>
144constexpr bool NearEqual(const T& left, const T& right);
145
146template<>
147inline bool NearEqual<float>(const float& left, const float& right)
148{
149    constexpr double epsilon = 0.001f;
150    return NearEqual(left, right, epsilon);
151}
152
153template<>
154inline bool NearEqual<double>(const double& left, const double& right)
155{
156    constexpr double epsilon = 0.00001f;
157    return NearEqual(left, right, epsilon);
158}
159
160template<typename T>
161constexpr bool NearEqual(const T& left, const T& right)
162{
163    return left == right;
164}
165
166inline bool NearZero(const double value, const double epsilon)
167{
168    return NearEqual(value, 0.0, epsilon);
169}
170
171inline bool NearEqual(const double left, const double right)
172{
173    constexpr double epsilon = 0.001f;
174    return NearEqual(left, right, epsilon);
175}
176
177inline bool NearZero(const double left)
178{
179    constexpr double epsilon = 0.001f;
180    return NearZero(left, epsilon);
181}
182
183inline bool LessOrEqual(double left, double right)
184{
185    constexpr double epsilon = 0.001f;
186    return (left - right) < epsilon;
187}
188
189inline bool LessOrEqualCustomPrecision(double left, double right, double epsilon = 0.000001f)
190{
191    return (left - right) < epsilon;
192}
193
194inline bool LessNotEqual(double left, double right)
195{
196    constexpr double epsilon = -0.001f;
197    return (left - right) < epsilon;
198}
199
200inline bool LessNotEqualCustomPrecision(double left, double right, double epsilon = -0.000001f)
201{
202    return (left - right) < epsilon;
203}
204
205inline bool GreatOrEqual(double left, double right)
206{
207    constexpr double epsilon = -0.001f;
208    return (left - right) > epsilon;
209}
210
211inline bool GreatOrEqualCustomPrecision(double left, double right, double epsilon = -0.000001f)
212{
213    return (left - right) > epsilon;
214}
215
216inline bool GreatNotEqual(double left, double right)
217{
218    constexpr double epsilon = 0.001f;
219    return (left - right) > epsilon;
220}
221
222inline bool GreatNotEqualCustomPrecision(double left, double right, double epsilon = 0.000001f)
223{
224    return (left - right) > epsilon;
225}
226
227inline double Round(double rawNum)
228{
229    constexpr double epsilon = 0.001f;
230    return std::round(rawNum + epsilon);
231}
232
233inline bool Negative(double value)
234{
235    return LessNotEqual(value, 0);
236}
237
238inline bool NonNegative(double value)
239{
240    return GreatOrEqual(value, 0);
241}
242
243inline bool Positive(double value)
244{
245    return GreatNotEqual(value, 0);
246}
247
248inline bool NonPositive(double value)
249{
250    return LessOrEqual(value, 0);
251}
252
253inline bool InRegion(double lowerBound, double upperBound, double destNum)
254{
255    return LessOrEqual(lowerBound, destNum) && LessOrEqual(destNum, upperBound);
256}
257
258inline bool GreaterOrEqualToInfinity(float num)
259{
260    return GreatOrEqual(num, INF_APPROACH);
261}
262
263inline 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
270inline 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
277inline 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
286inline 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
296bool RealPath(const std::string& fileName, char* realPath);
297
298} // namespace OHOS::Ace
299
300#endif // FOUNDATION_ACE_FRAMEWORKS_BASE_UTILS_UTILS_H
301