blob: 95232c95a682ae548ff33169456bed35a6d75bc5 [file] [log] [blame]
/*
* 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.
*/
#ifndef UTILS_UTIL_DEFINE_H
#define UTILS_UTIL_DEFINE_H
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
/* ======== 跨平台兼容性定义 ======== */
#if defined(_WIN32)
#define PLATFORM_WINDOWS 1
#elif defined(__APPLE__)
#define PLATFORM_APPLE 1
#elif defined(__linux__)
#define PLATFORM_LINUX 1
#else
#define PLATFORM_UNKNOWN 1
#endif
/* ======== unused ======== */
#define UNUSED(v) ((void)(v))
/* ======== inline ======== */
#if defined(_MSC_VER)
#define FORCE_INLINE __forceinline
#elif defined(__GNUC__)
#define FORCE_INLINE inline __attribute__((always_inline))
#else
#define FORCE_INLINE inline
#endif
#ifdef BUILD_FOR_SMALL_BINARY
#define INLINE FORCE_INLINE
#else
#define INLINE
#endif
/* ======== likely/unlikely ======== */
#if defined(__GNUC__) && __GNUC__ >= 4
#define LIKELY(x) (__builtin_expect((x), 1))
#define UNLIKELY(x) (__builtin_expect((x), 0))
#elif defined(_MSC_VER)
#define LIKELY(x) (x)
#define UNLIKELY(x) (x)
#else
#define LIKELY(x) (x)
#define UNLIKELY(x) (x)
#endif
/* ======== nullptr ======== */
#if __cplusplus < 201103L && !defined(_MSC_VER)
#ifndef nullptr
#define nullptr NULL
#endif
#define OVERRIDE
#else
#define OVERRIDE override
#endif
/* ======== cache line ======== */
#ifndef CACHE_LINE_SIZE
#define CACHE_LINE_SIZE 64
#endif
/* ======== assert ======== */
#ifdef NDEBUG
#define ASSERT(condition) ((void)0)
#else
#define ASSERT(condition) assert((condition))
#endif
/* ======== static assert ======== */
#if __cplusplus < 201103L && !defined(_MSC_VER)
#define STATIC_ASSERT(cond, msg) \
typedef char static_assertion_##msg[(cond) ? 1 : -1] __attribute__((unused))
#else
#define STATIC_ASSERT(cond, msg) static_assert((cond), #msg)
#endif
/* ======== atomic operations ======== */
#if defined(__GNUC__) || defined(__clang__)
#define ATOMIC_FAA(val_addr, addv) \
__atomic_fetch_add((val_addr), (addv), __ATOMIC_SEQ_CST)
#define ATOMIC_AAF(val_addr, addv) \
__atomic_add_fetch((val_addr), (addv), __ATOMIC_SEQ_CST)
#define ATOMIC_CAS(val_addr, expected, desired) \
__atomic_compare_exchange_n((val_addr), (expected), (desired), \
/* weak = */ false, \
/* success_memorder = */ __ATOMIC_SEQ_CST, \
/* failure_memorder = */ __ATOMIC_SEQ_CST)
#define ATOMIC_LOAD(val_addr) __atomic_load_n((val_addr), __ATOMIC_SEQ_CST)
#define ATOMIC_STORE(val_addr, val) \
__atomic_store_n((val_addr), (val), __ATOMIC_SEQ_CST)
#elif defined(_MSC_VER)
#include <intrin.h>
#define ATOMIC_FAA(val_addr, addv) _InterlockedExchangeAdd(val_addr, addv)
#ifdef _WIN64
#define ATOMIC_AAF(val_addr, addv) \
(_InterlockedExchangeAdd64(reinterpret_cast<volatile __int64*>(val_addr), static_cast<__int64>(addv)) + (addv))
#else
#define ATOMIC_AAF(val_addr, addv) \
(_InterlockedExchangeAdd(reinterpret_cast<volatile long*>(val_addr), static_cast<long>(addv)) + (addv))
#endif
#define ATOMIC_CAS(val_addr, expected, desired) \
(_InterlockedCompareExchange(val_addr, desired, *expected) == *expected)
#define ATOMIC_LOAD(val_addr) (*val_addr)
#define ATOMIC_STORE(val_addr, val) (*val_addr = val)
#else
#error "Atomic operations not supported on this platform"
#endif
/* ======== alignment ======== */
#if defined(_MSC_VER)
#define ALIGNED(a) __declspec(align(a))
#elif defined(__GNUC__)
#define ALIGNED(a) __attribute__((aligned(a)))
#else
#define ALIGNED(a)
#endif
#define ALIGNED_4 ALIGNED(4)
#define ALIGNED_8 ALIGNED(8)
/* ======== disallow copy and assign ======== */
#if __cplusplus < 201103L && !defined(_MSC_VER)
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
#else
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \
TypeName& operator=(const TypeName&) = delete;
#endif
/* ======== return value check ======== */
#define RET_FAIL(expr) UNLIKELY(common::E_OK != (ret = (expr)))
#define RFAIL(expr) UNLIKELY(common::E_OK != (ret = (expr)))
#define RET_SUCC(expr) LIKELY(common::E_OK == (ret = (expr)))
#define RSUCC(expr) LIKELY(common::E_OK == (ret = (expr)))
#define IS_SUCC(ret) LIKELY(common::E_OK == (ret))
#define IS_FAIL(ret) UNLIKELY(common::E_OK != (ret))
#define IS_NULL(ptr) UNLIKELY((ptr) == nullptr)
/* ======== min/max ======== */
#define UTIL_MAX(a, b) ((a) > (b) ? (a) : (b))
#define UTIL_MIN(a, b) ((a) > (b) ? (b) : (a))
/*
* int64_max < 10^20
* consider +/- and the '\0' tail. 24 is enough
*/
#define INT64_TO_BASE10_MAX_LEN 24
#endif // UTILS_UTIL_DEFINE_H