Skip to content

Commit

Permalink
Merge pull request #319 from qicosmos/support_stream
Browse files Browse the repository at this point in the history
  • Loading branch information
qicosmos authored Oct 21, 2024
2 parents bfab303 + a8ff737 commit 8c4426d
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 71 deletions.
95 changes: 95 additions & 0 deletions iguana/detail/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,100 @@ template <typename T, std::size_t I>
using variant_type_at_t =
typename variant_type_at<typename member_traits<T>::value_type, I>::type;

/// concepts
template <typename Type>
constexpr bool is_char_v =
std::is_same_v<Type, signed char> || std::is_same_v<Type, char> ||
std::is_same_v<Type, unsigned char> || std::is_same_v<Type, wchar_t> ||
std::is_same_v<Type, char16_t> || std::is_same_v<Type, char32_t>
#ifdef __cpp_lib_char8_t
|| std::is_same_v<Type, char8_t>
#endif
;

#if __cplusplus >= 202002L
template <typename Type>
concept is_container_v = requires(Type container) {
typename std::remove_cvref_t<Type>::value_type;
container.size();
container.begin();
container.end();
};

template <typename Type>
concept is_resizable_char_container_v = requires(Type container) {
typename std::remove_cvref_t<Type>::value_type;
container.size();
container.begin();
container.end();
requires is_char_v<typename std::remove_cvref_t<Type>::value_type>;
container.resize(std::size_t{});
};

template <typename T>
concept char_writer = requires(T t) {
t.write((const char *)nullptr, std::size_t{});
};

template <typename T>
concept char_reader = requires(T t) {
t.read((char *)nullptr, std::size_t{});
};
#else
template <typename T, typename = void>
struct container_impl : std::false_type {};

template <typename T>
struct container_impl<T,
std::void_t<typename std::remove_cvref_t<T>::value_type,
decltype(std::declval<T>().size()),
decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end())>>
: std::true_type {};

template <typename T>
constexpr bool is_container_v = container_impl<T>::value;

template <typename T, typename = void>
struct resizable_char_container_impl : std::false_type {};

template <typename T>
struct resizable_char_container_impl<
T, std::void_t<typename std::remove_cvref_t<T>::value_type,
decltype(std::declval<T>().size()),
decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end()),
std::enable_if_t<
is_char_v<typename std::remove_cvref_t<T>::value_type>>,
decltype(std::declval<T>().resize(std::size_t{}))>>
: std::true_type {};

template <typename T>
constexpr bool is_resizable_char_container_v =
resizable_char_container_impl<T>::value;

template <typename T, typename = void>
struct char_writer_impl : std::false_type {};

template <typename T>
struct char_writer_impl<T, std::void_t<decltype(std::declval<T>().write(
(const char *)nullptr, std::size_t{}))>>
: std::true_type {};

template <typename T>
constexpr bool char_writer = char_writer_impl<T>::value;

template <typename T, typename = void>
struct char_reader_impl : std::false_type {};

template <typename T>
struct char_reader_impl<T, std::void_t<decltype(std::declval<T>().read(
(char *)nullptr, std::size_t{}))>>
: std::true_type {};

template <typename T>
constexpr bool char_reader = char_reader_impl<T>::value;
#endif

} // namespace iguana
#endif // SERIALIZE_TRAITS_HPP
42 changes: 22 additions & 20 deletions iguana/pb_util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,41 +193,43 @@ constexpr size_t variant_uint32_size_constexpr(uint32_t value) {
return log / 7 + 1;
}

template <uint64_t v, size_t I, typename It>
IGUANA_INLINE void append_varint_u32_constexpr_help(It&& it) {
*(it++) = static_cast<uint8_t>((v >> (7 * I)) | 0x80);
template <uint64_t v, typename Writer, size_t... I>
IGUANA_INLINE void append_varint_u32(Writer& writer,
std::index_sequence<I...>) {
uint8_t temp = 0;
((temp = static_cast<uint8_t>(v >> (7 * I)), writer.write(&temp, 1)), ...);
}

template <uint64_t v, typename It, size_t... I>
IGUANA_INLINE void append_varint_u32_constexpr(It&& it,
std::index_sequence<I...>) {
(append_varint_u32_constexpr_help<v, I>(it), ...);
}

template <uint32_t v, typename It>
IGUANA_INLINE void serialize_varint_u32_constexpr(It&& it) {
template <uint32_t v, typename Writer>
IGUANA_INLINE void serialize_varint_u32(Writer& writer) {
constexpr auto size = variant_uint32_size_constexpr(v);
append_varint_u32_constexpr<v>(it, std::make_index_sequence<size - 1>{});
*(it++) = static_cast<uint8_t>(v >> (7 * (size - 1)));
append_varint_u32<v>(writer, std::make_index_sequence<size - 1>{});
uint8_t temp = static_cast<uint8_t>(v >> (7 * (size - 1)));
writer.write((const char*)&temp, 1);
}

template <typename It>
IGUANA_INLINE void serialize_varint(uint64_t v, It&& it) {
template <typename Writer>
IGUANA_INLINE void serialize_varint(uint64_t v, Writer& writer) {
uint8_t temp = static_cast<uint8_t>(v);
if (v < 0x80) {
*(it++) = static_cast<uint8_t>(v);
writer.write((const char*)&temp, 1);
return;
}
*(it++) = static_cast<uint8_t>(v | 0x80);
temp = static_cast<uint8_t>(v | 0x80);
writer.write((const char*)&temp, 1);
v >>= 7;
if (v < 0x80) {
*(it++) = static_cast<uint8_t>(v);
temp = static_cast<uint8_t>(v);
writer.write((const char*)&temp, 1);
return;
}
do {
*(it++) = static_cast<uint8_t>(v | 0x80);
temp = static_cast<uint8_t>(v | 0x80);
writer.write((const char*)&temp, 1);
v >>= 7;
} while (v >= 0x80);
*(it++) = static_cast<uint8_t>(v);
temp = static_cast<uint8_t>(v);
writer.write((const char*)&temp, 1);
}

IGUANA_INLINE uint32_t log2_floor_uint32(uint32_t n) {
Expand Down
Loading

0 comments on commit 8c4426d

Please sign in to comment.