]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
denc: Add support for std::array
authorAdam C. Emerson <aemerson@redhat.com>
Tue, 27 Dec 2016 17:55:18 +0000 (12:55 -0500)
committerAdam C. Emerson <aemerson@redhat.com>
Tue, 10 Jan 2017 16:40:34 +0000 (11:40 -0500)
Signed-off-by: Adam C. Emerson <aemerson@redhat.com>
src/include/denc.h
src/include/encoding.h
src/test/test_denc.cc

index 58b542a453a370b022c9ed2f704395b1e792502c..4ab51ddc4b52cf497afba53ae19ca8e1c8356d32 100644 (file)
 #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 {
@@ -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
 
index b8a358ef49a6ab92a3d2f9f87b4f674f01f8e120..9ea25d316d1bed82e2d40804dd181778c0084e98 100644 (file)
@@ -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
index 12a5489f6c2606c0db9cd96808c4d2dbc80c7fae..4c3fc5cd6a5f84938aff6cfcdd9bf9e0e6adb464 100644 (file)
@@ -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);
+  }
+}