diff --git a/include/ylt/coro_io/rate_limiter.hpp b/include/ylt/coro_io/rate_limiter.hpp index b9b96fd1e..62340b775 100644 --- a/include/ylt/coro_io/rate_limiter.hpp +++ b/include/ylt/coro_io/rate_limiter.hpp @@ -101,7 +101,8 @@ class abstract_smooth_rate_limiter : public rate_limiter { do_set_rate(permits_per_second, stable_internal_micros); } std::chrono::steady_clock::time_point reserve_earliest_available( - int required_permits, std::chrono::steady_clock::time_point now_micros) { + int required_permits, + std::chrono::steady_clock::time_point now_micros) override { resync(now_micros); std::chrono::steady_clock::time_point return_value = this->next_free_ticket_micros_; diff --git a/include/ylt/coro_rpc/impl/coro_rpc_client.hpp b/include/ylt/coro_rpc/impl/coro_rpc_client.hpp index cdf6ea004..2a8bda43b 100644 --- a/include/ylt/coro_rpc/impl/coro_rpc_client.hpp +++ b/include/ylt/coro_rpc/impl/coro_rpc_client.hpp @@ -669,6 +669,7 @@ class coro_rpc_client { } auto &header = *(coro_rpc_protocol::req_header *)buffer.data(); + header = {}; header.magic = coro_rpc_protocol::magic_number; header.function_id = func_id(); #ifdef UNIT_TEST_INJECT diff --git a/include/ylt/struct_pack.hpp b/include/ylt/struct_pack.hpp index a4b524437..3d5b2c50a 100644 --- a/include/ylt/struct_pack.hpp +++ b/include/ylt/struct_pack.hpp @@ -152,7 +152,7 @@ STRUCT_PACK_INLINE void serialize_to(Writer &writer, const Args &...args) { auto data_offset = writer.size(); auto info = detail::get_serialize_runtime_info(args...); auto total = data_offset + info.size(); - writer.resize(total); + detail::resize(writer, total); auto real_writer = struct_pack::detail::memory_writer{(char *)writer.data() + data_offset}; struct_pack::detail::serialize_to(real_writer, info, args...); @@ -189,7 +189,7 @@ void STRUCT_PACK_INLINE serialize_to_with_offset(Buffer &buffer, static_assert(sizeof...(args) > 0); auto info = detail::get_serialize_runtime_info(args...); auto old_size = buffer.size(); - buffer.resize(old_size + offset + info.size()); + detail::resize(buffer, old_size + offset + info.size()); auto writer = struct_pack::detail::memory_writer{(char *)buffer.data() + old_size + offset}; struct_pack::detail::serialize_to(writer, info, args...); diff --git a/include/ylt/struct_pack/type_trait.hpp b/include/ylt/struct_pack/type_trait.hpp index d2bc224fc..20946f712 100644 --- a/include/ylt/struct_pack/type_trait.hpp +++ b/include/ylt/struct_pack/type_trait.hpp @@ -25,7 +25,7 @@ namespace struct_pack::detail { template constexpr bool struct_pack_byte = std::is_same_v || std::is_same_v || - std::is_same_v; + std::is_same_v || std::is_same_v; template #if __cpp_concepts < 201907L diff --git a/include/ylt/struct_pack/util.h b/include/ylt/struct_pack/util.h index 9c54ac0b1..7ba44f791 100644 --- a/include/ylt/struct_pack/util.h +++ b/include/ylt/struct_pack/util.h @@ -15,6 +15,10 @@ */ #pragma once #include +#include +#include +#include +#include #include "marco.h" namespace struct_pack::detail { @@ -77,4 +81,133 @@ constexpr void STRUCT_PACK_INLINE compile_time_unique( } } } + +#if __cpp_lib_string_resize_and_overwrite >= 202110L +template +inline void resize(std::basic_string &str, std::size_t sz) { + str.resize_and_overwrite(sz, [](ch *, std::size_t sz) { + return sz; + }); +} +#elif (defined(_MSC_VER) && _MSC_VER <= 1920) +// old msvc don't support visit private, discard it. + +#else + +template +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; +#else +template class string_thief; +#endif +#elif defined(_LIBCPP_VERSION) +template class string_thief; +#elif defined(_MSVC_STL_VERSION) +template class string_thief; +#endif + +void string_set_length_hacker(std::string &, std::size_t); + +template +inline void resize(std::basic_string &raw_str, std::size_t sz) { + std::string &str = *reinterpret_cast(&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 &self, std::size_t sz); + +template +class vector_thief { + public: + friend void vector_set_length_hacker(std::vector &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> *)(&self)).*func_ptr) = + self.data() + sz; +#else + (self.*func_ptr) = self.data() + sz; +#endif +#else +#if defined(__GLIBCXX__) + ((*(std::_Vector_base> *)(&self)).*func_ptr) + ._M_finish = self.data() + sz; +#endif +#endif +#endif + } +}; + +#if defined(__GLIBCXX__) // libstdc++ +template class vector_thief::_M_impl), + &std::vector::_M_impl>; +#elif defined(_LIBCPP_VERSION) +template class vector_thief::__end_), + &std::vector::__end_>; +#elif defined(_MSVC_STL_VERSION) +template class vector_thief::_Mypair), + &std::vector::_Mypair>; +#endif + +template +inline void resize(std::vector &raw_vec, std::size_t sz) { +#if defined(__GLIBCXX__) || \ + (defined(_LIBCPP_VERSION) && defined(_LIBCPP_HAS_NO_ASAN)) || \ + defined(_MSVC_STL_VERSION) + std::vector &vec = *reinterpret_cast *>(&raw_vec); + vec.reserve(sz); + vector_set_length_hacker(vec, sz); +#else + raw_vec.resize(sz); +#endif +} +#endif + +template +inline void resize(T &str, std::size_t sz) { + str.resize(sz); +} + } // namespace struct_pack::detail \ No newline at end of file diff --git a/src/struct_pack/examples/basic_usage.cpp b/src/struct_pack/examples/basic_usage.cpp index 7a6f31380..c2985219f 100644 --- a/src/struct_pack/examples/basic_usage.cpp +++ b/src/struct_pack/examples/basic_usage.cpp @@ -83,7 +83,10 @@ void basic_usage() { // api 5. serialize with offset { auto buffer = struct_pack::serialize_with_offset(/* offset = */ 2, p); - assert(buffer[0] == '\0' && buffer[1] == '\0'); + auto buffer2 = struct_pack::serialize(p); + bool result = std::string_view{buffer.data() + 2, buffer.size() - 2} == + std::string_view{buffer2.data(), buffer2.size()}; + assert(result); } // api 6. serialize varadic param {