10#include <userver/storages/postgres/exceptions.hpp>
11#include <userver/storages/postgres/io/buffer_io.hpp>
12#include <userver/storages/postgres/io/buffer_io_base.hpp>
13#include <userver/storages/postgres/io/type_mapping.hpp>
15#include <userver/utils/flags.hpp>
17USERVER_NAMESPACE_BEGIN
23template <
typename BitContainer>
26template <
typename Enum>
30template <std::size_t N>
33template <std::size_t N>
37inline constexpr bool kIsBitStringCompatible = IsBitStringCompatible<T>::value;
39template <
typename BitContainer,
typename Enable =
void>
40struct BitContainerTraits;
46 return bits & (1ull <<
i);
59 static_assert(
N > 0,
"Length for bit container must be at least 1");
71 static_assert(
N > 0,
"Length for bit container must be at least 1");
83enum class BitStringType { kBit, kBitVarying };
87enum class BitContainerInterface { kCommon, kFlags };
89template <
typename BitContainerRef, BitContainerInterface, BitStringType>
90struct BitStringRefWrapper {
91 static_assert(std::is_reference<BitContainerRef>::value,
92 "The container must be passed by reference");
94 using BitContainer = std::decay_t<BitContainerRef>;
95 static_assert(io::traits::kIsBitStringCompatible<BitContainer>,
96 "This C++ type cannot be used with PostgreSQL 'bit' and 'bit "
97 "varying' data type");
104template <
typename BitContainer, BitStringType>
106 static_assert(!std::is_reference<BitContainer>::value,
107 "The container must not be passed by reference");
109 static_assert(
io::
traits::kIsBitStringCompatible<BitContainer>,
110 "This C++ type cannot be used with PostgreSQL 'bit' and 'bit "
111 "varying' data type");
116template <BitStringType kBitStringType,
typename BitContainer>
117constexpr detail::BitStringRefWrapper<
118 const BitContainer&, detail::BitContainerInterface::kCommon, kBitStringType>
119BitString(
const BitContainer& bits) {
123template <BitStringType kBitStringType,
typename BitContainer>
124constexpr detail::BitStringRefWrapper<
125 BitContainer&, detail::BitContainerInterface::kCommon, kBitStringType>
126BitString(BitContainer& bits) {
130template <BitStringType kBitStringType,
typename Enum>
131constexpr detail::BitStringRefWrapper<
132 const USERVER_NAMESPACE::utils::Flags<Enum>&,
133 detail::BitContainerInterface::kFlags, kBitStringType>
134BitString(
const USERVER_NAMESPACE::utils::Flags<Enum>& bits) {
138template <BitStringType kBitStringType,
typename Enum>
139constexpr detail::BitStringRefWrapper<USERVER_NAMESPACE::utils::Flags<Enum>&,
140 detail::BitContainerInterface::kFlags,
142BitString(USERVER_NAMESPACE::utils::Flags<Enum>& bits) {
146template <
typename BitContainer>
147constexpr auto Varbit(BitContainer&& bits) {
148 return BitString<BitStringType::kBitVarying>(
149 std::forward<BitContainer>(bits));
152template <
typename BitContainer>
153constexpr auto Bit(BitContainer&& bits) {
154 return BitString<BitStringType::kBit>(std::forward<BitContainer>(bits));
256 template <
typename Buffer>
292 template <
typename Buffer>
307 template <
typename Buffer>
322 template <
typename Buffer>
328template <
typename BitContainer,
329 postgres::detail::BitContainerInterface kContainerInterface>
330struct CppToSystemPg<
postgres::detail::BitStringRefWrapper<
331 BitContainer, kContainerInterface,
postgres::BitStringType::kBitVarying>>
332 : PredefinedOid<PredefinedOids::kVarbit> {};
333template <
typename BitContainer>
335 BitContainer,
postgres::BitStringType::kBitVarying>>
336 : PredefinedOid<PredefinedOids::kVarbit> {};
338template <
typename BitContainer,
339 postgres::detail::BitContainerInterface kContainerInterface>
340struct CppToSystemPg<
postgres::detail::BitStringRefWrapper<
341 BitContainer, kContainerInterface,
postgres::BitStringType::kBit>>
342 : PredefinedOid<PredefinedOids::kBit> {};
343template <
typename BitContainer>
346 : PredefinedOid<PredefinedOids::kBit> {};
348template <std::size_t N>
349struct CppToSystemPg<std::bitset<N>> : PredefinedOid<PredefinedOids::kVarbit> {