From: Kefu Chai Date: Sat, 4 Jul 2020 10:10:55 +0000 (+0800) Subject: denc: add boost::container::small_vector support X-Git-Tag: v17.0.0~1774^2~1 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=ef10bee7c7326d704a9b02064d92916179705eb8;p=ceph.git denc: add boost::container::small_vector support i could use `_denc::container_base<>` and `_denc::pushback_details<>` to implement the traits for boost::container::small_vector (bcs for short), but the second template parameter of bcs is a value of type size_t, so the value it not a type, forunately, C++17 allows us to declare non-type template parameter using `auto`, but when instantiating _denc::container_base<>, the compiler complains that it expects a constatnt of `auto` but `T` is passed in. because i have to change the signature of `container_base` to something like ``` template class C, typename Details, auto ...Ts> struct container_base { ``` so, in this change, the traits for bsc is implemented from scratch. Signed-off-by: Kefu Chai --- diff --git a/src/include/denc.h b/src/include/denc.h index 24fe8b08d215c..a463f7647df55 100644 --- a/src/include/denc.h +++ b/src/include/denc.h @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -1085,6 +1086,106 @@ struct denc_traits< _denc::pushback_details>, T, Ts...> {}; +template +struct denc_traits< + boost::container::small_vector, + typename std::enable_if_t::supported>> { +private: + using container = boost::container::small_vector; +public: + using traits = denc_traits; + + static constexpr bool supported = true; + static constexpr bool featured = traits::featured; + static constexpr bool bounded = false; + static constexpr bool need_contiguous = traits::need_contiguous; + + template + static void bound_encode(const container& s, size_t& p, uint64_t f = 0) { + p += sizeof(uint32_t); + if constexpr (traits::bounded) { + if (!s.empty()) { + const auto elem_num = s.size(); + size_t elem_size = 0; + if constexpr (traits::featured) { + denc(*s.begin(), elem_size, f); + } else { + denc(*s.begin(), elem_size); + } + p += elem_size * elem_num; + } + } else { + for (const T& e : s) { + if constexpr (traits::featured) { + denc(e, p, f); + } else { + denc(e, p); + } + } + } + } + + template + static void encode(const container& s, + ceph::buffer::list::contiguous_appender& p, + uint64_t f = 0) { + denc((uint32_t)s.size(), p); + if constexpr (traits::featured) { + encode_nohead(s, p, f); + } else { + encode_nohead(s, p); + } + } + static void decode(container& s, ceph::buffer::ptr::const_iterator& p, + uint64_t f = 0) { + uint32_t num; + denc(num, p); + decode_nohead(num, s, p, f); + } + template + static std::enable_if_t + decode(container& s, ceph::buffer::list::const_iterator& p) { + uint32_t num; + denc(num, p); + decode_nohead(num, s, p); + } + + // nohead + static void encode_nohead(const container& s, ceph::buffer::list::contiguous_appender& p, + uint64_t f = 0) { + for (const T& e : s) { + if constexpr (traits::featured) { + denc(e, p, f); + } else { + denc(e, p); + } + } + } + static void decode_nohead(size_t num, container& s, + ceph::buffer::ptr::const_iterator& p, + uint64_t f=0) { + s.clear(); + s.reserve(num); + while (num--) { + T t; + denc(t, p, f); + s.push_back(std::move(t)); + } + } + template + static std::enable_if_t + decode_nohead(size_t num, container& s, + ceph::buffer::list::const_iterator& p) { + s.clear(); + s.reserve(num); + while (num--) { + T t; + denc(t, p); + s.push_back(std::move(t)); + } + } +}; + namespace _denc { template struct setlike_details : public container_details_base {