xref: /aosp_15_r20/external/libtextclassifier/native/utils/base/macros.h (revision 993b0882672172b81d12fad7a7ac0c3e5c824a12)
1*993b0882SAndroid Build Coastguard Worker /*
2*993b0882SAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
3*993b0882SAndroid Build Coastguard Worker  *
4*993b0882SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*993b0882SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*993b0882SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*993b0882SAndroid Build Coastguard Worker  *
8*993b0882SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*993b0882SAndroid Build Coastguard Worker  *
10*993b0882SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*993b0882SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*993b0882SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*993b0882SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*993b0882SAndroid Build Coastguard Worker  * limitations under the License.
15*993b0882SAndroid Build Coastguard Worker  */
16*993b0882SAndroid Build Coastguard Worker 
17*993b0882SAndroid Build Coastguard Worker #ifndef LIBTEXTCLASSIFIER_UTILS_BASE_MACROS_H_
18*993b0882SAndroid Build Coastguard Worker #define LIBTEXTCLASSIFIER_UTILS_BASE_MACROS_H_
19*993b0882SAndroid Build Coastguard Worker 
20*993b0882SAndroid Build Coastguard Worker #include "utils/base/config.h"
21*993b0882SAndroid Build Coastguard Worker 
22*993b0882SAndroid Build Coastguard Worker namespace libtextclassifier3 {
23*993b0882SAndroid Build Coastguard Worker 
24*993b0882SAndroid Build Coastguard Worker #define TC3_ARRAYSIZE(a) \
25*993b0882SAndroid Build Coastguard Worker   ((sizeof(a) / sizeof(*(a))) / (size_t)(!(sizeof(a) % sizeof(*(a)))))
26*993b0882SAndroid Build Coastguard Worker 
27*993b0882SAndroid Build Coastguard Worker #if LANG_CXX11
28*993b0882SAndroid Build Coastguard Worker #define TC3_DISALLOW_COPY_AND_ASSIGN(TypeName) \
29*993b0882SAndroid Build Coastguard Worker   TypeName(const TypeName &) = delete;         \
30*993b0882SAndroid Build Coastguard Worker   TypeName &operator=(const TypeName &) = delete
31*993b0882SAndroid Build Coastguard Worker #else  // C++98 case follows
32*993b0882SAndroid Build Coastguard Worker 
33*993b0882SAndroid Build Coastguard Worker // Note that these C++98 implementations cannot completely disallow copying,
34*993b0882SAndroid Build Coastguard Worker // as members and friends can still accidentally make elided copies without
35*993b0882SAndroid Build Coastguard Worker // triggering a linker error.
36*993b0882SAndroid Build Coastguard Worker #define TC3_DISALLOW_COPY_AND_ASSIGN(TypeName) \
37*993b0882SAndroid Build Coastguard Worker   TypeName(const TypeName &);                  \
38*993b0882SAndroid Build Coastguard Worker   TypeName &operator=(const TypeName &)
39*993b0882SAndroid Build Coastguard Worker #endif  // LANG_CXX11
40*993b0882SAndroid Build Coastguard Worker 
41*993b0882SAndroid Build Coastguard Worker // The TC3_FALLTHROUGH_INTENDED macro can be used to annotate implicit
42*993b0882SAndroid Build Coastguard Worker // fall-through between switch labels:
43*993b0882SAndroid Build Coastguard Worker //
44*993b0882SAndroid Build Coastguard Worker //  switch (x) {
45*993b0882SAndroid Build Coastguard Worker //    case 40:
46*993b0882SAndroid Build Coastguard Worker //    case 41:
47*993b0882SAndroid Build Coastguard Worker //      if (truth_is_out_there) {
48*993b0882SAndroid Build Coastguard Worker //        ++x;
49*993b0882SAndroid Build Coastguard Worker //        TC3_FALLTHROUGH_INTENDED;  // Use instead of/along with annotations in
50*993b0882SAndroid Build Coastguard Worker //                                  // comments.
51*993b0882SAndroid Build Coastguard Worker //      } else {
52*993b0882SAndroid Build Coastguard Worker //        return x;
53*993b0882SAndroid Build Coastguard Worker //      }
54*993b0882SAndroid Build Coastguard Worker //    case 42:
55*993b0882SAndroid Build Coastguard Worker //      ...
56*993b0882SAndroid Build Coastguard Worker //
57*993b0882SAndroid Build Coastguard Worker //  As shown in the example above, the TC3_FALLTHROUGH_INTENDED macro should be
58*993b0882SAndroid Build Coastguard Worker //  followed by a semicolon. It is designed to mimic control-flow statements
59*993b0882SAndroid Build Coastguard Worker //  like 'break;', so it can be placed in most places where 'break;' can, but
60*993b0882SAndroid Build Coastguard Worker //  only if there are no statements on the execution path between it and the
61*993b0882SAndroid Build Coastguard Worker //  next switch label.
62*993b0882SAndroid Build Coastguard Worker //
63*993b0882SAndroid Build Coastguard Worker //  When compiled with clang in C++11 mode, the TC3_FALLTHROUGH_INTENDED macro
64*993b0882SAndroid Build Coastguard Worker //  is expanded to [[clang::fallthrough]] attribute, which is analysed when
65*993b0882SAndroid Build Coastguard Worker //  performing switch labels fall-through diagnostic ('-Wimplicit-fallthrough').
66*993b0882SAndroid Build Coastguard Worker //  See clang documentation on language extensions for details:
67*993b0882SAndroid Build Coastguard Worker //  http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
68*993b0882SAndroid Build Coastguard Worker //
69*993b0882SAndroid Build Coastguard Worker //  When used with unsupported compilers, the TC3_FALLTHROUGH_INTENDED macro has
70*993b0882SAndroid Build Coastguard Worker //  no effect on diagnostics.
71*993b0882SAndroid Build Coastguard Worker //
72*993b0882SAndroid Build Coastguard Worker //  In either case this macro has no effect on runtime behavior and performance
73*993b0882SAndroid Build Coastguard Worker //  of code.
74*993b0882SAndroid Build Coastguard Worker #if defined(__clang__) && defined(__has_warning)
75*993b0882SAndroid Build Coastguard Worker #if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough")
76*993b0882SAndroid Build Coastguard Worker #define TC3_FALLTHROUGH_INTENDED [[clang::fallthrough]]
77*993b0882SAndroid Build Coastguard Worker #endif
78*993b0882SAndroid Build Coastguard Worker #elif defined(__GNUC__) && __GNUC__ >= 7
79*993b0882SAndroid Build Coastguard Worker #define TC3_FALLTHROUGH_INTENDED [[gnu::fallthrough]]
80*993b0882SAndroid Build Coastguard Worker #endif
81*993b0882SAndroid Build Coastguard Worker 
82*993b0882SAndroid Build Coastguard Worker #ifndef TC3_FALLTHROUGH_INTENDED
83*993b0882SAndroid Build Coastguard Worker #define TC3_FALLTHROUGH_INTENDED \
84*993b0882SAndroid Build Coastguard Worker   do {                           \
85*993b0882SAndroid Build Coastguard Worker   } while (0)
86*993b0882SAndroid Build Coastguard Worker #endif
87*993b0882SAndroid Build Coastguard Worker 
88*993b0882SAndroid Build Coastguard Worker #ifdef __has_builtin
89*993b0882SAndroid Build Coastguard Worker #define TC3_HAS_BUILTIN(x) __has_builtin(x)
90*993b0882SAndroid Build Coastguard Worker #else
91*993b0882SAndroid Build Coastguard Worker #define TC3_HAS_BUILTIN(x) 0
92*993b0882SAndroid Build Coastguard Worker #endif
93*993b0882SAndroid Build Coastguard Worker 
94*993b0882SAndroid Build Coastguard Worker // Compilers can be told that a certain branch is not likely to be taken
95*993b0882SAndroid Build Coastguard Worker // (for instance, a CHECK failure), and use that information in static
96*993b0882SAndroid Build Coastguard Worker // analysis. Giving it this information can help it optimize for the
97*993b0882SAndroid Build Coastguard Worker // common case in the absence of better information (ie.
98*993b0882SAndroid Build Coastguard Worker // -fprofile-arcs).
99*993b0882SAndroid Build Coastguard Worker //
100*993b0882SAndroid Build Coastguard Worker // We need to disable this for GPU builds, though, since nvcc8 and older
101*993b0882SAndroid Build Coastguard Worker // don't recognize `__builtin_expect` as a builtin, and fail compilation.
102*993b0882SAndroid Build Coastguard Worker #if (!defined(__NVCC__)) && (TC3_HAS_BUILTIN(__builtin_expect) || \
103*993b0882SAndroid Build Coastguard Worker                              (defined(__GNUC__) && __GNUC__ >= 3))
104*993b0882SAndroid Build Coastguard Worker #define TC3_PREDICT_FALSE(x) (__builtin_expect(x, 0))
105*993b0882SAndroid Build Coastguard Worker #define TC3_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1))
106*993b0882SAndroid Build Coastguard Worker #else
107*993b0882SAndroid Build Coastguard Worker #define TC3_PREDICT_FALSE(x) (x)
108*993b0882SAndroid Build Coastguard Worker #define TC3_PREDICT_TRUE(x) (x)
109*993b0882SAndroid Build Coastguard Worker #endif
110*993b0882SAndroid Build Coastguard Worker 
111*993b0882SAndroid Build Coastguard Worker // TC3_HAVE_ATTRIBUTE
112*993b0882SAndroid Build Coastguard Worker //
113*993b0882SAndroid Build Coastguard Worker // A function-like feature checking macro that is a wrapper around
114*993b0882SAndroid Build Coastguard Worker // `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a
115*993b0882SAndroid Build Coastguard Worker // nonzero constant integer if the attribute is supported or 0 if not.
116*993b0882SAndroid Build Coastguard Worker //
117*993b0882SAndroid Build Coastguard Worker // It evaluates to zero if `__has_attribute` is not defined by the compiler.
118*993b0882SAndroid Build Coastguard Worker //
119*993b0882SAndroid Build Coastguard Worker // GCC: https://gcc.gnu.org/gcc-5/changes.html
120*993b0882SAndroid Build Coastguard Worker // Clang: https://clang.llvm.org/docs/LanguageExtensions.html
121*993b0882SAndroid Build Coastguard Worker #ifdef __has_attribute
122*993b0882SAndroid Build Coastguard Worker #define TC3_HAVE_ATTRIBUTE(x) __has_attribute(x)
123*993b0882SAndroid Build Coastguard Worker #else
124*993b0882SAndroid Build Coastguard Worker #define TC3_HAVE_ATTRIBUTE(x) 0
125*993b0882SAndroid Build Coastguard Worker #endif
126*993b0882SAndroid Build Coastguard Worker 
127*993b0882SAndroid Build Coastguard Worker // TC3_ATTRIBUTE_PACKED
128*993b0882SAndroid Build Coastguard Worker //
129*993b0882SAndroid Build Coastguard Worker // Prevents the compiler from padding a structure to natural alignment
130*993b0882SAndroid Build Coastguard Worker #if TC3_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__))
131*993b0882SAndroid Build Coastguard Worker #define TC3_ATTRIBUTE_PACKED __attribute__((__packed__))
132*993b0882SAndroid Build Coastguard Worker #else
133*993b0882SAndroid Build Coastguard Worker #define TC3_ATTRIBUTE_PACKED
134*993b0882SAndroid Build Coastguard Worker #endif
135*993b0882SAndroid Build Coastguard Worker 
136*993b0882SAndroid Build Coastguard Worker }  // namespace libtextclassifier3
137*993b0882SAndroid Build Coastguard Worker 
138*993b0882SAndroid Build Coastguard Worker #endif  // LIBTEXTCLASSIFIER_UTILS_BASE_MACROS_H_
139