Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update iguana and cfg #111

Merged
merged 1 commit into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions include/iguana/define.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#pragma once

#include <array>
#include <bit>
#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 x) {
// x will never be zero in iguana
unsigned long pos;
_BitScanForward64(&pos, x);
return pos;
}

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
45 changes: 45 additions & 0 deletions include/iguana/detail/charconv.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#pragma once
#include "dragonbox_to_chars.h"
#include "fast_float.h"
#include "itoa.hpp"
#include <charconv>

namespace iguana {
template <typename T>
struct is_char_type
: std::disjunction<std::is_same<T, char>, std::is_same<T, unsigned char>,
std::is_same<T, signed char>, std::is_same<T, wchar_t>,
std::is_same<T, char16_t>, std::is_same<T, char32_t>> {};

namespace detail {
template <typename U>
std::pair<const char *, std::errc>
from_chars(const char *first, const char *last, U &value) noexcept {
using T = std::decay_t<U>;
if constexpr (std::is_floating_point_v<T>) {
auto [p, ec] = fast_float::from_chars(first, last, value);
return {p, ec};
} else {
auto [p, ec] = std::from_chars(first, last, value);
return {p, ec};
}
}

// not support uint8 for now
template <typename T> char *to_chars(char *buffer, T value) noexcept {
using U = std::decay_t<T>;
if constexpr (std::is_floating_point_v<U>) {
return jkj::dragonbox::to_chars(value, buffer);
} else if constexpr (std::is_signed_v<U> && (sizeof(U) >= 8)) {
return xtoa(value, buffer, 10, 1); // int64_t
} else if constexpr (std::is_unsigned_v<U> && (sizeof(U) >= 8)) {
return xtoa(value, buffer, 10, 0); // uint64_t
} else if constexpr (std::is_integral_v<U> && !is_char_type<U>::value) {
return itoa_fwd(value, buffer); // only support more than 2 bytes intergal
} else {
static_assert(!sizeof(U), "only support arithmetic type except char type");
}
}

} // namespace detail
} // namespace iguana
Loading
Loading