mdbx++: добавление slice::as_pod<typename>().

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2023-10-06 12:06:22 +03:00
parent bc6d320bb2
commit c256e8358c
2 changed files with 151 additions and 0 deletions

View File

@ -394,6 +394,16 @@ using path = ::std::wstring;
using path = ::std::string;
#endif /* mdbx::path */
#if defined(__SIZEOF_INT128__) || \
(defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 128)
#ifndef MDBX_U128_TYPE
#define MDBX_U128_TYPE __uint128_t
#endif /* MDBX_U128_TYPE */
#ifndef MDBX_I128_TYPE
#define MDBX_I128_TYPE __int128_t
#endif /* MDBX_I128_TYPE */
#endif /* __SIZEOF_INT128__ || _INTEGRAL_MAX_BITS >= 128 */
#if __cplusplus >= 201103L || defined(DOXYGEN)
/// \brief Duration in 1/65536 units of second.
using duration = ::std::chrono::duration<unsigned, ::std::ratio<1, 65536>>;
@ -552,6 +562,7 @@ MDBX_DECLARE_EXCEPTION(transaction_overlapping);
[[noreturn]] LIBMDBX_API void throw_max_length_exceeded();
[[noreturn]] LIBMDBX_API void throw_out_range();
[[noreturn]] LIBMDBX_API void throw_allocators_mismatch();
[[noreturn]] LIBMDBX_API void throw_bad_value_size();
static MDBX_CXX14_CONSTEXPR size_t check_length(size_t bytes);
static MDBX_CXX14_CONSTEXPR size_t check_length(size_t headroom,
size_t payload);
@ -1029,6 +1040,35 @@ struct LIBMDBX_API_TYPE slice : public ::MDBX_val {
return slice(size_t(-1));
}
template <typename POD> MDBX_CXX14_CONSTEXPR POD as_pod() const {
static_assert(::std::is_standard_layout<POD>::value &&
!::std::is_pointer<POD>::value,
"Must be a standard layout type!");
if (MDBX_LIKELY(size() == sizeof(POD)))
MDBX_CXX20_LIKELY {
POD r;
memcpy(&r, data(), sizeof(r));
return r;
}
throw_bad_value_size();
}
#ifdef MDBX_U128_TYPE
MDBX_U128_TYPE as_uint128() const;
#endif /* MDBX_U128_TYPE */
uint64_t as_uint64() const;
uint32_t as_uint32() const;
uint16_t as_uint16() const;
uint8_t as_uint8() const;
#ifdef MDBX_I128_TYPE
MDBX_I128_TYPE as_int128() const;
#endif /* MDBX_I128_TYPE */
int64_t as_int64() const;
int32_t as_int32() const;
int16_t as_int16() const;
int8_t as_int8() const;
protected:
MDBX_CXX11_CONSTEXPR slice(size_t invalid_length) noexcept
: ::MDBX_val({nullptr, invalid_length}) {}
@ -2292,6 +2332,10 @@ public:
return buffer(::mdbx::slice::wrap(pod), make_reference, allocator);
}
template <typename POD> MDBX_CXX14_CONSTEXPR POD as_pod() const {
return slice_.as_pod<POD>();
}
/// \brief Reserves storage space.
void reserve(size_t wanna_headroom, size_t wanna_tailroom) {
wanna_headroom = ::std::min(::std::max(headroom(), wanna_headroom),

View File

@ -233,6 +233,10 @@ namespace mdbx {
"into an incompatible memory allocation scheme.");
}
[[noreturn]] __cold void throw_bad_value_size() {
throw bad_value_size(MDBX_BAD_VALSIZE);
}
__cold exception::exception(const ::mdbx::error &error) noexcept
: base(error.what()), error_(error) {}
@ -483,6 +487,109 @@ bool slice::is_printable(bool disable_utf8) const noexcept {
return true;
}
#ifdef MDBX_U128_TYPE
MDBX_U128_TYPE slice::as_uint128() const {
static_assert(sizeof(MDBX_U128_TYPE) == 16, "WTF?");
if (size() == 16) {
MDBX_U128_TYPE r;
memcpy(&r, data(), sizeof(r));
return r;
} else
return as_uint64();
}
#endif /* MDBX_U128_TYPE */
uint64_t slice::as_uint64() const {
static_assert(sizeof(uint64_t) == 8, "WTF?");
if (size() == 8) {
uint64_t r;
memcpy(&r, data(), sizeof(r));
return r;
} else
return as_uint32();
}
uint32_t slice::as_uint32() const {
static_assert(sizeof(uint32_t) == 4, "WTF?");
if (size() == 4) {
uint32_t r;
memcpy(&r, data(), sizeof(r));
return r;
} else
return as_uint16();
}
uint16_t slice::as_uint16() const {
static_assert(sizeof(uint16_t) == 2, "WTF?");
if (size() == 2) {
uint16_t r;
memcpy(&r, data(), sizeof(r));
return r;
} else
return as_uint8();
}
uint8_t slice::as_uint8() const {
static_assert(sizeof(uint8_t) == 1, "WTF?");
if (size() == 1)
return *static_cast<const uint8_t *>(data());
else if (size() == 0)
return 0;
else
MDBX_CXX20_UNLIKELY throw_bad_value_size();
}
#ifdef MDBX_I128_TYPE
MDBX_I128_TYPE slice::as_int128() const {
static_assert(sizeof(MDBX_I128_TYPE) == 16, "WTF?");
if (size() == 16) {
MDBX_I128_TYPE r;
memcpy(&r, data(), sizeof(r));
return r;
} else
return as_int64();
}
#endif /* MDBX_I128_TYPE */
int64_t slice::as_int64() const {
static_assert(sizeof(int64_t) == 8, "WTF?");
if (size() == 8) {
uint64_t r;
memcpy(&r, data(), sizeof(r));
return r;
} else
return as_int32();
}
int32_t slice::as_int32() const {
static_assert(sizeof(int32_t) == 4, "WTF?");
if (size() == 4) {
int32_t r;
memcpy(&r, data(), sizeof(r));
return r;
} else
return as_int16();
}
int16_t slice::as_int16() const {
static_assert(sizeof(int16_t) == 2, "WTF?");
if (size() == 2) {
int16_t r;
memcpy(&r, data(), sizeof(r));
return r;
} else
return as_int8();
}
int8_t slice::as_int8() const {
if (size() == 1)
return *static_cast<const int8_t *>(data());
else if (size() == 0)
return 0;
else
MDBX_CXX20_UNLIKELY throw_bad_value_size();
}
//------------------------------------------------------------------------------
char *to_hex::write_bytes(char *__restrict const dest, size_t dest_size) const {