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