Skip to content

Commit

Permalink
denc: Support boost::optional
Browse files Browse the repository at this point in the history
Signed-off-by: Adam C. Emerson <aemerson@redhat.com>
  • Loading branch information
adamemerson committed Jan 10, 2017
1 parent cf044f7 commit ea52d39
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 0 deletions.
101 changes: 101 additions & 0 deletions src/include/denc.h
Expand Up @@ -35,6 +35,7 @@
#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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1134,6 +1136,105 @@ struct denc_traits<
}
};

//
// 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

Expand Down
1 change: 1 addition & 0 deletions src/test/CMakeLists.txt
Expand Up @@ -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

38 changes: 38 additions & 0 deletions src/test/test_denc.cc
Expand Up @@ -540,3 +540,41 @@ TEST(denc, tuple)
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());
}
}

0 comments on commit ea52d39

Please sign in to comment.