Skip to content

Commit

Permalink
denc: Add support for std::array
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 9, 2017
1 parent 929f7bd commit 6723d15
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 6 deletions.
85 changes: 79 additions & 6 deletions src/include/denc.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,24 @@
#ifndef _ENC_DEC_H
#define _ENC_DEC_H

#include <set>
#include <array>
#include <cstring>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <string.h>
#include <type_traits>
#include <boost/intrusive/set.hpp>
#include <vector>

#include <boost/container/flat_map.hpp>
#include <boost/container/flat_set.hpp>
#include <boost/intrusive/set.hpp>

#include "include/int_types.h"
#include "include/intarith.h"
#include "include/int_types.h"
#include "include/memory.h"
#include "byteorder.h"

#include "buffer.h"
#include "byteorder.h"

template<typename T, typename VVV=void>
struct denc_traits {
Expand Down Expand Up @@ -863,6 +866,76 @@ struct denc_traits<
A, B, Ts...>>,
A, B, Ts...> {};

template<typename T, size_t N>
struct denc_traits<
std::array<T, N>,
typename std::enable_if<denc_traits<T>::supported != 0>::type> {
private:
using container = std::array<T, N>;
public:
using traits = denc_traits<T>;

enum { supported = true };
enum { featured = traits::featured };
enum { bounded = traits::bounded };

template<typename U=T>
static typename std::enable_if<sizeof(U) &&
!traits::bounded &&
!traits::featured>::type
bound_encode(const container& s, size_t& p) {
for (const auto& e : s)
denc(e, p);
}
template<typename U=T>
static typename std::enable_if<sizeof(U) &&
traits::bounded &&
!traits::featured, void>::type
bound_encode(const container& s, size_t& p) {
size_t elem_size = 0;
denc(*(const T*)nullptr, elem_size);
p += elem_size * N;
}
template<typename U=T>
static typename std::enable_if<sizeof(U) &&
!traits::bounded &&
traits::featured, void>::type
bound_encode(const container& s, size_t& p, uint64_t f) {
for (const auto& e : s)
denc(e, p, f);
}
template<typename U=T>
static typename std::enable_if<sizeof(U) &&
traits::bounded &&
traits::featured>::type
bound_encode(const container& s, size_t& p, uint64_t f) {
size_t elem_size = 0;
denc(*(const T*)nullptr, elem_size, f);
p += sizeof(uint32_t) + elem_size * s.size();
}

template<typename U=T>
static typename std::enable_if<sizeof(U) &&
!traits::featured>::type
encode(const container& s, buffer::list::contiguous_appender& p) {
for (const auto& e : s)
denc(e, p);
}
template<typename U=T>
static typename std::enable_if<sizeof(U) &&
traits::featured>::type
encode(const container& s, buffer::list::contiguous_appender& p,
uint64_t f) {
for (const auto& e : s)
denc(e, p, f);
}
static void decode(container& s, buffer::ptr::iterator& p, uint64_t f = 0) {
for (auto& e : s)
denc(e, p, f);
}
};


// ----------------------------------------------------------------------
// class helpers

Expand Down
23 changes: 23 additions & 0 deletions src/include/encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,29 @@ inline void decode(std::deque<T,Alloc>& ls, bufferlist::iterator& p)
}
}

// std::array<T, N>
template<class T, size_t N, typename traits = denc_traits<T>>
inline typename std::enable_if<!traits::supported>::type
encode(const std::array<T, N>& v, bufferlist& bl, uint64_t features)
{
for (const auto& e : v)
encode(e, bl, features);
}
template<class T, size_t N, typename traits = denc_traits<T>>
inline typename std::enable_if<!traits::supported>::type
encode(const std::array<T, N>& v, bufferlist& bl)
{
for (const auto& e : v)
encode(e, bl);
}
template<class T, size_t N, typename traits = denc_traits<T>>
inline typename std::enable_if<!traits::supported>::type
decode(std::array<T, N>& v, bufferlist::iterator& p)
{
for (auto& e : v)
decode(e, p);
}


/*
* guards
Expand Down
20 changes: 20 additions & 0 deletions src/test/test_denc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,23 @@ TEST(denc, bufferptr_shallow_and_deep) {
ASSERT_EQ('f', op[0]);
}
}

TEST(denc, array)
{
{
cout << "std::array<std::string, 3>" << std::endl;
std::array<std::string, 3> s = { "foo", "bar", "baz" };
counts.reset();
test_denc(s);
}
{
cout << "std::array<uint32_t, 3>" << std::endl;
std::array<uint32_t, 3> s = { 1UL, 2UL, 3UL };
test_denc(s);
}
{
cout << "std::array<legacy_t, 3>" << std::endl;
std::array<legacy_t, 2> s = { legacy_t(1), legacy_t(2) };
test_encode_decode(s);
}
}

0 comments on commit 6723d15

Please sign in to comment.