#define _ENC_DEC_H
#include <array>
+#include <bit>
#include <cstring>
+#include <concepts>
#include <map>
#include <optional>
#include <set>
#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"
// ---------------------------------------------------------------------
// 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;
}
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;
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) {
// 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;
};
} // 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;
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) {
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 {
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);
}
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;
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;
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);
}
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;
*(__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) {
}
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)
}
}
-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)
}
}
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);
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);
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));