#include <string.h>
#include <type_traits>
#include <boost/intrusive/set.hpp>
+#include <boost/container/flat_map.hpp>
#include "include/int_types.h"
#include "include/intarith.h"
}
};
+// boost::container::flat_map
+template<typename A, typename B>
+struct denc_traits<
+ boost::container::flat_map<A, B>,
+ typename std::enable_if<denc_traits<A>::supported != 0 &&
+ denc_traits<B>::supported != 0>::type> {
+ typedef denc_traits<A> a_traits;
+ typedef denc_traits<B> b_traits;
+
+ enum { supported = true };
+ enum { featured = a_traits::featured || b_traits::featured };
+ enum { bounded = a_traits::bounded && b_traits::bounded };
+
+ template<typename AA=A>
+ static typename std::enable_if<sizeof(AA) &&
+ !bounded &&
+ !featured>::type
+ bound_encode(const boost::container::flat_map<A,B>& v, size_t& p) {
+ denc((uint32_t)v.size(), p);
+ for (const auto& i : v) {
+ denc(i.first, p);
+ denc(i.second, p);
+ }
+ }
+ template<typename AA=A>
+ static typename std::enable_if<sizeof(AA) &&
+ !bounded &&
+ featured, void>::type
+ bound_encode(const boost::container::flat_map<A,B>& v, size_t& p,
+ uint64_t f) {
+ denc((uint32_t)v.size(), p);
+ for (const auto& i : v) {
+ denc(i.first, p, f);
+ denc(i.second, p, f);
+ }
+ }
+ template<typename AA=A>
+ static typename std::enable_if<sizeof(AA) &&
+ bounded &&
+ !featured>::type
+ bound_encode(const boost::container::flat_map<A,B>& v, size_t& p) {
+ denc((uint32_t)v.size(), p);
+ size_t elem_size = 0;
+ denc(*(A*)nullptr, elem_size);
+ denc(*(B*)nullptr, elem_size);
+ p += v.size() * elem_size;
+ }
+ template<typename AA=A>
+ static typename std::enable_if<sizeof(AA) &&
+ bounded &&
+ featured, void>::type
+ bound_encode(const boost::container::flat_map<A,B>& v, size_t& p,
+ uint64_t f) {
+ denc((uint32_t)v.size(), p);
+ size_t elem_size = 0;
+ denc(*(A*)nullptr, elem_size, f);
+ denc(*(B*)nullptr, elem_size, f);
+ p += v.size() * elem_size;
+ }
+
+ template<typename AA=A>
+ static typename std::enable_if<sizeof(AA) &&
+ !featured>::type
+ encode(const boost::container::flat_map<A,B>& v,
+ bufferlist::contiguous_appender& p) {
+ denc((uint32_t)v.size(), p);
+ for (const auto& i : v) {
+ denc(i.first, p);
+ denc(i.second, p);
+ }
+ }
+ template<typename AA=A>
+ static typename std::enable_if<sizeof(AA) &&
+ featured, void>::type
+ encode(const boost::container::flat_map<A,B>& v,
+ bufferlist::contiguous_appender& p,
+ uint64_t f) {
+ denc((uint32_t)v.size(), p);
+ for (const auto& i : v) {
+ denc(i.first, p, f);
+ denc(i.second, p, f);
+ }
+ }
+
+ static void decode(boost::container::flat_map<A,B>& v,
+ buffer::ptr::iterator& p) {
+ v.clear();
+ uint32_t num;
+ denc(num, p);
+ A key;
+ while (num--) {
+ denc(key, p);
+ denc(v[key], p);
+ }
+ }
+
+ // nohead variants
+ template<typename AA=A>
+ static typename std::enable_if<sizeof(AA) &&
+ !featured>::type
+ encode_nohead(const boost::container::flat_map<A,B>& v,
+ bufferlist::contiguous_appender& p) {
+ for (const auto& i : v) {
+ denc(i.first, p);
+ denc(i.second, p);
+ }
+ }
+ template<typename AA=A>
+ static typename std::enable_if<sizeof(AA) &&
+ featured, void>::type
+ encode_nohead(const boost::container::flat_map<A,B>& v,
+ bufferlist::contiguous_appender& p,
+ uint64_t f) {
+ for (const auto& i : v) {
+ denc(i.first, p, f);
+ denc(i.second, p, f);
+ }
+ }
+ static void decode_nohead(size_t num, boost::container::flat_map<A,B>& v,
+ buffer::ptr::iterator& p) {
+ v.clear();
+ A key;
+ while (num--) {
+ denc(key, p);
+ denc(v[key], p);
+ }
+ }
+};
// ----------------------------------------------------------------------
// class helpers
}
}
+// boost::container::flat-map
+template<class T, class U, class Comp, class Alloc,
+ typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+ inline typename std::enable_if<!t_traits::supported ||
+ !u_traits::supported>::type
+ encode(const boost::container::flat_map<T,U,Comp,Alloc>& m, bufferlist& bl)
+{
+ __u32 n = (__u32)(m.size());
+ encode(n, bl);
+ for (typename boost::container::flat_map<T,U,Comp>::const_iterator p
+ = m.begin(); p != m.end(); ++p) {
+ encode(p->first, bl);
+ encode(p->second, bl);
+ }
+}
+template<class T, class U, class Comp, class Alloc,
+ typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+ inline typename std::enable_if<!t_traits::supported ||
+ !u_traits::supported>::type
+ encode(const boost::container::flat_map<T,U,Comp,Alloc>& m, bufferlist& bl,
+ uint64_t features)
+{
+ __u32 n = (__u32)(m.size());
+ encode(n, bl);
+ for (typename boost::container::flat_map<T,U,Comp>::const_iterator p
+ = m.begin(); p != m.end(); ++p) {
+ encode(p->first, bl, features);
+ encode(p->second, bl, features);
+ }
+}
+template<class T, class U, class Comp, class Alloc,
+ typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+ inline typename std::enable_if<!t_traits::supported ||
+ !u_traits::supported>::type
+ decode(boost::container::flat_map<T,U,Comp,Alloc>& m, bufferlist::iterator& p)
+{
+ __u32 n;
+ decode(n, p);
+ m.clear();
+ while (n--) {
+ T k;
+ decode(k, p);
+ decode(m[k], p);
+ }
+}
+template<class T, class U, class Comp, class Alloc>
+inline void decode_noclear(boost::container::flat_map<T,U,Comp,Alloc>& m,
+ bufferlist::iterator& p)
+{
+ __u32 n;
+ decode(n, p);
+ while (n--) {
+ T k;
+ decode(k, p);
+ decode(m[k], p);
+ }
+}
+template<class T, class U, class Comp, class Alloc,
+ typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+ inline typename std::enable_if<!t_traits::supported ||
+ !u_traits::supported>::type
+ encode_nohead(const boost::container::flat_map<T,U,Comp,Alloc>& m,
+ bufferlist& bl)
+{
+ for (typename boost::container::flat_map<T,U,Comp>::const_iterator p
+ = m.begin(); p != m.end(); ++p) {
+ encode(p->first, bl);
+ encode(p->second, bl);
+ }
+}
+template<class T, class U, class Comp, class Alloc,
+ typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+ inline typename std::enable_if<!t_traits::supported ||
+ !u_traits::supported>::type
+ encode_nohead(const boost::container::flat_map<T,U,Comp,Alloc>& m,
+ bufferlist& bl, uint64_t features)
+{
+ for (typename boost::container::flat_map<T,U,Comp>::const_iterator p
+ = m.begin(); p != m.end(); ++p) {
+ encode(p->first, bl, features);
+ encode(p->second, bl, features);
+ }
+}
+template<class T, class U, class Comp, class Alloc,
+ typename t_traits=denc_traits<T>, typename u_traits=denc_traits<U>>
+inline typename std::enable_if<!t_traits::supported ||
+ !u_traits::supported>::type
+ decode_nohead(int n, boost::container::flat_map<T,U,Comp,Alloc>& m,
+ bufferlist::iterator& p)
+{
+ m.clear();
+ while (n--) {
+ T k;
+ decode(k, p);
+ decode(m[k], p);
+ }
+}
+
// multimap
template<class T, class U, class Comp, class Alloc>
inline void encode(const std::multimap<T,U,Comp,Alloc>& m, bufferlist& bl)