Skip to content

Commit

Permalink
update laster iguana
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacyking committed May 21, 2024
1 parent 248f35e commit 84c3cf7
Show file tree
Hide file tree
Showing 10 changed files with 1,453 additions and 15 deletions.
3 changes: 1 addition & 2 deletions iguana/detail/fast_float.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ from_chars_result from_chars_advanced(const char* first, const char* last,
#include <cstring>
#include <type_traits>


#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \
defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) || \
defined(__MINGW64__) || defined(__s390x__) || \
Expand Down Expand Up @@ -2709,7 +2708,7 @@ fastfloat_really_inline void round(adjusted_mantissa& am,
if (-am.power2 >= mantissa_shift) {
// have a denormal float
int32_t shift = -am.power2 + 1;
cb(am, std::min(shift, 64));
cb(am, (std::min)(shift, 64));
// check for round-up: if rounding-nearest carried us to the hidden bit.
am.power2 = (am.mantissa <
(uint64_t(1) << binary_format<T>::mantissa_explicit_bits()))
Expand Down
135 changes: 135 additions & 0 deletions iguana/detail/pb_type.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#pragma once

namespace iguana {

struct sint32_t {
using value_type = int32_t;
int32_t val;
bool operator==(const sint32_t& other) const { return val == other.val; }
};

inline bool operator==(sint32_t value1, int32_t value2) {
return value1.val == value2;
}

// for key in std::map
inline bool operator<(const sint32_t& lhs, const sint32_t& rhs) {
return lhs.val < rhs.val;
}

struct sint64_t {
using value_type = int64_t;
int64_t val;
bool operator==(const sint64_t& other) const { return val == other.val; }
};

inline bool operator==(sint64_t value1, int64_t value2) {
return value1.val == value2;
}

inline bool operator<(const sint64_t& lhs, const sint64_t& rhs) {
return lhs.val < rhs.val;
}

struct fixed32_t {
using value_type = uint32_t;
uint32_t val;
bool operator==(const fixed32_t& other) const { return val == other.val; }
};

inline bool operator==(fixed32_t value1, uint32_t value2) {
return value1.val == value2;
}

inline bool operator<(const fixed32_t& lhs, const fixed32_t& rhs) {
return lhs.val < rhs.val;
}

struct fixed64_t {
using value_type = uint64_t;
uint64_t val;
bool operator==(const fixed64_t& other) const { return val == other.val; }
};

inline bool operator==(fixed64_t value1, uint64_t value2) {
return value1.val == value2;
}

inline bool operator<(const fixed64_t& lhs, const fixed64_t& rhs) {
return lhs.val < rhs.val;
}

struct sfixed32_t {
using value_type = int32_t;
int32_t val;
bool operator==(const sfixed32_t& other) const { return val == other.val; }
};

inline bool operator==(sfixed32_t value1, int32_t value2) {
return value1.val == value2;
}

inline bool operator<(const sfixed32_t& lhs, const sfixed32_t& rhs) {
return lhs.val < rhs.val;
}

struct sfixed64_t {
using value_type = int64_t;
int64_t val;
bool operator==(const sfixed64_t& other) const { return val == other.val; }
};

inline bool operator==(sfixed64_t value1, int64_t value2) {
return value1.val == value2;
}

inline bool operator<(const sfixed64_t& lhs, const sfixed64_t& rhs) {
return lhs.val < rhs.val;
}

} // namespace iguana

// for key in std::unordered_map
namespace std {
template <>
struct hash<iguana::sint32_t> {
size_t operator()(const iguana::sint32_t& x) const noexcept {
return std::hash<int32_t>()(x.val);
}
};

template <>
struct hash<iguana::sint64_t> {
size_t operator()(const iguana::sint64_t& x) const noexcept {
return std::hash<int64_t>()(x.val);
}
};

template <>
struct hash<iguana::fixed32_t> {
size_t operator()(const iguana::fixed32_t& x) const noexcept {
return std::hash<uint32_t>()(x.val);
}
};

template <>
struct hash<iguana::fixed64_t> {
size_t operator()(const iguana::fixed64_t& x) const noexcept {
return std::hash<uint64_t>()(x.val);
}
};

template <>
struct hash<iguana::sfixed32_t> {
size_t operator()(const iguana::sfixed32_t& x) const noexcept {
return std::hash<int32_t>()(x.val);
}
};

template <>
struct hash<iguana::sfixed64_t> {
size_t operator()(const iguana::sfixed64_t& x) const noexcept {
return std::hash<int64_t>()(x.val);
}
};
} // namespace std
131 changes: 131 additions & 0 deletions iguana/detail/string_resize.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#pragma once
#include <cstddef>
#include <string>
#include <utility>
#include <vector>

namespace iguana::detail {

#if __cpp_lib_string_resize_and_overwrite >= 202110L
template <typename ch>
inline void resize(std::basic_string<ch> &str, std::size_t sz) {
str.resize_and_overwrite(sz, [sz](ch *, std::size_t) {
return sz;
});
}
#elif (defined(_MSC_VER) && _MSC_VER <= 1920)
// old msvc don't support visit private, discard it.

#else

template <typename Function, Function func_ptr>
class string_thief {
public:
friend void string_set_length_hacker(std::string &self, std::size_t sz) {
#if defined(_MSVC_STL_VERSION)
(self.*func_ptr)._Myval2._Mysize = sz;
#else
#if defined(_LIBCPP_VERSION)
(self.*func_ptr)(sz);
#else
#if (_GLIBCXX_USE_CXX11_ABI == 0) && defined(__GLIBCXX__)
(self.*func_ptr)()->_M_set_length_and_sharable(sz);
#else
#if defined(__GLIBCXX__)
(self.*func_ptr)(sz);
#endif
#endif
#endif
#endif
}
};

#if defined(__GLIBCXX__) // libstdc++
#if (_GLIBCXX_USE_CXX11_ABI == 0)
template class string_thief<decltype(&std::string::_M_rep),
&std::string::_M_rep>;
#else
template class string_thief<decltype(&std::string::_M_set_length),
&std::string::_M_set_length>;
#endif
#elif defined(_LIBCPP_VERSION)
template class string_thief<decltype(&std::string::__set_size),
&std::string::__set_size>;
#elif defined(_MSVC_STL_VERSION)
template class string_thief<decltype(&std::string::_Mypair),
&std::string::_Mypair>;
#endif

void string_set_length_hacker(std::string &, std::size_t);

template <typename ch>
inline void resize(std::basic_string<ch> &raw_str, std::size_t sz) {
std::string &str = *reinterpret_cast<std::string *>(&raw_str);
#if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) || \
defined(_MSVC_STL_VERSION)
if (sz > str.capacity()) {
str.reserve(sz);
}
string_set_length_hacker(str, sz);
str[sz] = '\0';
#else
raw_str.resize(sz);
#endif
}

#endif

#if (defined(_MSC_VER) && _MSC_VER <= 1920)
#else
void vector_set_length_hacker(std::vector<char> &self, std::size_t sz);

template <typename Function, Function func_ptr>
class vector_thief {
public:
friend void vector_set_length_hacker(std::vector<char> &self,
std::size_t sz) {
#if defined(_MSVC_STL_VERSION)
(self.*func_ptr)._Myval2._Mylast = self.data() + sz;
#else
#if defined(_LIBCPP_VERSION)
#if _LIBCPP_VERSION < 14000
((*(std::__vector_base<char, std::allocator<char> > *)(&self)).*func_ptr) =
self.data() + sz;
#else
(self.*func_ptr) = self.data() + sz;
#endif
#else
#if defined(__GLIBCXX__)
((*(std::_Vector_base<char, std::allocator<char> > *)(&self)).*func_ptr)
._M_finish = self.data() + sz;
#endif
#endif
#endif
}
};

#if defined(__GLIBCXX__) // libstdc++
template class vector_thief<decltype(&std::vector<char>::_M_impl),
&std::vector<char>::_M_impl>;
#elif defined(_LIBCPP_VERSION)
template class vector_thief<decltype(&std::vector<char>::__end_),
&std::vector<char>::__end_>;
#elif defined(_MSVC_STL_VERSION)
template class vector_thief<decltype(&std::vector<char>::_Mypair),
&std::vector<char>::_Mypair>;
#endif

template <typename ch>
inline void resize(std::vector<ch> &raw_vec, std::size_t sz) {
#if defined(__GLIBCXX__) || \
(defined(_LIBCPP_VERSION) && defined(_LIBCPP_HAS_NO_ASAN)) || \
defined(_MSVC_STL_VERSION)
std::vector<char> &vec = *reinterpret_cast<std::vector<char> *>(&raw_vec);
vec.reserve(sz);
vector_set_length_hacker(vec, sz);
#else
raw_vec.resize(sz);
#endif
}
#endif
}; // namespace iguana::detail
34 changes: 34 additions & 0 deletions iguana/detail/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,39 @@ struct member_tratis<T Owner::*> {
template <typename T>
inline constexpr bool is_int64_v =
std::is_same_v<T, int64_t> || std::is_same_v<T, uint64_t>;

template <typename T>
struct is_variant : std::false_type {};

template <typename... T>
struct is_variant<std::variant<T...>> : std::true_type {};

template <class T>
struct member_traits {
using value_type = T;
};

template <class T, class Owner>
struct member_traits<T Owner::*> {
using owner_type = Owner;
using value_type = T;
};

template <class T>
using member_value_type_t = typename member_traits<T>::value_type;

template <typename T, std::size_t I, typename = void>
struct variant_type_at {
using type = T;
};

template <typename T, std::size_t I>
struct variant_type_at<T, I, std::enable_if_t<is_variant<T>::value>> {
using type = std::variant_alternative_t<I, T>;
};
template <typename T, std::size_t I>
using variant_type_at_t =
typename variant_type_at<typename member_traits<T>::value_type, I>::type;

} // namespace iguana
#endif // SERIALIZE_TRAITS_HPP
Loading

0 comments on commit 84c3cf7

Please sign in to comment.