| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| // Adapted from Apache Arrow | |
| // https://github.com/apache/arrow/blob/apache-arrow-17.0.0/cpp/src/arrow/util/macros.h | |
| #pragma once | |
| #include <cstdint> | |
| #if defined(__GNUC__) && __GNUC__ >= 4 | |
| #define PAIMON_LIKELY(x) (__builtin_expect((x), 1)) | |
| #define PAIMON_UNLIKELY(x) (__builtin_expect((x), 0)) | |
| #else | |
| #define PAIMON_LIKELY(x) (x) | |
| #define PAIMON_UNLIKELY(x) (x) | |
| #endif | |
| #define MEMORY_BARRIER() __asm__ __volatile__("" ::: "memory") | |
| #define PAIMON_EXPAND(x) x | |
| #define PAIMON_STRINGIFY(x) #x | |
| #define PAIMON_CONCAT(x, y) x##y | |
| // From Google gutil | |
| #ifndef PAIMON_DISALLOW_COPY_AND_ASSIGN | |
| #define PAIMON_DISALLOW_COPY_AND_ASSIGN(TypeName) \ | |
| TypeName(const TypeName&) = delete; \ | |
| void operator=(const TypeName&) = delete | |
| #endif | |
| #ifndef PAIMON_DEFAULT_MOVE_AND_ASSIGN | |
| #define PAIMON_DEFAULT_MOVE_AND_ASSIGN(TypeName) \ | |
| TypeName(TypeName&&) = default; \ | |
| TypeName& operator=(TypeName&&) = default | |
| #endif | |
| #define PAIMON_UNUSED(x) (void)(x) | |
| #define PAIMON_ARG_UNUSED(x) | |
| // | |
| // GCC can be told that a certain branch is not likely to be taken (for | |
| // instance, a CHECK failure), and use that information in static analysis. | |
| // Giving it this information can help it optimize for the common case in | |
| // the absence of better information (ie. -fprofile-arcs). | |
| // | |
| #if defined(__GNUC__) | |
| #define PAIMON_PREDICT_FALSE(x) (__builtin_expect(!!(x), 0)) | |
| #define PAIMON_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) | |
| #define PAIMON_NORETURN __attribute__((noreturn)) | |
| #define PAIMON_NOINLINE __attribute__((noinline)) | |
| #define PAIMON_PREFETCH(addr) __builtin_prefetch(addr) | |
| #elif defined(_MSC_VER) | |
| #define PAIMON_NORETURN __declspec(noreturn) | |
| #define PAIMON_NOINLINE __declspec(noinline) | |
| #define PAIMON_PREDICT_FALSE(x) (x) | |
| #define PAIMON_PREDICT_TRUE(x) (x) | |
| #define PAIMON_PREFETCH(addr) | |
| #else | |
| #define PAIMON_NORETURN | |
| #define PAIMON_PREDICT_FALSE(x) (x) | |
| #define PAIMON_PREDICT_TRUE(x) (x) | |
| #define PAIMON_PREFETCH(addr) | |
| #endif | |
| #if (defined(__GNUC__) || defined(__APPLE__)) | |
| #define PAIMON_MUST_USE_RESULT __attribute__((warn_unused_result)) | |
| #elif defined(_MSC_VER) | |
| #define PAIMON_MUST_USE_RESULT | |
| #else | |
| #define PAIMON_MUST_USE_RESULT | |
| #endif | |
| #if defined(__clang__) | |
| // Only clang supports warn_unused_result as a type annotation. | |
| #define PAIMON_MUST_USE_TYPE PAIMON_MUST_USE_RESULT | |
| #else | |
| #define PAIMON_MUST_USE_TYPE | |
| #endif | |
| // ---------------------------------------------------------------------- | |
| // clang-format off | |
| // [[deprecated]] is only available in C++14, use this for the time being | |
| // This macro takes an optional deprecation message | |
| #ifdef __COVERITY__ | |
| # define PAIMON_DEPRECATED(...) | |
| # define PAIMON_DEPRECATED_USING(...) | |
| #elif __cplusplus > 201103L | |
| # define PAIMON_DEPRECATED(...) [[deprecated(__VA_ARGS__)]] | |
| # define PAIMON_DEPRECATED_USING(...) PAIMON_DEPRECATED(__VA_ARGS__) | |
| #else | |
| # ifdef __GNUC__ | |
| # define PAIMON_DEPRECATED(...) __attribute__((deprecated(__VA_ARGS__))) | |
| # define PAIMON_DEPRECATED_USING(...) PAIMON_DEPRECATED(__VA_ARGS__) | |
| # elif defined(_MSC_VER) | |
| # define PAIMON_DEPRECATED(...) __declspec(deprecated(__VA_ARGS__)) | |
| # define PAIMON_DEPRECATED_USING(...) | |
| # else | |
| # define PAIMON_DEPRECATED(...) | |
| # define PAIMON_DEPRECATED_USING(...) | |
| # endif | |
| #endif | |
| // clang-format on | |
| // ---------------------------------------------------------------------- | |
| // macros to disable padding | |
| // these macros are portable across different compilers and platforms | |
| // [https://github.com/google/flatbuffers/blob/master/include/flatbuffers/flatbuffers.h#L1355] | |
| #if !defined(MANUALLY_ALIGNED_STRUCT) | |
| #if defined(_MSC_VER) | |
| #define MANUALLY_ALIGNED_STRUCT(alignment) \ | |
| __pragma(pack(1)); \ | |
| struct __declspec(align(alignment)) | |
| #define STRUCT_END(name, size) \ | |
| __pragma(pack()); \ | |
| static_assert(sizeof(name) == size, "compiler breaks packing rules") | |
| #elif defined(__GNUC__) || defined(__clang__) | |
| #define MANUALLY_ALIGNED_STRUCT(alignment) \ | |
| _Pragma("pack(1)") struct __attribute__((aligned(alignment))) | |
| #define STRUCT_END(name, size) \ | |
| _Pragma("pack()") static_assert(sizeof(name) == size, "compiler breaks packing rules") | |
| #else | |
| #error Unknown compiler, please define structure alignment macros | |
| #endif | |
| #endif // !defined(MANUALLY_ALIGNED_STRUCT) | |
| // ---------------------------------------------------------------------- | |
| // Convenience macro disabling a particular UBSan check in a function | |
| #if defined(__clang__) | |
| #define PAIMON_DISABLE_UBSAN(feature) __attribute__((no_sanitize(feature))) | |
| #else | |
| #define PAIMON_DISABLE_UBSAN(feature) | |
| #endif | |
| // ---------------------------------------------------------------------- | |
| // Machine information | |
| #if INTPTR_MAX == INT64_MAX | |
| #define PAIMON_BITNESS 64 | |
| #elif INTPTR_MAX == INT32_MAX | |
| #define PAIMON_BITNESS 32 | |
| #else | |
| #error Unexpected INTPTR_MAX | |
| #endif | |
| // ---------------------------------------------------------------------- | |
| // From googletest | |
| // (also in parquet-cpp) | |
| // When you need to test the private or protected members of a class, | |
| // use the FRIEND_TEST macro to declare your tests as friends of the | |
| // class. For example: | |
| // | |
| // class MyClass { | |
| // private: | |
| // void MyMethod(); | |
| // FRIEND_TEST(MyClassTest, MyMethod); | |
| // }; | |
| // | |
| // class MyClassTest : public testing::Test { | |
| // // ... | |
| // }; | |
| // | |
| // TEST_F(MyClassTest, MyMethod) { | |
| // // Can call MyClass::MyMethod() here. | |
| // } | |
| #define FRIEND_TEST(test_case_name, test_name) friend class test_case_name##_##test_name##_Test |