1 /*
2  * Copyright (c) 2024 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 DFX_LOG_PUBLIC_H
17 #define DFX_LOG_PUBLIC_H
18 
19 #include <array>
20 
21 #ifndef is_ohos_lite
22 namespace OHOS {
23 namespace HiviewDFX {
24 template<typename I, typename O>
Copy(I first,I last,O result)25 constexpr void Copy(I first, I last, O result)
26 {
27     while (first != last) {
28         *result++ = *first++;
29     }
30 }
31 
32 template<typename LHS, typename RHS>
ConcatStr(LHS && lhs,RHS && rhs)33 constexpr auto ConcatStr(LHS&& lhs, RHS&& rhs)
34 {
35     std::array<char, sizeof(lhs) + sizeof(rhs) - 1> res {};
36     std::size_t i = 0;
37     for (auto it = std::begin(lhs); it != std::end(lhs) && *it; ++it) {
38         res[i++] = *it;
39     }
40     for (auto it = std::begin(rhs); it != std::end(rhs) && *it; ++it) {
41         res[i++] = *it;
42     }
43     return res;
44 }
45 
46 // 编译时计算: 直接得到func<line>:字符串,避免运行时格式化开销
47 template<std::size_t N, int... D>
48 struct NumStr : NumStr<N / 10, N % 10, D...> { // 10 : decimal
49 };
50 
51 template<int ...D>
52 struct NumStr<0, D...> {
53     static_assert(((D >= 0 && D <= 9) && ...)); // 9 : decimal
54     constexpr static std::size_t len = sizeof...(D);
55     constexpr static char str[] { D + '0'... };
56 };
57 
58 template<char... Cs>
59 struct CharList {
60     static constexpr std::array value { Cs..., '\0'};
61 };
62 
63 // 编译时计算: 字符串替换 %d -> %{public}d
64 // ohos默认hilog打印<private>而不是具体值
65 template<typename In, typename Out = OHOS::HiviewDFX::CharList<>>
66 struct FmtToPublic {
67     static constexpr auto value = Out::value;
68 };
69 
70 template<char C, char... Cs, char... O>
71 struct FmtToPublic<CharList<C, Cs...>, CharList<O...>> : FmtToPublic<CharList<Cs...>, CharList<O..., C>> {};
72 
73 // case: %{, skip
74 template<char... Cs, char... O>
75 struct FmtToPublic<CharList<'%', '{', Cs...>, CharList<O...>>
76     : FmtToPublic<CharList<Cs...>, CharList<O..., '%', '{'>> {};
77 
78 // case: %%, skip
79 template<char... Cs, char... O>
80 struct FmtToPublic<CharList<'%', '%', Cs...>, CharList<O...>>
81     : FmtToPublic<CharList<Cs...>, CharList<O..., '%', '%'>> {};
82 
83 // case: %d, %u, add {public}
84 template<char... Cs, char... O>
85 struct FmtToPublic<CharList<'%', Cs...>, CharList<O...>>
86     : FmtToPublic<CharList<Cs...>, CharList<O..., '%', '{', 'p', 'u', 'b', 'l', 'i', 'c', '}'>> {};
87 } // nameapace HiviewDFX
88 } // nameapace OHOS
89 
90 #pragma clang diagnostic push
91 #pragma clang diagnostic ignored "-Wgnu-string-literal-operator-template"
92 template<typename CharT, CharT... Cs>
93 constexpr auto operator"" _DfxToPublic()
94 {
95     return OHOS::HiviewDFX::FmtToPublic<OHOS::HiviewDFX::CharList<Cs...>>::value;
96 };
97 #pragma clang diagnostic pop
98 #endif // is_ohos_lite
99 #endif