yalantinglibs/include/ylt/standalone/iguana/define.h

117 lines
3.6 KiB
C++

#pragma once
#if (defined(_MSC_VER) && _MSC_VER >= 1920 && _MSVC_LANG >= 202002L) || \
(!defined(_MSC_VER) && defined(__cplusplus) && __cplusplus >= 202002L)
#include <bit>
#endif
#include <array>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>
#if defined __clang__
#define IGUANA_INLINE __attribute__((always_inline)) inline
#define IGUANA__INLINE_LAMBDA __attribute__((always_inline)) constexpr
#elif defined _MSC_VER
#define IGUANA_INLINE __forceinline
#define IGUANA__INLINE_LAMBDA constexpr
#else
#define IGUANA_INLINE __attribute__((always_inline)) inline
#define IGUANA__INLINE_LAMBDA constexpr __attribute__((always_inline))
#endif
#if __has_cpp_attribute(likely) && __has_cpp_attribute(unlikely)
#define IGUANA_LIKELY [[likely]]
#define IGUANA_UNLIKELY [[unlikely]]
#else
#define IGUANA_LIKELY
#define IGUANA_UNLIKELY
#endif
#ifdef _MSC_VER
#if _MSC_VER >= 1920 && _MSVC_LANG >= 202002L
IGUANA_INLINE int countr_zero(unsigned long long x) {
return std::countr_zero(x);
}
template <typename T>
constexpr inline bool contiguous_iterator = std::contiguous_iterator<T>;
#else
IGUANA_INLINE int countr_zero(unsigned long long n) {
// x will never be zero in iguana
#if defined(_MSC_VER) && defined(_M_X64)
unsigned long c;
_BitScanForward64(&c, n);
return static_cast<int>(c);
#elif defined(_MSC_VER) && defined(_M_IX86)
unsigned long c;
if (static_cast<uint32_t>(n) != 0) {
_BitScanForward(&c, static_cast<uint32_t>(n));
return static_cast<int>(c);
}
else {
_BitScanForward(&c, static_cast<uint32_t>(n >> 32));
return static_cast<int>(c) + 32;
}
#endif
}
namespace std {
template <typename T>
using remove_cvref_t =
typename remove_cv<typename remove_reference<T>::type>::type;
}
template <typename T>
constexpr inline bool contiguous_iterator =
std::is_same_v<std::remove_cvref_t<T>,
typename std::vector<char>::iterator> ||
std::is_same_v<std::remove_cvref_t<T>,
typename std::vector<char>::const_iterator> ||
std::is_same_v<std::remove_cvref_t<T>, typename std::string::iterator> ||
std::is_same_v<std::remove_cvref_t<T>,
typename std::string::const_iterator> ||
std::is_same_v<std::remove_cvref_t<T>, char *> ||
std::is_same_v<std::remove_cvref_t<T>,
typename std::string_view::iterator> ||
std::is_same_v<std::remove_cvref_t<T>,
typename std::string_view::const_iterator>;
#endif
#else
#if __cplusplus >= 202002L
IGUANA_INLINE int countr_zero(unsigned long long x) {
return std::countr_zero(x);
}
template <typename T>
constexpr inline bool contiguous_iterator = std::contiguous_iterator<T>;
#else
IGUANA_INLINE int countr_zero(unsigned long long x) {
// x will never be zero in iguana
return __builtin_ctzll(x);
}
namespace std {
template <typename T>
using remove_cvref_t =
typename remove_cv<typename remove_reference<T>::type>::type;
}
template <typename T>
constexpr inline bool contiguous_iterator =
std::is_same_v<std::remove_cvref_t<T>,
typename std::vector<char>::iterator> ||
std::is_same_v<std::remove_cvref_t<T>,
typename std::vector<char>::const_iterator> ||
std::is_same_v<std::remove_cvref_t<T>, typename std::string::iterator> ||
std::is_same_v<std::remove_cvref_t<T>,
typename std::string::const_iterator> ||
std::is_same_v<std::remove_cvref_t<T>, char *> ||
std::is_same_v<std::remove_cvref_t<T>,
typename std::string_view::iterator> ||
std::is_same_v<std::remove_cvref_t<T>,
typename std::string_view::const_iterator>;
#endif
#endif