7#include <boost/endian/conversion.hpp>
11#include <userver/storages/postgres/exceptions.hpp>
12#include <userver/storages/postgres/io/buffer_io_base.hpp>
13#include <userver/storages/postgres/io/traits.hpp>
14#include <userver/storages/postgres/io/type_mapping.hpp>
16USERVER_NAMESPACE_BEGIN
22template <std::size_t Size>
26struct IntegralType<2> {
27 using type = Smallint;
31struct IntegralType<4> {
36struct IntegralType<8> {
40template <std::size_t Size>
41struct IntegralBySizeParser {
42 using IntType =
typename IntegralType<Size>::type;
43 constexpr static std::size_t size = Size;
45 static IntType ParseBuffer(
const FieldBuffer& buf) {
47 std::memcpy(&i, buf.buffer, size);
48 return boost::endian::big_to_native(i);
53struct IntegralBinaryParser : BufferParserBase<T> {
54 using BaseType = BufferParserBase<T>;
55 using BaseType::BaseType;
60 this->value = IntegralBySizeParser<2>::ParseBuffer(buf);
63 this->value = IntegralBySizeParser<4>::ParseBuffer(buf);
66 this->value = IntegralBySizeParser<8>::ParseBuffer(buf);
69 throw InvalidInputBufferSize{buf.length,
"for an integral value type"};
75struct IntegralBinaryFormatter {
76 static constexpr std::size_t size =
sizeof(T);
77 using BySizeType =
typename IntegralType<size>::type;
81 explicit IntegralBinaryFormatter(T val) : value{val} {}
82 template <
typename Buffer>
83 void operator()(
const UserTypes&, Buffer& buf)
const {
84 buf.reserve(buf.size() + size);
85 auto tmp = boost::endian::native_to_big(
static_cast<BySizeType>(value));
86 const char* p =
reinterpret_cast<
char const*>(&tmp);
87 const char* e = p + size;
88 std::copy(p, e, std::back_inserter(buf));
92 template <
typename Iterator>
93 void operator()(Iterator buffer)
const {
94 auto tmp = boost::endian::native_to_big(
static_cast<BySizeType>(value));
95 const char* p =
reinterpret_cast<
char const*>(&tmp);
96 const char* e = p + size;
97 std::copy(p, e, buffer);
101#if defined(__x86_64__
) || defined(__aarch64__)
104 std::conditional_t<std::is_same_v<Bigint,
long>,
long long,
long>;
105static_assert(
sizeof(AltInteger) ==
sizeof(Bigint));
109 std::conditional_t<std::is_same_v<Integer,
int>,
long int,
int>;
110static_assert(
sizeof(AltInteger) ==
sizeof(Integer));
183 template <
typename Buffer>
193struct CppToSystemPg<Smallint> : PredefinedOid<PredefinedOids::kInt2> {};
195struct CppToSystemPg<Integer> : PredefinedOid<PredefinedOids::kInt4> {};
197struct CppToSystemPg<Bigint> : PredefinedOid<PredefinedOids::kInt8> {};
199struct CppToSystemPg<
bool> : PredefinedOid<PredefinedOids::kBoolean> {};