#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
#include <boost/intrusive/set.hpp>
+#include <boost/optional.hpp>
#include "include/intarith.h"
#include "include/int_types.h"
WRITE_INT_DENC(int32_t, __le32);
WRITE_INT_DENC(uint64_t, __le64);
WRITE_INT_DENC(int64_t, __le64);
+WRITE_INT_DENC(bool, uint8_t);
// varint
}
};
+//
+// boost::optional<T>
+//
+template<typename T>
+struct denc_traits<
+ boost::optional<T>,
+ typename std::enable_if<denc_traits<T>::supported != 0>::type> {
+ using traits = denc_traits<T>;
+
+ enum { supported = true };
+ enum { featured = traits::featured };
+ enum { bounded = false };
+
+ template<typename U = T>
+ static typename std::enable_if<sizeof(U) && !featured>::type
+ bound_encode(const boost::optional<T>& v, size_t& p) {
+ denc(*(bool *)nullptr, p);
+ if (v)
+ denc(*v, p);
+ }
+ template<typename U = T>
+ static typename std::enable_if<sizeof(U) && featured>::type
+ bound_encode(const boost::optional<T>& v, size_t& p, uint64_t f) {
+ denc(*(bool *)nullptr, p);
+ if (v)
+ denc(*v, p);
+ }
+
+ template<typename U = T>
+ static typename std::enable_if<sizeof(U) && !featured>::type
+ encode(const boost::optional<T>& v, bufferlist::contiguous_appender& p) {
+ denc((bool)v, p);
+ if (v)
+ denc(*v, p);
+ }
+ template<typename U = T>
+ static typename std::enable_if<sizeof(U) && featured>::type
+ encode(const boost::optional<T>& v, bufferlist::contiguous_appender& p,
+ uint64_t f) {
+ denc((bool)v, p, f);
+ if (v)
+ denc(*v, p, f);
+ }
+
+ static void decode(boost::optional<T>& v, buffer::ptr::iterator& p,
+ uint64_t f = 0) {
+ bool x;
+ denc(x, p, f);
+ if (x) {
+ v = T{};
+ denc(*v, p, f);
+ } else {
+ v = boost::none;
+ }
+ }
+
+ template<typename U = T>
+ static typename std::enable_if<sizeof(U) && !featured>::type
+ encode_nohead(const boost::optional<T>& v,
+ bufferlist::contiguous_appender& p) {
+ if (v)
+ denc(*v, p);
+ }
+ template<typename U = T>
+ static typename std::enable_if<sizeof(U) && featured>::type
+ encode_nohead(const boost::optional<T>& v,
+ bufferlist::contiguous_appender& p,
+ uint64_t f) {
+ if (v)
+ denc(*v, p, f);
+ }
+
+ static void decode_nohead(bool num, boost::optional<T>& v,
+ buffer::ptr::iterator& p, uint64_t f = 0) {
+ if (num) {
+ v = T();
+ denc(*v, p, f);
+ } else {
+ v = boost::none;
+ }
+ }
+};
+
+template<>
+struct denc_traits<boost::none_t> {
+ enum { supported = true };
+ enum { featured = false };
+ enum { bounded = true };
+
+ static void bound_encode(const boost::none_t& v, size_t& p) {
+ denc(*(bool *)nullptr, p);
+ }
+
+ static void encode(const boost::none_t& v,
+ bufferlist::contiguous_appender& p) {
+ denc(false, p);
+ }
+};
+
// ----------------------------------------------------------------------
// class helpers
test_denc(s);
}
}
+
+TEST(denc, optional)
+{
+ {
+ cout << "boost::optional<uint64_t>" << std::endl;
+ boost::optional<uint64_t> s = 97, t = boost::none;
+ counts.reset();
+ test_denc(s);
+ test_denc(t);
+ }
+ {
+ cout << "boost::optional<std::string>" << std::endl;
+ boost::optional<std::string> s = std::string("Meow"), t = boost::none;
+ counts.reset();
+ test_denc(s);
+ test_denc(t);
+ }
+ {
+ size_t s = 0;
+ denc(boost::none, s);
+ ASSERT_NE(s, 0u);
+
+ // encode
+ bufferlist bl;
+ {
+ auto a = bl.get_contiguous_appender(s);
+ denc(boost::none, a);
+ }
+ ASSERT_LE(bl.length(), s);
+
+ bl.rebuild();
+ boost::optional<uint32_t> out = 5;
+ auto bpi = bl.front().begin();
+ denc(out, bpi);
+ ASSERT_FALSE(!!out);
+ ASSERT_EQ(bpi.get_pos(), bl.c_str() + bl.length());
+ }
+}