mirror of https://gitee.com/bigwinds/arangodb
375 lines
13 KiB
C++
375 lines
13 KiB
C++
////////////////////////////////////////////////////////////////////////////////
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2016 by EMC Corporation, All Rights Reserved
|
|
///
|
|
/// Licensed 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.
|
|
///
|
|
/// Copyright holder is EMC Corporation
|
|
///
|
|
/// @author Andrey Abramov
|
|
/// @author Vasiliy Nabatchikov
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef IRESEARCH_SHARED_H
|
|
#define IRESEARCH_SHARED_H
|
|
|
|
#include <cfloat>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <cstddef> //need this for wchar_t, size_t, NULL
|
|
#include <stdint.h> //need this for int32_t, etc
|
|
#include <math.h> //required for float_t
|
|
#include <string> //need to include this really early...
|
|
|
|
#if (defined(__GNUC__) && __GNUC__ == 8 && __GNUC_MINOR__ < 1)
|
|
// protection against broken GCC 8.0 from Ubuntu 18.04 official repository
|
|
#error "GCC 8.0 isn't officially supported (https://gcc.gnu.org/releases.html)"
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// C++ standard
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef __cplusplus
|
|
#error C++ is required
|
|
#endif
|
|
|
|
#define IRESEARCH_CXX_98 199711L // c++03/c++98
|
|
#define IRESEARCH_CXX_11 201103L // c++11
|
|
#define IRESEARCH_CXX_14 201402L // c++14
|
|
#define IRESEARCH_CXX_17 201703L // c++17
|
|
|
|
#if defined(_MSC_VER)
|
|
// MSVC doesn't honor __cplusplus macro,
|
|
// it always equals to IRESEARCH_CXX_98
|
|
// therefore we use _MSC_VER
|
|
#if _MSC_VER < 1800 // before MSVC2013
|
|
#error "at least C++11 is required"
|
|
#elif _MSC_VER >= 1800 && _MSC_VER < 1910 // MSVC2013-2015
|
|
// not MSVC2015 nor MSVC2017 are not c++14 compatible
|
|
#define IRESEARCH_CXX IRESEARCH_CXX_11
|
|
#elif _MSC_VER >= 1910 // MSVC2017 and later
|
|
#define IRESEARCH_CXX IRESEARCH_CXX_14
|
|
#endif
|
|
#else // GCC/Clang
|
|
#if __cplusplus < IRESEARCH_CXX_11
|
|
#error "at least C++11 is required"
|
|
#elif __cplusplus >= IRESEARCH_CXX_11 && __cplusplus < IRESEARCH_CXX_14
|
|
#define IRESEARCH_CXX IRESEARCH_CXX_11
|
|
#elif __cplusplus >= IRESEARCH_CXX_14 && __cplusplus < IRESEARCH_CXX_17
|
|
#define IRESEARCH_CXX IRESEARCH_CXX_14
|
|
#elif __cplusplus >= IRESEARCH_CXX_17
|
|
#define IRESEARCH_CXX IRESEARCH_CXX_17
|
|
#endif
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// Export/Import definitions
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Generic helper definitions for shared library support
|
|
#if defined _MSC_VER || defined __CYGWIN__
|
|
#define IRESEARCH_HELPER_DLL_IMPORT __declspec(dllimport)
|
|
#define IRESEARCH_HELPER_DLL_EXPORT __declspec(dllexport)
|
|
#define IRESEARCH_HELPER_DLL_LOCAL
|
|
#define IRESEARCH_HELPER_TEMPLATE_IMPORT
|
|
#define IRESEARCH_HELPER_TEMPLATE_EXPORT
|
|
|
|
#if _MSC_VER < 1900 // before msvc2015
|
|
#define CONSTEXPR
|
|
#define NOEXCEPT throw()
|
|
#define ALIGNOF(v) __alignof(v)
|
|
#define ALIGNAS(v) __declspec(align(v))
|
|
#else
|
|
#define CONSTEXPR constexpr
|
|
#define NOEXCEPT noexcept
|
|
#define ALIGNOF(v) alignof(v)
|
|
#define ALIGNAS(v) alignas(v)
|
|
|
|
// MSVC2017.1 - MSVC2017.7 does not correctly support alignas()
|
|
// FIXME TODO find a workaround or do not use alignas(...) and remove definition from CMakeLists.txt
|
|
static_assert(_MSC_VER <= 1910 || _MSC_VER >= 1916, "_MSC_VER > 1910 && _MSC_VER < 1915");
|
|
#endif
|
|
|
|
#define FORCE_INLINE inline __forceinline
|
|
#define NO_INLINE __declspec(noinline)
|
|
#define RESTRICT __restrict
|
|
#define IRESEARCH_IGNORE_UNUSED /* unused */
|
|
#else
|
|
#if defined(__GNUC__) && __GNUC__ >= 4
|
|
#define IRESEARCH_HELPER_DLL_IMPORT __attribute__ ((visibility ("default")))
|
|
#define IRESEARCH_HELPER_DLL_EXPORT __attribute__ ((visibility ("default")))
|
|
#define IRESEARCH_HELPER_DLL_LOCAL __attribute__ ((visibility ("hidden")))
|
|
#define CONSTEXPR constexpr
|
|
#else
|
|
#define IRESEARCH_HELPER_DLL_IMPORT
|
|
#define IRESEARCH_HELPER_DLL_EXPORT
|
|
#define IRESEARCH_HELPER_DLL_LOCAL
|
|
#define CONSTEXPR
|
|
#endif
|
|
#define IRESEARCH_HELPER_TEMPLATE_IMPORT IRESEARCH_HELPER_DLL_IMPORT
|
|
#define IRESEARCH_HELPER_TEMPLATE_EXPORT IRESEARCH_HELPER_DLL_EXPORT
|
|
|
|
#define NOEXCEPT noexcept
|
|
#define ALIGNOF(v) alignof(v)
|
|
#define ALIGNAS(v) alignas(v)
|
|
#define FORCE_INLINE inline __attribute__ ((always_inline))
|
|
#define NO_INLINE __attribute__ ((noinline))
|
|
#define RESTRICT __restrict__
|
|
#define IRESEARCH_IGNORE_UNUSED __attribute__ ((unused))
|
|
#endif
|
|
|
|
#if (defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ < 9)
|
|
// GCC4.8 doesn't have std::max_align_t
|
|
#define MAX_ALIGN_T ::max_align_t
|
|
#else
|
|
#define MAX_ALIGN_T std::max_align_t
|
|
#endif
|
|
|
|
// hook for GCC 8.1/8.2 optimized code
|
|
// these versions produce incorrect code when inlining optimizations are enabled
|
|
#if defined(__OPTIMIZE__) && defined(__GNUC__) \
|
|
&& ((__GNUC__ == 8 && __GNUC_MINOR__ == 1) \
|
|
|| (__GNUC__ == 8 && __GNUC_MINOR__ == 2))
|
|
#define GCC8_12_OPTIMIZED_WORKAROUND(...) __VA_ARGS__
|
|
#else
|
|
#define GCC8_12_OPTIMIZED_WORKAROUND(...)
|
|
#endif
|
|
|
|
// hook for MSVC2017.3-9 optimized code
|
|
// these versions produce incorrect code when inlining optimizations are enabled
|
|
// for versions @see https://github.com/lordmulder/MUtilities/blob/master/include/MUtils/Version.h
|
|
// and https://dev.to/yumetodo/list-of-mscver-and-mscfullver-8nd
|
|
#if defined(_MSC_VER) \
|
|
&& !defined(_DEBUG) \
|
|
&& (((_MSC_FULL_VER >= 191125506) && (_MSC_FULL_VER <= 191125508)) \
|
|
|| ((_MSC_FULL_VER >= 191125542) && (_MSC_FULL_VER <= 191125547)) \
|
|
|| ((_MSC_FULL_VER >= 191225830) && (_MSC_FULL_VER <= 191225835)) \
|
|
|| ((_MSC_FULL_VER >= 191326128) && (_MSC_FULL_VER <= 191326132)) \
|
|
|| ((_MSC_FULL_VER >= 191426430) && (_MSC_FULL_VER <= 191426433)) \
|
|
|| ((_MSC_FULL_VER >= 191526726) && (_MSC_FULL_VER <= 191526732)) \
|
|
|| ((_MSC_FULL_VER >= 191627023) && (_MSC_FULL_VER <= 191627032)))
|
|
#define MSVC2017_3456789_OPTIMIZED_WORKAROUND(...) __VA_ARGS__
|
|
#else
|
|
#define MSVC2017_3456789_OPTIMIZED_WORKAROUND(...)
|
|
#endif
|
|
|
|
// hook for MSVC-only code
|
|
#if defined(_MSC_VER)
|
|
#define MSVC_ONLY(...) __VA_ARGS__
|
|
#else
|
|
#define MSVC_ONLY(...)
|
|
#endif
|
|
|
|
// hook for MSVC2013-only code
|
|
#if defined(_MSC_VER) && _MSC_VER == 1800
|
|
#define MSVC2013_ONLY(...) __VA_ARGS__
|
|
#else
|
|
#define MSVC2013_ONLY(...)
|
|
#endif
|
|
|
|
// hook for MSVC2015-only code
|
|
#if defined(_MSC_VER) && _MSC_VER == 1900
|
|
#define MSVC2015_ONLY(...) __VA_ARGS__
|
|
#else
|
|
#define MSVC2015_ONLY(...)
|
|
#endif
|
|
|
|
// hook for MSVC2015 optimized-only code
|
|
#if defined(_MSC_VER) && !defined(_DEBUG) && _MSC_VER == 1900
|
|
#define MSVC2015_OPTIMIZED_ONLY(...) __VA_ARGS__
|
|
#else
|
|
#define MSVC2015_OPTIMIZED_ONLY(...)
|
|
#endif
|
|
|
|
// hook for MSVC2017-only code (2017.2 || 2017.3/2017.4 || 2017.5 || 2017.6 || 2017.7 || 2017.8 || 2017.9)
|
|
#if defined(_MSC_VER) \
|
|
&& (_MSC_VER == 1910 \
|
|
|| _MSC_VER == 1911 \
|
|
|| _MSC_VER == 1912 \
|
|
|| _MSC_VER == 1913 \
|
|
|| _MSC_VER == 1914 \
|
|
|| _MSC_VER == 1915 \
|
|
|| _MSC_VER == 1916)
|
|
#define MSVC2017_ONLY(...) __VA_ARGS__
|
|
#else
|
|
#define MSVC2017_ONLY(...)
|
|
#endif
|
|
|
|
#if defined(_MSC_VER) \
|
|
&& (_MSC_VER == 1920)
|
|
#define MSVC2019_ONLY(...) __VA_ARGS__
|
|
#else
|
|
#define MSVC2019_ONLY(...)
|
|
#endif
|
|
|
|
// hook for GCC-only code
|
|
#if defined(__GNUC__)
|
|
#define GCC_ONLY(...) __VA_ARGS__
|
|
#else
|
|
#define GCC_ONLY(...)
|
|
#endif
|
|
|
|
// hool for Valgrind-only code
|
|
#if defined(IRESEARCH_VALGRIND)
|
|
#define VALGRIND_ONLY(...) __VA_ARGS__
|
|
#else
|
|
#define VALGRIND_ONLY(...)
|
|
#endif
|
|
|
|
// check if sizeof(float_t) == sizeof(double_t)
|
|
#if defined(FLT_EVAL_METHOD) && ((FLT_EVAL_METHOD == 1) || (FLT_EVAL_METHOD == 2))
|
|
static_assert(sizeof(float_t) == sizeof(double_t), "sizeof(float_t) != sizeof(double_t)");
|
|
#define FLOAT_T_IS_DOUBLE_T
|
|
#else
|
|
static_assert(sizeof(float_t) != sizeof(double_t), "sizeof(float_t) == sizeof(double_t)");
|
|
#undef FLOAT_T_IS_DOUBLE_T
|
|
#endif
|
|
|
|
// IRESEARCH_API is used for the public API symbols. It either DLL imports or DLL exports (or does nothing for static build)
|
|
// IRESEARCH_LOCAL is used for non-api symbols.
|
|
// IRESEARCH_PLUGIN is used for public API symbols of plugin modules
|
|
#ifdef IRESEARCH_DLL
|
|
#ifdef IRESEARCH_DLL_EXPORTS
|
|
#define IRESEARCH_API IRESEARCH_HELPER_DLL_EXPORT
|
|
#define IRESEARCH_API_TEMPLATE IRESEARCH_HELPER_TEMPLATE_EXPORT
|
|
#else
|
|
#define IRESEARCH_API IRESEARCH_HELPER_DLL_IMPORT
|
|
#define IRESEARCH_API_TEMPLATE IRESEARCH_HELPER_TEMPLATE_IMPORT
|
|
#endif // IRESEARCH_DLL_EXPORTS
|
|
#define IRESEARCH_API_PRIVATE_VARIABLES_BEGIN MSVC_ONLY(__pragma(warning(disable: 4251)))
|
|
#define IRESEARCH_API_PRIVATE_VARIABLES_END MSVC_ONLY(__pragma(warning(default: 4251)))
|
|
#define IRESEARCH_LOCAL IRESEARCH_HELPER_DLL_LOCAL
|
|
#ifdef IRESEARCH_DLL_PLUGIN
|
|
#define IRESEARCH_PLUGIN IRESEARCH_HELPER_DLL_EXPORT
|
|
#define IRESEARCH_PLUGIN_EXPORT extern "C" IRESEARCH_HELPER_DLL_EXPORT
|
|
#else
|
|
#define IRESEARCH_PLUGIN IRESEARCH_HELPER_DLL_IMPORT
|
|
#define IRESEARCH_PLUGIN_EXPORT
|
|
#endif // IRESEARCH_DLL_PLUGIN
|
|
#define IRESEARCH_TEMPLATE_EXPORT(x) template IRESEARCH_API x
|
|
#define IRESEARCH_TEMPLATE_IMPORT(x) extern template x
|
|
#else // IRESEARCH_DLL is not defined: this means IRESEARCH is a static lib.
|
|
#define IRESEARCH_API
|
|
#define IRESEARCH_API_TEMPLATE
|
|
#define IRESEARCH_API_PRIVATE_VARIABLES_BEGIN
|
|
#define IRESEARCH_API_PRIVATE_VARIABLES_END
|
|
#define IRESEARCH_LOCAL
|
|
#define IRESEARCH_PLUGIN
|
|
#define IRESEARCH_TEMPLATE_EXPORT(x)
|
|
#define IRESEARCH_TEMPLATE_IMPORT(x)
|
|
#endif // IRESEARCH_DLL
|
|
|
|
// MSVC 2015 does not define __cpp_lib_generic_associative_lookup macro
|
|
#if (defined(__cpp_lib_generic_associative_lookup) || (defined(_MSC_VER) && _MSC_VER >= 1900))
|
|
#define IRESEARCH_GENERIC_ASSOCIATIVE_LOOKUP
|
|
#endif
|
|
|
|
#if defined(__GNUC__)
|
|
#define IRESEARCH_INIT(f) \
|
|
static void f(void) __attribute__((constructor)); \
|
|
static void f(void)
|
|
#define RESEARCH_FINI(f) \
|
|
static void f(void) __attribute__((destructor)); \
|
|
static void f(void)
|
|
#elif defined(_MSC_VER)
|
|
#define IRESEARCH_INIT(f) \
|
|
static void __cdecl f(void); \
|
|
static int f ## _init_wrapper(void) { f(); return 0; } \
|
|
__declspec(allocate(".CRT$XCU")) void (__cdecl*f##_)(void) = f ## _init_wrapper; \
|
|
static void __cdecl f(void)
|
|
#define RESEARCH_FINI(f) \
|
|
static void __cdecl f(void); \
|
|
static int f ## _fini_wrapper(void) { atexit(f); return 0; } \
|
|
__declspec(allocate(".CRT$XCU")) static int (__cdecl*f##_)(void) = f ## _fini_wrapper; \
|
|
static void __cdecl f(void)
|
|
#endif
|
|
|
|
// define function name used for pretty printing
|
|
// NOTE: the alias points to a compile time finction not a preprocessor macro
|
|
#if defined(__GNUC__)
|
|
#define CURRENT_FUNCTION __PRETTY_FUNCTION__
|
|
#elif defined(_MSC_VER)
|
|
#define CURRENT_FUNCTION __FUNCSIG__
|
|
#endif
|
|
|
|
#ifndef __has_feature
|
|
#define IRESEARCH_COMPILER_HAS_FEATURE(x) 0 // Compatibility with non-clang compilers.
|
|
#else
|
|
#define IRESEARCH_COMPILER_HAS_FEATURE(x) __has_feature(x)
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// SSE compatibility
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifdef __SSE2__
|
|
#define IRESEARCH_SSE2
|
|
#endif
|
|
|
|
#ifdef __SSE4_1__
|
|
#define IRESEARCH_SSE4_1
|
|
#endif
|
|
|
|
#ifdef __SSE4_2__
|
|
#define IRESEARCH_SSE4_2
|
|
#endif
|
|
|
|
#ifdef __AVX__
|
|
#define IRESEARCH_AVX
|
|
#endif
|
|
|
|
#ifdef __AVX2__
|
|
#define IRESEARCH_AVX2
|
|
#endif
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// likely/unlikely branch indicator
|
|
// macro definitions similar to the ones at
|
|
// https://kernelnewbies.org/FAQ/LikelyUnlikely
|
|
#if defined(__GNUC__) || defined(__GNUG__)
|
|
#define IRS_LIKELY(v) __builtin_expect(!!(v), 1)
|
|
#define IRS_UNLIKELY(v) __builtin_expect(!!(v), 0)
|
|
#else
|
|
#define IRS_LIKELY(v) v
|
|
#define IRS_UNLIKELY(v) v
|
|
#endif
|
|
|
|
#ifdef IRESEARCH_DEBUG
|
|
#define IRS_ASSERT(CHECK) \
|
|
( (CHECK) ? void(0) : []{assert(!#CHECK);}() )
|
|
#else
|
|
#define IRS_ASSERT(CHECK) void(0)
|
|
#endif
|
|
|
|
#define UNUSED(par) (void)(par)
|
|
|
|
#define NS_BEGIN(ns) namespace ns {
|
|
#define NS_LOCAL namespace {
|
|
#define NS_ROOT NS_BEGIN(iresearch)
|
|
#define NS_END }
|
|
|
|
NS_ROOT NS_END // ROOT namespace predeclaration
|
|
namespace irs = ::iresearch;
|
|
|
|
#define ASSERT( cond, mess ) assert( (cond) && (mess) )
|
|
|
|
#define STRINGIFY(x) #x
|
|
#define TOSTRING(x) STRINGIFY(x)
|
|
|
|
#include "types.hpp" // iresearch types
|
|
|
|
#endif // IRESEACH_SHARED_H
|