]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/include/denc.h
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / include / denc.h
index 71db1003ace89ad93cd7b07b51f61919a17469e2..d075dd518318567667358024c302b44dd77c384b 100644 (file)
@@ -25,7 +25,9 @@
 #define _ENC_DEC_H
 
 #include <array>
+#include <bit>
 #include <cstring>
+#include <concepts>
 #include <map>
 #include <optional>
 #include <set>
@@ -39,8 +41,8 @@
 #include <boost/intrusive/set.hpp>
 #include <boost/optional.hpp>
 
+#include "include/cpp_lib_backport.h"
 #include "include/compat.h"
-#include "include/intarith.h"
 #include "include/int_types.h"
 #include "include/scope_guard.h"
 
@@ -268,8 +270,8 @@ template<typename T> int DencDumper<T>::i = 0;
 // ---------------------------------------------------------------------
 // raw types
 namespace _denc {
-template<typename T, typename... Us>
-inline constexpr bool is_any_of = (... || std::is_same_v<T, Us>);
+template<typename T, typename... U>
+concept is_any_of = (std::same_as<T, U> || ...);
 
 template<typename T, typename=void> struct underlying_type {
   using type = T;
@@ -283,42 +285,29 @@ using underlying_type_t = typename underlying_type<T>::type;
 }
 
 template<class It>
-struct is_const_iterator
-  : std::conditional_t<std::is_const_v<std::remove_pointer_t<typename It::pointer>>,
-                      std::true_type,
-                      std::false_type>
-{};
-template<>
-struct is_const_iterator<size_t> : std::false_type {};
-template<>
-struct is_const_iterator<ceph::buffer::list::contiguous_appender> : std::false_type {
-  // appender is used for *changing* the buffer
+concept is_const_iterator = requires(It& it, size_t n) {
+  { it.get_pos_add(n) } -> std::same_as<const char*>;
 };
-template<class It>
-inline constexpr bool is_const_iterator_v = is_const_iterator<It>::value;
 
-template<typename T, class It>
-std::enable_if_t<is_const_iterator_v<It>, const T&>
-get_pos_add(It& i) {
+template<typename T, is_const_iterator It>
+const T& get_pos_add(It& i) {
   return *reinterpret_cast<const T*>(i.get_pos_add(sizeof(T)));
 }
 
 template<typename T, class It>
-std::enable_if_t<!is_const_iterator_v<It>, T&>
-get_pos_add(It& i) {
+requires (!is_const_iterator<It>)
+T& get_pos_add(It& i) {
   return *reinterpret_cast<T*>(i.get_pos_add(sizeof(T)));
 }
 
 template<typename T>
-struct denc_traits<
-  T,
-  std::enable_if_t<
-    _denc::is_any_of<_denc::underlying_type_t<T>,
-                    ceph_le64, ceph_le32, ceph_le16, uint8_t
+requires _denc::is_any_of<_denc::underlying_type_t<T>,
+                         ceph_le64, ceph_le32, ceph_le16, uint8_t
 #ifndef _CHAR_IS_SIGNED
-                      , int8_t
+                         , int8_t
 #endif
-                    >>> {
+                         >
+struct denc_traits<T> {
   static constexpr bool supported = true;
   static constexpr bool featured = false;
   static constexpr bool bounded = true;
@@ -327,13 +316,12 @@ struct denc_traits<
     p += sizeof(T);
   }
   template<class It>
-  static std::enable_if_t<!is_const_iterator_v<It>>
-  encode(const T &o, It& p, uint64_t f=0) {
+  requires (!is_const_iterator<It>)
+  static void encode(const T &o, It& p, uint64_t f=0) {
     get_pos_add<T>(p) = o;
   }
-  template<class It>
-  static std::enable_if_t<is_const_iterator_v<It>>
-  decode(T& o, It& p, uint64_t f=0) {
+  template<is_const_iterator It>
+  static void decode(T& o, It& p, uint64_t f=0) {
     o = get_pos_add<T>(p);
   }
   static void decode(T& o, ceph::buffer::list::const_iterator &p) {
@@ -355,25 +343,28 @@ struct denc_traits<
 // up a contiguous_appender etc is likely to be slower.
 namespace _denc {
 
-template<typename T, typename=void> struct ExtType {
+template<typename T> struct ExtType {
   using type = void;
 };
 
 template<typename T>
-struct ExtType<T, std::enable_if_t<std::is_same_v<T, int16_t> ||
-                                  std::is_same_v<T, uint16_t>>> {
+requires _denc::is_any_of<T,
+                         int16_t, uint16_t>
+struct ExtType<T> {
   using type = ceph_le16;
 };
 
 template<typename T>
-struct ExtType<T, std::enable_if_t<std::is_same_v<T, int32_t> ||
-                                  std::is_same_v<T, uint32_t>>> {
+requires _denc::is_any_of<T,
+                         int32_t, uint32_t>
+struct ExtType<T> {
   using type = ceph_le32;
 };
 
 template<typename T>
-struct ExtType<T, std::enable_if_t<std::is_same_v<T, int64_t> ||
-                                  std::is_same_v<T, uint64_t>>> {
+requires _denc::is_any_of<T,
+                         int64_t, uint64_t>
+struct ExtType<T> {
   using type = ceph_le64;
 };
 
@@ -386,7 +377,8 @@ using ExtType_t = typename ExtType<T>::type;
 } // namespace _denc
 
 template<typename T>
-struct denc_traits<T, std::enable_if_t<!std::is_void_v<_denc::ExtType_t<T>>>>
+requires (!std::is_void_v<_denc::ExtType_t<T>>)
+struct denc_traits<T>
 {
   static constexpr bool supported = true;
   static constexpr bool featured = false;
@@ -397,13 +389,12 @@ struct denc_traits<T, std::enable_if_t<!std::is_void_v<_denc::ExtType_t<T>>>>
     p += sizeof(etype);
   }
   template<class It>
-  static std::enable_if_t<!is_const_iterator_v<It>>
-  encode(const T &o, It& p, uint64_t f=0) {
+  requires (!is_const_iterator<It>)
+  static void encode(const T &o, It& p, uint64_t f=0) {
     get_pos_add<etype>(p) = o;
   }
-  template<class It>
-  static std::enable_if_t<is_const_iterator_v<It>>
-  decode(T& o, It &p, uint64_t f=0) {
+  template<is_const_iterator It>
+  static void decode(T& o, It &p, uint64_t f=0) {
     o = get_pos_add<etype>(p);
   }
   static void decode(T& o, ceph::buffer::list::const_iterator &p) {
@@ -455,8 +446,8 @@ inline void denc_signed_varint(int64_t v, size_t& p) {
   p += sizeof(v) + 2;
 }
 template<class It>
-inline std::enable_if_t<!is_const_iterator_v<It>>
-denc_signed_varint(int64_t v, It& p) {
+requires (!is_const_iterator<It>)
+void denc_signed_varint(int64_t v, It& p) {
   if (v < 0) {
     v = (-v << 1) | 1;
   } else {
@@ -465,9 +456,8 @@ denc_signed_varint(int64_t v, It& p) {
   denc_varint(v, p);
 }
 
-template<typename T, class It>
-inline std::enable_if_t<is_const_iterator_v<It>>
-denc_signed_varint(T& v, It& p)
+template<typename T, is_const_iterator It>
+inline void denc_signed_varint(T& v, It& p)
 {
   int64_t i = 0;
   denc_varint(i, p);
@@ -488,7 +478,7 @@ inline void denc_varint_lowz(uint64_t v, size_t& p) {
 }
 inline void denc_varint_lowz(uint64_t v,
                             ceph::buffer::list::contiguous_appender& p) {
-  int lowznib = v ? (ctz(v) / 4) : 0;
+  int lowznib = v ? (std::countr_zero(v) / 4) : 0;
   if (lowznib > 3)
     lowznib = 3;
   v >>= lowznib * 4;
@@ -518,14 +508,14 @@ inline void denc_signed_varint_lowz(int64_t v, size_t& p) {
   p += sizeof(v) + 2;
 }
 template<class It>
-inline std::enable_if_t<!is_const_iterator_v<It>>
-denc_signed_varint_lowz(int64_t v, It& p) {
+requires (!is_const_iterator<It>)
+inline void denc_signed_varint_lowz(int64_t v, It& p) {
   bool negative = false;
   if (v < 0) {
     v = -v;
     negative = true;
   }
-  unsigned lowznib = v ? (ctz(v) / 4) : 0u;
+  unsigned lowznib = v ? (std::countr_zero(std::bit_cast<uint64_t>(v)) / 4) : 0u;
   if (lowznib > 3)
     lowznib = 3;
   v >>= lowznib * 4;
@@ -535,9 +525,8 @@ denc_signed_varint_lowz(int64_t v, It& p) {
   denc_varint(v, p);
 }
 
-template<typename T, class It>
-inline std::enable_if_t<is_const_iterator_v<It>>
-denc_signed_varint_lowz(T& v, It& p)
+template<typename T, is_const_iterator It>
+inline void denc_signed_varint_lowz(T& v, It& p)
 {
   int64_t i = 0;
   denc_varint(i, p);
@@ -569,9 +558,9 @@ inline void denc_lba(uint64_t v, size_t& p) {
 }
 
 template<class It>
-inline std::enable_if_t<!is_const_iterator_v<It>>
-denc_lba(uint64_t v, It& p) {
-  int low_zero_nibbles = v ? (int)(ctz(v) / 4) : 0;
+requires (!is_const_iterator<It>)
+inline void denc_lba(uint64_t v, It& p) {
+  int low_zero_nibbles = v ? std::countr_zero(v) / 4 : 0;
   int pos;
   uint32_t word;
   int t = low_zero_nibbles - 3;
@@ -606,9 +595,8 @@ denc_lba(uint64_t v, It& p) {
   *(__u8*)p.get_pos_add(1) = byte;
 }
 
-template<class It>
-inline std::enable_if_t<is_const_iterator_v<It>>
-denc_lba(uint64_t& v, It& p) {
+template<is_const_iterator It>
+inline void denc_lba(uint64_t& v, It& p) {
   uint32_t word = *(ceph_le32*)p.get_pos_add(sizeof(uint32_t));
   int shift = 0;
   switch (word & 7) {
@@ -658,7 +646,8 @@ inline std::enable_if_t<traits::supported> denc(
 }
 
 template<typename T, class It, typename traits=denc_traits<T>>
-inline std::enable_if_t<traits::supported && !is_const_iterator_v<It>>
+requires traits::supported && (!is_const_iterator<It>)
+inline void
 denc(const T& o,
      It& p,
      uint64_t features=0)
@@ -670,8 +659,9 @@ denc(const T& o,
   }
 }
 
-template<typename T, class It, typename traits=denc_traits<T>>
-inline std::enable_if_t<traits::supported && is_const_iterator_v<It>>
+template<typename T, is_const_iterator It, typename traits=denc_traits<T>>
+requires traits::supported
+inline void
 denc(T& o,
      It& p,
      uint64_t features=0)
@@ -779,7 +769,8 @@ public:
     }
   }
   template<class It>
-  static std::enable_if_t<!is_const_iterator_v<It>>
+  requires (!is_const_iterator<It>)
+  static void
   encode_nohead(const value_type& s, It& p) {
     auto len = s.length();
     maybe_inline_memcpy(p.get_pos_add(len), s.data(), len, 16);
@@ -799,13 +790,14 @@ struct denc_traits<ceph::buffer::ptr> {
     p += sizeof(uint32_t) + v.length();
   }
   template <class It>
-  static std::enable_if_t<!is_const_iterator_v<It>>
+  requires (!is_const_iterator<It>)
+  static void
   encode(const ceph::buffer::ptr& v, It& p, uint64_t f=0) {
     denc((uint32_t)v.length(), p);
     p.append(v);
   }
-  template <class It>
-  static std::enable_if_t<is_const_iterator_v<It>>
+  template <is_const_iterator It>
+  static void
   decode(ceph::buffer::ptr& v, It& p, uint64_t f=0) {
     uint32_t len;
     denc(len, p);
@@ -843,7 +835,7 @@ struct denc_traits<ceph::buffer::list> {
     p.append(v);
   }
   static void decode(ceph::buffer::list& v, ceph::buffer::ptr::const_iterator& p, uint64_t f=0) {
-    uint32_t len;
+    uint32_t len = 0;
     denc(len, p);
     v.clear();
     v.push_back(p.get_ptr(len));