From c1b91c8f5f644b614277732b90d2059e2b29d52a Mon Sep 17 00:00:00 2001 From: "Adam C. Emerson" Date: Tue, 27 Dec 2016 21:26:25 -0500 Subject: [PATCH] denc: Support boost::optional Signed-off-by: Adam C. Emerson --- src/include/denc.h | 101 ++++++++++++++++++++++++++++++++++++++++ src/test/CMakeLists.txt | 1 + src/test/test_denc.cc | 38 +++++++++++++++ 3 files changed, 140 insertions(+) diff --git a/src/include/denc.h b/src/include/denc.h index 29adc2e2970f1d..01eddd7e48b2fd 100644 --- a/src/include/denc.h +++ b/src/include/denc.h @@ -35,6 +35,7 @@ #include #include #include +#include #include "include/intarith.h" #include "include/int_types.h" @@ -231,6 +232,7 @@ WRITE_INT_DENC(uint32_t, __le32); 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 @@ -1134,6 +1136,105 @@ struct denc_traits< } }; +// +// boost::optional +// +template +struct denc_traits< + boost::optional, + typename std::enable_if::supported != 0>::type> { + using traits = denc_traits; + + enum { supported = true }; + enum { featured = traits::featured }; + enum { bounded = false }; + + template + static typename std::enable_if::type + bound_encode(const boost::optional& v, size_t& p) { + denc(*(bool *)nullptr, p); + if (v) + denc(*v, p); + } + template + static typename std::enable_if::type + bound_encode(const boost::optional& v, size_t& p, uint64_t f) { + denc(*(bool *)nullptr, p); + if (v) + denc(*v, p); + } + + template + static typename std::enable_if::type + encode(const boost::optional& v, bufferlist::contiguous_appender& p) { + denc((bool)v, p); + if (v) + denc(*v, p); + } + template + static typename std::enable_if::type + encode(const boost::optional& v, bufferlist::contiguous_appender& p, + uint64_t f) { + denc((bool)v, p, f); + if (v) + denc(*v, p, f); + } + + static void decode(boost::optional& 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 + static typename std::enable_if::type + encode_nohead(const boost::optional& v, + bufferlist::contiguous_appender& p) { + if (v) + denc(*v, p); + } + template + static typename std::enable_if::type + encode_nohead(const boost::optional& v, + bufferlist::contiguous_appender& p, + uint64_t f) { + if (v) + denc(*v, p, f); + } + + static void decode_nohead(bool num, boost::optional& 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 { + 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 diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index a5719da30206ae..4e1ab2482c39f5 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -878,6 +878,7 @@ target_link_libraries(unittest_subprocess global) # unittest_pageset add_executable(unittest_pageset test_pageset.cc) add_ceph_unittest(unittest_pageset ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest_pageset) +target_link_libraries(unittest_pageset global) #make check ends here diff --git a/src/test/test_denc.cc b/src/test/test_denc.cc index 83edd9191023f4..152088146bf7bd 100644 --- a/src/test/test_denc.cc +++ b/src/test/test_denc.cc @@ -539,3 +539,41 @@ TEST(denc, tuple) test_denc(s); } } + +TEST(denc, optional) +{ + { + cout << "boost::optional" << std::endl; + boost::optional s = 97, t = boost::none; + counts.reset(); + test_denc(s); + test_denc(t); + } + { + cout << "boost::optional" << std::endl; + boost::optional 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 out = 5; + auto bpi = bl.front().begin(); + denc(out, bpi); + ASSERT_FALSE(!!out); + ASSERT_EQ(bpi.get_pos(), bl.c_str() + bl.length()); + } +}