remove ceph code
[stor4nfv.git] / src / ceph / src / include / denc.h
diff --git a/src/ceph/src/include/denc.h b/src/ceph/src/include/denc.h
deleted file mode 100644 (file)
index 823da64..0000000
+++ /dev/null
@@ -1,1796 +0,0 @@
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2016 Allen Samuels <allen.samuels@sandisk.com>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation.  See file COPYING.
- *
- */
-
-// If you #include "include/encoding.h" you get the old-style *and*
-// the new-style definitions.  (The old-style needs denc_traits<> in
-// order to disable the container helpers when new-style traits are
-// present.)
-
-// You can also just #include "include/denc.h" and get only the
-// new-style helpers.  The eventual goal is to drop the legacy
-// definitions.
-
-#ifndef _ENC_DEC_H
-#define _ENC_DEC_H
-
-#include <array>
-#include <cstring>
-#include <map>
-#include <set>
-#include <string>
-#include <type_traits>
-#include <vector>
-
-#include <boost/container/flat_map.hpp>
-#include <boost/container/flat_set.hpp>
-#include <boost/intrusive/set.hpp>
-#include <boost/optional.hpp>
-
-#include "include/assert.h"    // boost clobbers this
-#include "include/intarith.h"
-#include "include/int_types.h"
-#include "include/memory.h"
-
-#include "buffer.h"
-#include "byteorder.h"
-
-template<typename T, typename=void>
-struct denc_traits {
-  static constexpr bool supported = false;
-  static constexpr bool featured = false;
-  static constexpr bool bounded = false;
-  static constexpr bool need_contiguous = true;
-};
-
-
-// hack for debug only; FIXME
-//#include <iostream>
-//using std::cout;
-
-// Define this to compile in a dump of all encoded objects to disk to
-// populate ceph-object-corpus.  Note that there is an almost
-// identical implementation in encoding.h, but you only need to define
-// ENCODE_DUMP_PATH here.
-//
-// See src/test/encoding/generate-corpus-objects.sh.
-//
-//#define ENCODE_DUMP_PATH /tmp/something
-
-#ifdef ENCODE_DUMP_PATH
-# include <stdio.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <fcntl.h>
-# define ENCODE_STR(x) #x
-# define ENCODE_STRINGIFY(x) ENCODE_STR(x)
-# define DENC_DUMP_PRE(Type)                   \
-  char *__denc_dump_pre = p.get_pos();
-  // this hackery with bits below is just to get a semi-reasonable
-  // distribution across time.  it is somewhat exponential but not
-  // quite.
-# define DENC_DUMP_POST(Type)                  \
-  do {                                                                 \
-    static int i = 0;                                                  \
-    i++;                                                               \
-    int bits = 0;                                                      \
-    for (unsigned t = i; t; bits++)                                    \
-      t &= t - 1;                                                      \
-    if (bits > 2)                                                      \
-      break;                                                           \
-    char fn[PATH_MAX];                                                 \
-    snprintf(fn, sizeof(fn),                                           \
-            ENCODE_STRINGIFY(ENCODE_DUMP_PATH) "/%s__%d.%x", #Type,            \
-            getpid(), i++);                                            \
-    int fd = ::open(fn, O_WRONLY|O_TRUNC|O_CREAT, 0644);               \
-    if (fd >= 0) {                                                     \
-      size_t len = p.get_pos() - __denc_dump_pre;                      \
-      int r = ::write(fd, __denc_dump_pre, len);                       \
-      (void)r;                                                         \
-      ::close(fd);                                                     \
-    }                                                                  \
-  } while (0)
-#else
-# define DENC_DUMP_PRE(Type)
-# define DENC_DUMP_POST(Type)
-#endif
-
-
-/*
-
-  top level level functions look like so
-  ======================================
-
-    inline void denc(const T& o, size_t& p, uint64_t features=0);
-    inline void denc(const T& o, buffer::list::contiguous_appender& p,
-                     uint64_t features=0);
-    inline void denc(T& o, buffer::ptr::iterator& p, uint64_t features=0);
-
-  or (for featured objects)
-
-    inline void denc(const T& o, size_t& p, uint64_t features);
-    inline void denc(const T& o, buffer::list::contiguous_appender& p,
-                     uint64_t features);
-    inline void denc(T& o, buffer::ptr::iterator& p, uint64_t features);
-
-  - These are symmetrical, so that they can be used from the magic DENC
-  method of writing the bound_encode/encode/decode methods all in one go;
-  they differ only in the type of p.
-
-  - These are automatically fabricated via a template that calls into
-  the denc_traits<> methods (see below), provided denc_traits<T>::supported
-  is defined and true.  They never need to be written explicitly.
-
-
-  static denc_traits<> definitions look like so
-  =============================================
-
-    template<>
-    struct denc_traits<T> {
-      static constexpr bool supported = true;
-      static constexpr bool bounded = false;
-      static constexpr bool featured = false;
-      static constexpr bool need_contiguous = true;
-      static void bound_encode(const T &o, size_t& p, uint64_t f=0);
-      static void encode(const T &o, buffer::list::contiguous_appender& p,
-                        uint64_t f=0);
-      static void decode(T& o, buffer::ptr::iterator &p, uint64_t f=0);
-    };
-
-  or (for featured objects)
-
-    template<>
-    struct denc_traits<T> {
-      static constexpr bool supported = true;
-      static constexpr bool bounded = false;
-      static constexpr bool featured = true;
-      static constexpr bool need_contiguous = true;
-      static void bound_encode(const T &o, size_t& p, uint64_t f);
-      static void encode(const T &o, buffer::list::contiguous_appender& p,
-                        uint64_t f);
-      static void decode(T& o, buffer::ptr::iterator &p, uint64_t f=0);
-    };
-
-  - denc_traits<T> is normally declared via the WRITE_CLASS_DENC(type) macro,
-  which is used in place of the old-style WRITE_CLASS_ENCODER(type) macro.
-  There are _FEATURED and _BOUNDED variants.  The class traits simply call
-  into class methods of the same name (see below).
-
-  - denc_traits<T> can also be written explicitly for some type to indicate
-  how it should be encoded.  This is the "source of truth" for how a type
-  is encoded.
-
-  - denc_traits<T> are declared for the base integer types, string, bufferptr,
-  and bufferlist base types.
-
-  - denc_traits<std::foo<T>>-like traits are declared for standard container
-  types.
-
-
-  class methods look like so
-  ==========================
-
-    void bound_encode(size_t& p) const;
-    void encode(buffer::list::contiguous_appender& p) const;
-    void decode(buffer::ptr::iterator &p);
-
-  or (for featured objects)
-
-    void bound_encode(size_t& p, uint64_t f) const;
-    void encode(buffer::list::contiguous_appender& p, uint64_t f) const;
-    void decode(buffer::ptr::iterator &p);
-
-  - These are normally invoked by the denc_traits<> methods that are
-  declared via WRITE_CLASS_DENC, although you can also invoke them explicitly
-  in your code.
-
-  - These methods are optimised for contiguous buffer, but denc() will try
-    rebuild a contigous one if the decoded bufferlist is segmented. If you are
-    concerned about the cost, you might want to define yet another method:
-
-    void decode(buffer::list::iterator &p);
-
-  - These can be defined either explicitly (as above), or can be "magically"
-  defined all in one go using the DENC macro and DENC_{START,FINISH} helpers
-  (which work like the legacy {ENCODE,DECODE}_{START,FINISH} macros):
-
-    class foo_t {
-      ...
-      DENC(foo_t, v, p) {
-        DENC_START(1, 1, p);
-        denc(v.foo, p);
-        denc(v.bar, p);
-        denc(v.baz, p);
-        DENC_FINISH(p);
-      }
-      ...
-    };
-    WRITE_CLASS_DENC(foo_t)
-
-  */
-
-
-// ---------------------------------------------------------------------
-// raw types
-namespace _denc {
-  template<class T, class...> struct is_any_of : std::false_type
-  {};
-  template<class T, class Head, class... Tail>
-  struct is_any_of<T, Head, Tail...> : std::conditional<
-    std::is_same<T, Head>::value,
-    std::true_type,
-    is_any_of<T, Tail...>>::type
-  {};
-}
-
-
-template<typename T>
-struct denc_traits<
-  T,
-  typename std::enable_if<
-    _denc::is_any_of<T, ceph_le64, ceph_le32, ceph_le16, uint8_t
-#ifndef _CHAR_IS_SIGNED
-                    , int8_t
-#endif
-                    >::value>::type> {
-  static constexpr bool supported = true;
-  static constexpr bool featured = false;
-  static constexpr bool bounded = true;
-  static constexpr bool need_contiguous = false;
-  static void bound_encode(const T &o, size_t& p, uint64_t f=0) {
-    p += sizeof(T);
-  }
-  static void encode(const T &o,
-                    buffer::list::contiguous_appender& p,
-                    uint64_t f=0) {
-    p.append((const char*)&o, sizeof(o));
-  }
-  static void decode(T& o, buffer::ptr::iterator &p,
-                    uint64_t f=0) {
-    o = *(T *)p.get_pos_add(sizeof(o));
-  }
-  static void decode(T& o, buffer::list::iterator &p) {
-    p.copy(sizeof(T), reinterpret_cast<char*>(&o));
-  }
-};
-
-
-// -----------------------------------------------------------------------
-// integer types
-
-// itype == internal type
-// otype == external type, i.e., the type on the wire
-
-// NOTE: the overload resolution ensures that the legacy encode/decode methods
-// defined for int types is prefered to the ones  defined using the specialized
-// template, and hence get selected. This machinary prevents these these from
-// getting glued into the legacy encode/decode methods; the overhead of setting
-// up a contiguous_appender etc is likely to be slower.
-namespace _denc {
-
-template<typename T, typename=void> struct ExtType {
-  using type = void;
-};
-
-template<typename T> struct ExtType<
-  T,
-  typename std::enable_if<std::is_same<T, int16_t>::value ||
-                         std::is_same<T, uint16_t>::value>::type> {
-  using type = __le16;
-};
-
-template<typename T> struct ExtType<
-  T,
-  typename std::enable_if<std::is_same<T, int32_t>::value ||
-                         std::is_same<T, uint32_t>::value>::type> {
-  using type = __le32;
-};
-
-template<typename T> struct ExtType<
-  T,
-  typename std::enable_if<std::is_same<T, int64_t>::value ||
-                         std::is_same<T, uint64_t>::value>::type> {
-  using type = __le64;
-};
-
-template<> struct ExtType<bool> {
-  using type = uint8_t;
-};
-} // namespace _denc
-
-template<typename T>
-struct denc_traits<
-  T,
-  typename std::enable_if<!std::is_void<typename _denc::ExtType<T>::type>::value>::type>
-{
-  static constexpr bool supported = true;
-  static constexpr bool featured = false;
-  static constexpr bool bounded = true;
-  static constexpr bool need_contiguous = false;
-  using etype = typename _denc::ExtType<T>::type;
-  static void bound_encode(const T &o, size_t& p, uint64_t f=0) {
-    p += sizeof(etype);
-  }
-  static void encode(const T &o, buffer::list::contiguous_appender& p,
-                    uint64_t f=0) {
-    *(etype *)p.get_pos_add(sizeof(etype)) = o;
-  }
-  static void decode(T& o, buffer::ptr::iterator &p,
-                    uint64_t f=0) {
-    o = *(etype*)p.get_pos_add(sizeof(etype));
-  }
-  static void decode(T& o, buffer::list::iterator &p) {
-    etype e;
-    p.copy(sizeof(etype), reinterpret_cast<char*>(&e));
-    o = e;
-  }
-};
-
-// varint
-//
-// high bit of each byte indicates another byte follows.
-template<typename T>
-inline void denc_varint(T v, size_t& p) {
-  p += sizeof(T) + 1;
-}
-
-template<typename T>
-inline void denc_varint(T v, bufferlist::contiguous_appender& p) {
-  uint8_t byte = v & 0x7f;
-  v >>= 7;
-  while (v) {
-    byte |= 0x80;
-    *(__u8*)p.get_pos_add(1) = byte;
-    byte = (v & 0x7f);
-    v >>= 7;
-  }
-  *(__u8*)p.get_pos_add(1) = byte;
-}
-
-template<typename T>
-inline void denc_varint(T& v, bufferptr::iterator& p) {
-  uint8_t byte = *(__u8*)p.get_pos_add(1);
-  v = byte & 0x7f;
-  int shift = 7;
-  while (byte & 0x80) {
-    byte = *(__u8*)p.get_pos_add(1);
-    v |= (T)(byte & 0x7f) << shift;
-    shift += 7;
-  }
-}
-
-
-// signed varint encoding
-//
-// low bit = 1 = negative, 0 = positive
-// high bit of every byte indicates whether another byte follows.
-inline void denc_signed_varint(int64_t v, size_t& p) {
-  p += sizeof(v) + 2;
-}
-inline void denc_signed_varint(int64_t v, bufferlist::contiguous_appender& p) {
-  if (v < 0) {
-    v = (-v << 1) | 1;
-  } else {
-    v <<= 1;
-  }
-  denc_varint(v, p);
-}
-
-template<typename T>
-inline void denc_signed_varint(T& v, bufferptr::iterator& p)
-{
-  int64_t i = 0;
-  denc_varint(i, p);
-  if (i & 1) {
-    v = -(i >> 1);
-  } else {
-    v = i >> 1;
-  }
-}
-
-// varint + lowz encoding
-//
-// first(low) 2 bits = how many low zero bits (nibbles)
-// high bit of each byte = another byte follows
-// (so, 5 bits data in first byte, 7 bits data thereafter)
-inline void denc_varint_lowz(uint64_t v, size_t& p) {
-  p += sizeof(v) + 2;
-}
-inline void denc_varint_lowz(uint64_t v, bufferlist::contiguous_appender& p) {
-  int lowznib = v ? (ctz(v) / 4) : 0;
-  if (lowznib > 3)
-    lowznib = 3;
-  v >>= lowznib * 4;
-  v <<= 2;
-  v |= lowznib;
-  denc_varint(v, p);
-}
-
-template<typename T>
-inline void denc_varint_lowz(T& v, bufferptr::iterator& p)
-{
-  uint64_t i = 0;
-  denc_varint(i, p);
-  int lowznib = (i & 3);
-  i >>= 2;
-  i <<= lowznib * 4;
-  v = i;
-}
-
-// signed varint + lowz encoding
-//
-// first low bit = 1 for negative, 0 for positive
-// next 2 bits = how many low zero bits (nibbles)
-// high bit of each byte = another byte follows
-// (so, 4 bits data in first byte, 7 bits data thereafter)
-inline void denc_signed_varint_lowz(int64_t v, size_t& p) {
-  p += sizeof(v) + 2;
-}
-inline void denc_signed_varint_lowz(int64_t v,
-                                   bufferlist::contiguous_appender& p) {
-  bool negative = false;
-  if (v < 0) {
-    v = -v;
-    negative = true;
-  }
-  unsigned lowznib = v ? (ctz(v) / 4) : 0u;
-  if (lowznib > 3)
-    lowznib = 3;
-  v >>= lowznib * 4;
-  v <<= 3;
-  v |= lowznib << 1;
-  v |= (int)negative;
-  denc_varint(v, p);
-}
-
-template<typename T>
-inline void denc_signed_varint_lowz(T& v, bufferptr::iterator& p)
-{
-  int64_t i = 0;
-  denc_varint(i, p);
-  int lowznib = (i & 6) >> 1;
-  if (i & 1) {
-    i >>= 3;
-    i <<= lowznib * 4;
-    v = -i;
-  } else {
-    i >>= 3;
-    i <<= lowznib * 4;
-    v = i;
-  }
-}
-
-
-// LBA
-//
-// first 1-3 bits = how many low zero bits
-//     *0 = 12 (common 4 K alignment case)
-//    *01 = 16
-//   *011 = 20
-//   *111 = byte
-// then 28-30 bits of data
-// then last bit = another byte follows
-// high bit of each subsequent byte = another byte follows
-inline void denc_lba(uint64_t v, size_t& p) {
-  p += sizeof(v) + 2;
-}
-
-inline void denc_lba(uint64_t v, bufferlist::contiguous_appender& p) {
-  int low_zero_nibbles = v ? (int)(ctz(v) / 4) : 0;
-  int pos;
-  uint32_t word;
-  int t = low_zero_nibbles - 3;
-  if (t < 0) {
-    pos = 3;
-    word = 0x7;
-  } else if (t < 3) {
-    v >>= (low_zero_nibbles * 4);
-    pos = t + 1;
-    word = (1 << t) - 1;
-  } else {
-    v >>= 20;
-    pos = 3;
-    word = 0x3;
-  }
-  word |= (v << pos) & 0x7fffffff;
-  v >>= 31 - pos;
-  if (!v) {
-    *(__le32*)p.get_pos_add(sizeof(uint32_t)) = word;
-    return;
-  }
-  word |= 0x80000000;
-  *(__le32*)p.get_pos_add(sizeof(uint32_t)) = word;
-  uint8_t byte = v & 0x7f;
-  v >>= 7;
-  while (v) {
-    byte |= 0x80;
-    *(__u8*)p.get_pos_add(1) = byte;
-    byte = (v & 0x7f);
-    v >>= 7;
-  }
-  *(__u8*)p.get_pos_add(1) = byte;
-}
-
-inline void denc_lba(uint64_t& v, bufferptr::iterator& p) {
-  uint32_t word = *(__le32*)p.get_pos_add(sizeof(uint32_t));
-  int shift;
-  switch (word & 7) {
-  case 0:
-  case 2:
-  case 4:
-  case 6:
-    v = (uint64_t)(word & 0x7ffffffe) << (12 - 1);
-    shift = 12 + 30;
-    break;
-  case 1:
-  case 5:
-    v = (uint64_t)(word & 0x7ffffffc) << (16 - 2);
-    shift = 16 + 29;
-    break;
-  case 3:
-    v = (uint64_t)(word & 0x7ffffff8) << (20 - 3);
-    shift = 20 + 28;
-    break;
-  case 7:
-    v = (uint64_t)(word & 0x7ffffff8) >> 3;
-    shift = 28;
-  }
-  uint8_t byte = word >> 24;
-  while (byte & 0x80) {
-    byte = *(__u8*)p.get_pos_add(1);
-    v |= (uint64_t)(byte & 0x7f) << shift;
-    shift += 7;
-  }
-}
-
-
-// ---------------------------------------------------------------------
-// denc top-level methods that call into denc_traits<T> methods
-
-template<typename T, typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              !traits::featured>::type denc(
-  const T& o,
-  size_t& p,
-  uint64_t f=0)
-{
-  traits::bound_encode(o, p);
-}
-template<typename T, typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              traits::featured>::type denc(
-  const T& o,
-  size_t& p,
-  uint64_t f)
-{
-  traits::bound_encode(o, p, f);
-}
-
-template<typename T, typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              !traits::featured>::type denc(
-  const T& o,
-  buffer::list::contiguous_appender& p,
-  uint64_t features=0)
-{
-  traits::encode(o, p);
-}
-template<typename T, typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              traits::featured>::type denc(
-  const T& o,
-  buffer::list::contiguous_appender& p,
-  uint64_t features)
-{
-  traits::encode(o, p, features);
-}
-
-template<typename T, typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              !traits::featured>::type denc(
-  T& o,
-  buffer::ptr::iterator& p,
-  uint64_t features=0)
-{
-  traits::decode(o, p);
-}
-template<typename T, typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              traits::featured>::type denc(
-  T& o,
-  buffer::ptr::iterator& p,
-  uint64_t features=0)
-{
-  traits::decode(o, p, features);
-}
-
-namespace _denc {
-  template<typename T, typename=void>
-  struct has_legacy_denc : std::false_type
-  {};
-  template<typename T>
-  struct has_legacy_denc<T,
-    decltype(std::declval<T&>()
-            .decode(std::declval<bufferlist::iterator&>()))> : std::true_type
-  {
-    static void decode(T& v, bufferlist::iterator& p) {
-      v.decode(p);
-    }
-  };
-  template<typename T>
-  struct has_legacy_denc<T,
-    typename std::enable_if<
-      !denc_traits<T>::need_contiguous>::type> : std::true_type
-  {
-    static void decode(T& v, bufferlist::iterator& p) {
-      denc_traits<T>::decode(v, p);
-    }
-  };
-}
-
-template<typename T,
-        typename traits=denc_traits<T>,
-        typename has_legacy_denc=_denc::has_legacy_denc<T>>
-inline typename std::enable_if<traits::supported &&
-                              has_legacy_denc::value>::type denc(
-  T& o,
-  buffer::list::iterator& p)
-{
-  has_legacy_denc::decode(o, p);
-}
-
-// ---------------------------------------------------------------------
-// base types and containers
-
-//
-// std::string
-//
-template<typename A>
-struct denc_traits<std::basic_string<char,std::char_traits<char>,A>> {
-private:
-  using value_type = std::basic_string<char,std::char_traits<char>,A>;
-
-public:
-  static constexpr bool supported = true;
-  static constexpr bool featured = false;
-  static constexpr bool bounded = false;
-  static constexpr bool need_contiguous = false;
-
-  static void bound_encode(const value_type& s, size_t& p, uint64_t f=0) {
-    p += sizeof(uint32_t) + s.size();
-  }
-  static void encode(const value_type& s,
-                    buffer::list::contiguous_appender& p,
-             uint64_t f=0) {
-    ::denc((uint32_t)s.size(), p);
-    memcpy(p.get_pos_add(s.size()), s.data(), s.size());
-  }
-  static void decode(value_type& s,
-                    buffer::ptr::iterator& p,
-                    uint64_t f=0) {
-    uint32_t len;
-    ::denc(len, p);
-    decode_nohead(len, s, p);
-  }
-  static void decode(value_type& s, buffer::list::iterator& p)
-  {
-    uint32_t len;
-    ::denc(len, p);
-    s.clear();
-    p.copy(len, s);
-  }
-  static void decode_nohead(size_t len, value_type& s,
-                           buffer::ptr::iterator& p) {
-    s.clear();
-    if (len) {
-      s.append(p.get_pos_add(len), len);
-    }
-  }
-  static void encode_nohead(const value_type& s,
-                           buffer::list::contiguous_appender& p) {
-    p.append(s.data(), s.length());
-  }
-};
-
-//
-// bufferptr
-//
-template<>
-struct denc_traits<bufferptr> {
-  static constexpr bool supported = true;
-  static constexpr bool featured = false;
-  static constexpr bool bounded = false;
-  static constexpr bool need_contiguous = false;
-  static void bound_encode(const bufferptr& v, size_t& p, uint64_t f=0) {
-    p += sizeof(uint32_t) + v.length();
-  }
-  static void encode(const bufferptr& v, buffer::list::contiguous_appender& p,
-             uint64_t f=0) {
-    ::denc((uint32_t)v.length(), p);
-    p.append(v);
-  }
-  static void decode(bufferptr& v, buffer::ptr::iterator& p, uint64_t f=0) {
-    uint32_t len;
-    ::denc(len, p);
-    v = p.get_ptr(len);
-  }
-  static void decode(bufferptr& v, buffer::list::iterator& p) {
-    uint32_t len;
-    ::denc(len, p);
-    bufferlist s;
-    p.copy(len, s);
-    if (len) {
-      if (s.get_num_buffers() == 1)
-       v = s.front();
-      else
-       v = buffer::copy(s.c_str(), s.length());
-    }
-  }
-};
-
-//
-// bufferlist
-//
-template<>
-struct denc_traits<bufferlist> {
-  static constexpr bool supported = true;
-  static constexpr bool featured = false;
-  static constexpr bool bounded = false;
-  static constexpr bool need_contiguous = false;
-  static void bound_encode(const bufferlist& v, size_t& p, uint64_t f=0) {
-    p += sizeof(uint32_t) + v.length();
-  }
-  static void encode(const bufferlist& v, buffer::list::contiguous_appender& p,
-             uint64_t f=0) {
-    ::denc((uint32_t)v.length(), p);
-    p.append(v);
-  }
-  static void decode(bufferlist& v, buffer::ptr::iterator& p, uint64_t f=0) {
-    uint32_t len;
-    ::denc(len, p);
-    v.clear();
-    v.push_back(p.get_ptr(len));
-  }
-  static void decode(bufferlist& v, buffer::list::iterator& p) {
-    uint32_t len;
-    ::denc(len, p);
-    v.clear();
-    p.copy(len, v);
-  }
-  static void encode_nohead(const bufferlist& v,
-                           buffer::list::contiguous_appender& p) {
-    p.append(v);
-  }
-  static void decode_nohead(size_t len, bufferlist& v,
-                           buffer::ptr::iterator& p) {
-    v.clear();
-    if (len) {
-      v.append(p.get_ptr(len));
-    }
-  }
-};
-
-//
-// std::pair<A, B>
-//
-template<typename A, typename B>
-struct denc_traits<
-  std::pair<A, B>,
-  typename std::enable_if<denc_traits<A>::supported &&
-                         denc_traits<B>::supported>::type> {
-  typedef denc_traits<A> a_traits;
-  typedef denc_traits<B> b_traits;
-
-  static constexpr bool supported = true;
-  static constexpr bool featured = a_traits::featured || b_traits::featured ;
-  static constexpr bool bounded = a_traits::bounded && b_traits::bounded;
-  static constexpr bool need_contiguous = (a_traits::need_contiguous ||
-                                          b_traits::need_contiguous);
-
-  template<typename AA=A>
-  static typename std::enable_if<sizeof(AA) &&
-                                !featured>::type
-  bound_encode(const std::pair<A,B>& v, size_t& p) {
-    denc(v.first, p);
-    denc(v.second, p);
-  }
-  template<typename AA=A>
-  static typename std::enable_if<sizeof(AA) &&
-                                featured, void>::type
-  bound_encode(const std::pair<A,B>& v, size_t& p, uint64_t f) {
-    denc(v.first, p, f);
-    denc(v.second, p, f);
-  }
-
-  template<typename AA=A>
-  static typename std::enable_if<sizeof(AA) &&
-                                !featured>::type
-  encode(const std::pair<A,B>& v, bufferlist::contiguous_appender& p) {
-    denc(v.first, p);
-    denc(v.second, p);
-  }
-  template<typename AA=A>
-  static typename std::enable_if<sizeof(AA) &&
-                                featured, void>::type
-  encode(const std::pair<A,B>& v, bufferlist::contiguous_appender& p,
-        uint64_t f) {
-    denc(v.first, p, f);
-    denc(v.second, p, f);
-  }
-
-  static void decode(std::pair<A,B>& v, buffer::ptr::iterator& p, uint64_t f=0) {
-    denc(v.first, p, f);
-    denc(v.second, p, f);
-  }
-  template<typename AA=A>
-  static typename std::enable_if<sizeof(AA) && !need_contiguous>::type
-    decode(std::pair<A,B>& v, buffer::list::iterator& p,
-           uint64_t f = 0) {
-    denc(v.first, p);
-    denc(v.second, p);
-  }
-};
-
-namespace _denc {
-  template<template<class...> class C, typename Details, typename ...Ts>
-  struct container_base {
-  private:
-    using container = C<Ts...>;
-    using T = typename Details::T;
-
-  public:
-    using traits = denc_traits<T>;
-
-    static constexpr bool supported = true;
-    static constexpr bool featured = traits::featured;
-    static constexpr bool bounded = false;
-    static constexpr bool need_contiguous = traits::need_contiguous;
-
-    template<typename U=T>
-    static typename std::enable_if<sizeof(U) &&
-                                  !traits::bounded &&
-                                  !traits::featured>::type
-    bound_encode(const container& s, size_t& p) {
-      p += sizeof(uint32_t);
-      for (const T& 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;
-      p += sizeof(uint32_t);
-      if (!s.empty()) {
-       // STL containers use weird element types like std::pair<const K, V>;
-       // cast to something we have denc_traits for.
-       denc(static_cast<const T&>(*s.begin()), elem_size);
-       p += sizeof(uint32_t) + elem_size * s.size();
-      }
-    }
-    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) {
-      p += sizeof(uint32_t);
-      for (const T& 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;
-      p += sizeof(uint32_t);
-      if (!s.empty()) {
-       // STL containers use weird element types like std::pair<const K, V>;
-       // cast to something we have denc_traits for.
-       denc(static_cast<const T&>(*s.begin()), elem_size, f);
-       p += 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) {
-      denc((uint32_t)s.size(), p);
-      encode_nohead(s, 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) {
-      denc((uint32_t)s.size(), p);
-      encode_nohead(s, p, f);
-    }
-    static void decode(container& s, buffer::ptr::iterator& p, uint64_t f = 0) {
-      uint32_t num;
-      denc(num, p);
-      decode_nohead(num, s, p, f);
-    }
-    template<typename U=T>
-    static typename std::enable_if<sizeof(U) && !need_contiguous>::type
-    decode(container& s, buffer::list::iterator& p) {
-      uint32_t num;
-      denc(num, p);
-      decode_nohead(num, s, p);
-    }
-
-    // nohead
-    template<typename U=T>
-    static typename std::enable_if<sizeof(U) &&
-                                  !traits::featured>::type
-    encode_nohead(const container& s, buffer::list::contiguous_appender& p) {
-      for (const T& e : s) {
-       denc(e, p);
-      }
-    }
-    template<typename U=T>
-    static typename std::enable_if<sizeof(U) &&
-                                  traits::featured>::type
-    encode_nohead(const container& s, buffer::list::contiguous_appender& p,
-                 uint64_t f) {
-      for (const T& e : s) {
-       denc(e, p, f);
-      }
-    }
-    static void decode_nohead(size_t num, container& s,
-                             buffer::ptr::iterator& p, uint64_t f=0) {
-      s.clear();
-      Details::reserve(s, num);
-      while (num--) {
-       T t;
-       denc(t, p, f);
-       Details::insert(s, std::move(t));
-      }
-    }
-    template<typename U=T>
-    static typename std::enable_if<sizeof(U) && !need_contiguous>::type
-    decode_nohead(size_t num, container& s,
-                 buffer::list::iterator& p) {
-      s.clear();
-      Details::reserve(s, num);
-      while (num--) {
-       T t;
-       denc(t, p);
-       Details::insert(s, std::move(t));
-      }
-    }
-  };
-
-  template<typename T>
-  class container_has_reserve {
-    template<typename U, U> struct SFINAE_match;
-    template<typename U>
-    static std::true_type test(SFINAE_match<T(*)(typename T::size_type),
-                              &U::reserve>*);
-
-    template<typename U>
-    static std::false_type test(...);
-
-  public:
-    static constexpr bool value = decltype(
-      test<denc_traits<T>>(0))::value;
-  };
-
-
-  template<typename Container,
-          bool Reserve = container_has_reserve<Container>::value>
-  struct reserve_switch;
-
-  template<typename Container>
-  struct reserve_switch<Container, true> {
-    static void reserve(Container& c, size_t s) {
-      c.reserve(s);
-    }
-  };
-
-  template<typename Container>
-  struct reserve_switch<Container, false> {
-    static void reserve(Container& c, size_t s) {}
-  };
-
-  template<typename Container>
-  struct container_details_base : public reserve_switch<Container> {
-    using T = typename Container::value_type;
-  };
-
-  template<typename Container>
-  struct pushback_details : public container_details_base<Container> {
-    template<typename ...Args>
-    static void insert(Container& c, Args&& ...args) {
-      c.emplace_back(std::forward<Args>(args)...);
-    }
-  };
-}
-
-template<typename T, typename ...Ts>
-struct denc_traits<
-  std::list<T, Ts...>,
-  typename std::enable_if<denc_traits<T>::supported>::type>
-  : public _denc::container_base<std::list,
-                                _denc::pushback_details<std::list<T, Ts...>>,
-                                T, Ts...> {};
-
-template<typename T, typename ...Ts>
-struct denc_traits<
-  std::vector<T, Ts...>,
-  typename std::enable_if<denc_traits<T>::supported>::type>
-  : public _denc::container_base<std::vector,
-                                _denc::pushback_details<std::vector<T, Ts...>>,
-                                T, Ts...> {};
-
-namespace _denc {
-  template<typename Container>
-  struct setlike_details : public container_details_base<Container> {
-    using T = typename Container::value_type;
-    template<typename ...Args>
-    static void insert(Container& c, Args&& ...args) {
-      c.emplace_hint(c.cend(), std::forward<Args>(args)...);
-    }
-  };
-}
-
-template<typename T, typename ...Ts>
-struct denc_traits<
-  std::set<T, Ts...>,
-  typename std::enable_if<denc_traits<T>::supported>::type>
-  : public _denc::container_base<std::set,
-                                _denc::setlike_details<std::set<T, Ts...>>,
-                                T, Ts...> {};
-
-template<typename T, typename ...Ts>
-struct denc_traits<
-  boost::container::flat_set<T, Ts...>,
-  typename std::enable_if<denc_traits<T>::supported>::type>
-  : public _denc::container_base<
-  boost::container::flat_set,
-  _denc::setlike_details<boost::container::flat_set<T, Ts...>>,
-  T, Ts...> {};
-
-namespace _denc {
-  template<typename Container>
-  struct maplike_details : public container_details_base<Container> {
-    using T = std::pair<typename Container::key_type,
-                       typename Container::mapped_type>;
-    template<typename ...Args>
-    static void insert(Container& c, Args&& ...args) {
-      c.emplace_hint(c.cend(), std::forward<Args>(args)...);
-    }
-  };
-}
-
-template<typename A, typename B, typename ...Ts>
-struct denc_traits<
-  std::map<A, B, Ts...>,
-  typename std::enable_if<denc_traits<A>::supported &&
-                         denc_traits<B>::supported>::type>
-  : public _denc::container_base<std::map,
-                                _denc::maplike_details<std::map<A, B, Ts...>>,
-                                A, B, Ts...> {};
-
-template<typename A, typename B, typename ...Ts>
-struct denc_traits<
-  boost::container::flat_map<A, B, Ts...>,
-  typename std::enable_if<denc_traits<A>::supported &&
-                         denc_traits<B>::supported>::type>
-  : public _denc::container_base<
-  boost::container::flat_map,
-  _denc::maplike_details<boost::container::flat_map<
-                          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>::type> {
-private:
-  using container = std::array<T, N>;
-public:
-  using traits = denc_traits<T>;
-
-  static constexpr bool supported = true;
-  static constexpr bool featured = traits::featured;
-  static constexpr bool bounded = traits::bounded;
-  static constexpr bool need_contiguous = traits::need_contiguous;
-
-  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(*s.begin(), 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;
-    p += sizeof(uint32_t);
-    if (!s.empty()) {
-      denc(*s.begin(), elem_size, f);
-      p += 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);
-  }
-  template<typename U=T>
-  static typename std::enable_if<sizeof(U) &&
-                                 !need_contiguous>::type
-  decode(container& s, buffer::list::iterator& p) {
-    for (auto& e : s) {
-      denc(e, p);
-    }
-  }
-};
-
-namespace _denc {
-  template<size_t... I>
-  struct indices {};
-
-  template<size_t ...S>
-  struct build_indices_helper;
-  template<size_t N, size_t ...Is>
-  struct build_indices_helper<N, N, Is...> {
-    using type = indices<Is...>;
-  };
-  template<size_t N, size_t I, size_t ...Is>
-  struct build_indices_helper<N, I, Is...> {
-    using type = typename build_indices_helper<N, I + 1, Is..., I>::type;
-  };
-
-  template<size_t I>
-  struct build_indices {
-    using type = typename build_indices_helper<I, 1, 0>::type;
-  };
-  template<>
-  struct build_indices<0> {
-    using type = indices<>;
-  };
-  template<>
-  struct build_indices<1> {
-    using type = indices<0>;
-  };
-
-  template<size_t I>
-  using build_indices_t = typename  build_indices<I>::type;
-
-  template<typename ...Ts>
-  struct tuple_traits;
-  template<typename T, typename ...Ts>
-  struct tuple_traits<T, Ts...> {
-    static constexpr bool supported = (denc_traits<T>::supported &&
-                                      tuple_traits<Ts...>::supported);
-    static constexpr bool bounded = (denc_traits<T>::bounded &&
-                                    tuple_traits<Ts...>::bounded);
-    static constexpr bool featured = (denc_traits<T>::featured ||
-                                   tuple_traits<Ts...>::featured);
-    static constexpr bool need_contiguous =
-      (denc_traits<T>::need_contiguous ||
-       tuple_traits<Ts...>::need_contiguous);
-  };
-  template<>
-  struct tuple_traits<> {
-    static constexpr bool supported = true;
-    static constexpr bool bounded = true;
-    static constexpr bool featured = false;
-    static constexpr bool need_contiguous = false;
-  };
-}
-
-template<typename ...Ts>
-struct denc_traits<
-  std::tuple<Ts...>,
-  typename std::enable_if<_denc::tuple_traits<Ts...>::supported>::type> {
-private:
-  static_assert(sizeof...(Ts) > 0,
-               "Zero-length tuples are not supported.");
-  using container = std::tuple<Ts...>;
-
-  template<typename T, size_t I, size_t J, size_t ...Is>
-  static void bound_encode_helper_nfnb(const T& s, size_t& p,
-                                      _denc::indices<I, J, Is...>) {
-    denc(std::get<I>(s), p);
-    bound_encode_helper_nfnb(s, p, _denc::indices<J, Is...>{});
-  }
-  template<typename T, size_t I>
-  static void bound_encode_helper_nfnb(const T& s, size_t& p,
-                                      _denc::indices<I>) {
-    denc(std::get<I>(s), p);
-  }
-
-  template<typename T, size_t I, size_t J, size_t ...Is>
-  static void bound_encode_helper_nfb(const T& s, size_t& p,
-                                     _denc::indices<I, J, Is...>) {
-    denc(std::get<I>(s), p);
-    bound_encode_helper_nfb(s, p, _denc::indices<J, Is...>{});
-  }
-  template<typename T, size_t I>
-  static void bound_encode_helper_nfb(const T& s, size_t& p,
-                                     _denc::indices<I>) {
-    denc(std::get<I>(s), p);
-  }
-
-  template<typename T, size_t I, size_t J, size_t ...Is>
-  static void bound_encode_helper_fnb(const T& s, size_t& p, uint64_t f,
-                                     _denc::indices<I, J, Is...>) {
-    denc(std::get<I>(s), p, f);
-    bound_encode_helper_fnb(s, p, f, _denc::indices<J, Is...>{});
-  }
-  template<typename T, size_t I>
-  static void bound_encode_helper_fnb(const T& s, size_t& p, uint64_t f,
-                                     _denc::indices<I>) {
-    denc(std::get<I>(s), p, f);
-  }
-
-  template<typename T, size_t I, size_t J, size_t ...Is>
-  static void bound_encode_helper_fb(const T& s, size_t& p, uint64_t f,
-                                    _denc::indices<I, J, Is...>) {
-    denc(std::get<I>(s), p);
-    bound_encode_helper_fb(s, p, f, _denc::indices<J, Is...>{});
-  }
-  template<typename T, size_t I>
-  static void bound_encode_helper_fb(const T& s, size_t& p, uint64_t f,
-                                    _denc::indices<I>) {
-    denc(std::get<I>(s), p);
-  }
-
-  template<typename T, size_t I, size_t J, size_t ...Is>
-  static void encode_helper_nf(const T& s, buffer::list::contiguous_appender& p,
-                              _denc::indices<I, J, Is...>) {
-    denc(std::get<I>(s), p);
-    encode_helper_nf(s, p, _denc::indices<J, Is...>{});
-  }
-  template<typename T, size_t I>
-  static void encode_helper_nf(const T& s, buffer::list::contiguous_appender& p,
-                       _denc::indices<I>) {
-    denc(std::get<I>(s), p);
-  }
-
-  template<typename T, size_t I, size_t J, size_t ...Is>
-  static void encode_helper_f(const T& s, buffer::list::contiguous_appender& p,
-                             uint64_t f, _denc::indices<I, J, Is...>) {
-    denc(std::get<I>(s), p, f);
-    encode_helper_nf(s, p, f, _denc::indices<J, Is...>{});
-  }
-  template<typename T, size_t I>
-  static void encode_helper_f(const T& s, buffer::list::contiguous_appender& p,
-                      uint64_t f, _denc::indices<I>) {
-    denc(std::get<I>(s), p, f);
-  }
-
-  template<typename T, size_t I, size_t J, size_t ...Is>
-  static void decode_helper(T& s, buffer::ptr::iterator& p,
-                           _denc::indices<I, J, Is...>) {
-    denc(std::get<I>(s), p);
-    decode_helper(s, p, _denc::indices<J, Is...>{});
-  }
-  template<typename T, size_t I>
-  static void decode_helper(T& s, buffer::ptr::iterator& p,
-                    _denc::indices<I>) {
-    denc(std::get<I>(s), p);
-  }
-  template<typename T, size_t I, size_t J, size_t ...Is>
-  static void decode_helper(T& s, buffer::list::iterator& p,
-                           _denc::indices<I, J, Is...>) {
-    denc(std::get<I>(s), p);
-    decode_helper(s, p, _denc::indices<J, Is...>{});
-  }
-  template<typename T, size_t I>
-  static void decode_helper(T& s, buffer::list::iterator& p,
-                           _denc::indices<I>) {
-    denc(std::get<I>(s), p);
-  }
-
-public:
-  using traits = _denc::tuple_traits<Ts...>;
-
-  static constexpr bool supported = true;
-  static constexpr bool featured = traits::featured;
-  static constexpr bool bounded = traits::bounded;
-  static constexpr bool need_contiguous = traits::need_contiguous;
-
-
-  template<typename U = traits>
-  static typename std::enable_if<U::supported &&
-                                !traits::bounded &&
-                                !traits::featured>::type
-  bound_encode(const container& s, size_t& p) {
-    bound_encode_helper_nfnb(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
-  }
-  template<typename U = traits>
-  static typename std::enable_if<U::supported &&
-                                traits::bounded &&
-                                !traits::featured, void>::type
-  bound_encode(const container& s, size_t& p) {
-    bound_encode_helper_nfb(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
-  }
-  template<typename U = traits>
-  static typename std::enable_if<U::traits &&
-                                !traits::bounded &&
-                                traits::featured, void>::type
-  bound_encode(const container& s, size_t& p, uint64_t f) {
-    bound_encode_helper_fnb(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
-  }
-  template<typename U = traits>
-  static typename std::enable_if<U::traits &&
-                                traits::bounded &&
-                                traits::featured>::type
-  bound_encode(const container& s, size_t& p, uint64_t f) {
-    bound_encode_helper_fb(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
-  }
-
-  template<typename U = traits>
-  static typename std::enable_if<U::supported &&
-                                !traits::featured>::type
-  encode(const container& s, buffer::list::contiguous_appender& p) {
-    encode_helper_nf(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
-  }
-  template<typename U = traits>
-  static typename std::enable_if<U::supported &&
-                                traits::featured>::type
-  encode(const container& s, buffer::list::contiguous_appender& p,
-        uint64_t f) {
-    encode_helper_f(s, p, f, _denc::build_indices_t<sizeof...(Ts)>{});
-  }
-
-  static void decode(container& s, buffer::ptr::iterator& p, uint64_t f = 0) {
-    decode_helper(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
-  }
-  template<typename U = traits>
-  static typename std::enable_if<U::supported &&
-                                 !need_contiguous>::type
-  decode(container& s, buffer::list::iterator& p, uint64_t f = 0) {
-    decode_helper(s, p, _denc::build_indices_t<sizeof...(Ts)>{});
-  }
-};
-
-//
-// boost::optional<T>
-//
-template<typename T>
-struct denc_traits<
-  boost::optional<T>,
-  typename std::enable_if<denc_traits<T>::supported>::type> {
-  using traits = denc_traits<T>;
-
-  static constexpr bool supported = true;
-  static constexpr bool featured = traits::featured;
-  static constexpr bool bounded = false;
-  static constexpr bool need_contiguous = traits::need_contiguous;
-
-  template<typename U = T>
-  static typename std::enable_if<sizeof(U) && !featured>::type
-  bound_encode(const boost::optional<T>& v, size_t& p) {
-    p += sizeof(bool);
-    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) {
-    p += sizeof(bool);
-    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) && !need_contiguous>::type
-  decode(boost::optional<T>& v, buffer::list::iterator& p) {
-    bool x;
-    denc(x, p);
-    if (x) {
-      v = T{};
-      denc(*v, p);
-    } 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> {
-  static constexpr bool supported = true;
-  static constexpr bool featured = false;
-  static constexpr bool bounded = true;
-  static constexpr bool need_contiguous = false;
-
-  static void bound_encode(const boost::none_t& v, size_t& p) {
-    p += sizeof(bool);
-  }
-
-  static void encode(const boost::none_t& v,
-                    bufferlist::contiguous_appender& p) {
-    denc(false, p);
-  }
-};
-
-// ----------------------------------------------------------------------
-// class helpers
-
-// Write denc_traits<> for a class that defines bound_encode/encode/decode
-// methods.
-
-#define WRITE_CLASS_DENC(T) _DECLARE_CLASS_DENC(T, false)
-#define WRITE_CLASS_DENC_BOUNDED(T) _DECLARE_CLASS_DENC(T, true)
-#define _DECLARE_CLASS_DENC(T, b)                                      \
-  template<> struct denc_traits<T> {                                   \
-    static constexpr bool supported = true;                            \
-    static constexpr bool featured = false;                            \
-    static constexpr bool bounded = b;                                 \
-    static constexpr bool need_contiguous = !_denc::has_legacy_denc<T>::value;\
-    static void bound_encode(const T& v, size_t& p, uint64_t f=0) {    \
-      v.bound_encode(p);                                               \
-    }                                                                  \
-    static void encode(const T& v, buffer::list::contiguous_appender& p, \
-                      uint64_t f=0) {                                  \
-      v.encode(p);                                                     \
-    }                                                                  \
-    static void decode(T& v, buffer::ptr::iterator& p, uint64_t f=0) { \
-      v.decode(p);                                                     \
-    }                                                                  \
-  };
-
-#define WRITE_CLASS_DENC_FEATURED(T) _DECLARE_CLASS_DENC_FEATURED(T, false)
-#define WRITE_CLASS_DENC_FEATURED_BOUNDED(T) _DECLARE_CLASS_DENC_FEATURED(T, true)
-#define _DECLARE_CLASS_DENC_FEATURED(T, b)                             \
-  template<> struct denc_traits<T> {                                   \
-    static constexpr bool supported = true;                            \
-    static constexpr bool featured = true;                             \
-    static constexpr bool bounded = b;                                 \
-    static constexpr bool need_contiguous = !_denc::has_legacy_denc<T>::value;\
-    static void bound_encode(const T& v, size_t& p, uint64_t f) {      \
-      v.bound_encode(p, f);                                            \
-    }                                                                  \
-    static void encode(const T& v, buffer::list::contiguous_appender& p, \
-                      uint64_t f) {                                    \
-      v.encode(p, f);                                                  \
-    }                                                                  \
-    static void decode(T& v, buffer::ptr::iterator& p, uint64_t f=0) { \
-      v.decode(p, f);                                                  \
-    }                                                                  \
-  };
-
-
-// ----------------------------------------------------------------------
-// encode/decode wrappers
-
-// These glue the new-style denc world into old-style calls to encode
-// and decode by calling into denc_traits<> methods (when present).
-
-template<typename T, typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              !traits::featured>::type encode(
-  const T& o,
-  bufferlist& bl,
-  uint64_t features_unused=0)
-{
-  size_t len = 0;
-  traits::bound_encode(o, len);
-  auto a = bl.get_contiguous_appender(len);
-  traits::encode(o, a);
-}
-
-template<typename T, typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              traits::featured>::type encode(
-  const T& o, bufferlist& bl,
-  uint64_t features)
-{
-  size_t len = 0;
-  traits::bound_encode(o, len, features);
-  auto a = bl.get_contiguous_appender(len);
-  traits::encode(o, a, features);
-}
-
-template<typename T,
-        typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              !traits::need_contiguous>::type decode(
-  T& o,
-  bufferlist::iterator& p)
-{
-  if (p.end())
-    throw buffer::end_of_buffer();
-  const auto& bl = p.get_bl();
-  const auto remaining = bl.length() - p.get_off();
-  // it is expensive to rebuild a contigous buffer and drop it, so avoid this.
-  if (p.get_current_ptr().get_raw() != bl.back().get_raw() &&
-      remaining > CEPH_PAGE_SIZE) {
-    traits::decode(o, p);
-  } else {
-    // ensure we get a contigous buffer... until the end of the
-    // bufferlist.  we don't really know how much we'll need here,
-    // unfortunately.  hopefully it is already contiguous and we're just
-    // bumping the raw ref and initializing the ptr tmp fields.
-    bufferptr tmp;
-    bufferlist::iterator t = p;
-    t.copy_shallow(remaining, tmp);
-    auto cp = tmp.begin();
-    traits::decode(o, cp);
-    p.advance((ssize_t)cp.get_offset());
-  }
-}
-
-template<typename T,
-        typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              traits::need_contiguous>::type decode(
-  T& o,
-  bufferlist::iterator& p)
-{
-  if (p.end())
-    throw buffer::end_of_buffer();
-  // ensure we get a contigous buffer... until the end of the
-  // bufferlist.  we don't really know how much we'll need here,
-  // unfortunately.  hopefully it is already contiguous and we're just
-  // bumping the raw ref and initializing the ptr tmp fields.
-  bufferptr tmp;
-  bufferlist::iterator t = p;
-  t.copy_shallow(p.get_bl().length() - p.get_off(), tmp);
-  auto cp = tmp.begin();
-  traits::decode(o, cp);
-  p.advance((ssize_t)cp.get_offset());
-}
-
-// nohead variants
-template<typename T, typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              !traits::featured>::type encode_nohead(
-  const T& o,
-  bufferlist& bl)
-{
-  size_t len = 0;
-  traits::bound_encode(o, len);
-  auto a = bl.get_contiguous_appender(len);
-  traits::encode_nohead(o, a);
-}
-
-template<typename T, typename traits=denc_traits<T>>
-inline typename std::enable_if<traits::supported &&
-                              !traits::featured>::type decode_nohead(
-  size_t num,
-  T& o,
-  bufferlist::iterator& p)
-{
-  if (!num)
-    return;
-  if (p.end())
-    throw buffer::end_of_buffer();
-  bufferptr tmp;
-  bufferlist::iterator t = p;
-  t.copy_shallow(p.get_bl().length() - p.get_off(), tmp);
-  auto cp = tmp.begin();
-  traits::decode_nohead(num, o, cp);
-  p.advance((ssize_t)cp.get_offset());
-}
-
-
-
-// ----------------------------------------------------------------
-// DENC
-
-// These are some class methods we need to do the version and length
-// wrappers for DENC_{START,FINISH} for inter-version
-// interoperability.
-
-#define DENC_HELPERS                                                   \
-  /* bound_encode */                                                   \
-  static void _denc_start(size_t& p,                                   \
-                         __u8 *struct_v,                               \
-                         __u8 *struct_compat,                          \
-                         char **, uint32_t *) {                        \
-    p += 2 + 4;                                                                \
-  }                                                                    \
-  static void _denc_finish(size_t& p,                                  \
-                          __u8 *struct_v,                              \
-                          __u8 *struct_compat,                         \
-                          char **, uint32_t *) { }                     \
-  /* encode */                                                         \
-  static void _denc_start(bufferlist::contiguous_appender& p,          \
-                         __u8 *struct_v,                               \
-                         __u8 *struct_compat,                          \
-                         char **len_pos,                               \
-                         uint32_t *start_oob_off) {                    \
-    denc(*struct_v, p);                                                        \
-    denc(*struct_compat, p);                                           \
-    *len_pos = p.get_pos_add(4);                                       \
-    *start_oob_off = p.get_out_of_band_offset();                       \
-  }                                                                    \
-  static void _denc_finish(bufferlist::contiguous_appender& p,         \
-                          __u8 *struct_v,                              \
-                          __u8 *struct_compat,                         \
-                          char **len_pos,                              \
-                          uint32_t *start_oob_off) {                   \
-    *(__le32*)*len_pos = p.get_pos() - *len_pos - sizeof(uint32_t) +   \
-      p.get_out_of_band_offset() - *start_oob_off;                     \
-  }                                                                    \
-  /* decode */                                                         \
-  static void _denc_start(buffer::ptr::iterator& p,                    \
-                         __u8 *struct_v,                               \
-                         __u8 *struct_compat,                          \
-                         char **start_pos,                             \
-                         uint32_t *struct_len) {                       \
-    denc(*struct_v, p);                                                        \
-    denc(*struct_compat, p);                                           \
-    denc(*struct_len, p);                                              \
-    *start_pos = const_cast<char*>(p.get_pos());                       \
-  }                                                                    \
-  static void _denc_finish(buffer::ptr::iterator& p,                   \
-                          __u8 *struct_v, __u8 *struct_compat,         \
-                          char **start_pos,                            \
-                          uint32_t *struct_len) {                      \
-    const char *pos = p.get_pos();                                     \
-    char *end = *start_pos + *struct_len;                              \
-    assert(pos <= end);                                                        \
-    if (pos < end) {                                                   \
-      p.advance(end - pos);                                            \
-    }                                                                  \
-  }
-
-// Helpers for versioning the encoding.  These correspond to the
-// {ENCODE,DECODE}_{START,FINISH} macros.
-
-#define DENC_START(v, compat, p)                                       \
-  __u8 struct_v = v;                                                   \
-  __u8 struct_compat = compat;                                         \
-  char *_denc_pchar;                                                   \
-  uint32_t _denc_u32;                                                  \
-  _denc_start(p, &struct_v, &struct_compat, &_denc_pchar, &_denc_u32); \
-  do {
-
-#define DENC_FINISH(p)                                                 \
-  } while (false);                                                     \
-  _denc_finish(p, &struct_v, &struct_compat, &_denc_pchar, &_denc_u32);
-
-
-// ----------------------------------------------------------------------
-
-// Helpers for writing a unified bound_encode/encode/decode
-// implementation that won't screw up buffer size estimations.
-
-#define DENC(Type, v, p)                                               \
-  DENC_HELPERS                                                         \
-  void bound_encode(size_t& p) const {                                 \
-    _denc_friend(*this, p);                                            \
-  }                                                                    \
-  void encode(bufferlist::contiguous_appender& p) const {              \
-    DENC_DUMP_PRE(Type);                                               \
-    _denc_friend(*this, p);                                            \
-    DENC_DUMP_POST(Type);                                              \
-  }                                                                    \
-  void decode(buffer::ptr::iterator& p) {                              \
-    _denc_friend(*this, p);                                            \
-  }                                                                    \
-  template<typename T, typename P>                                     \
-  friend typename std::enable_if<boost::is_same<T,Type>::value ||      \
-  boost::is_same<T,const Type>::value>::type                           \
-  _denc_friend(T& v, P& p)
-
-#define DENC_FEATURED(Type, v, p, f)                                   \
-  DENC_HELPERS                                                         \
-  void bound_encode(size_t& p, uint64_t f) const {                     \
-    _denc_friend(*this, p, f);                                         \
-  }                                                                    \
-  void encode(bufferlist::contiguous_appender& p, uint64_t f) const {  \
-    DENC_DUMP_PRE(Type);                                               \
-    _denc_friend(*this, p, f);                                         \
-    DENC_DUMP_POST(Type);                                              \
-  }                                                                    \
-  void decode(buffer::ptr::iterator& p, uint64_t f=0) {                        \
-    _denc_friend(*this, p, f);                                         \
-  }                                                                    \
-  template<typename T, typename P>                                     \
-  friend typename std::enable_if<boost::is_same<T,Type>::value ||      \
-  boost::is_same<T,const Type>::value>::type                           \
-  _denc_friend(T& v, P& p, uint64_t f)
-
-#endif