userver: userver/storages/postgres/io/optional.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
optional.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/storages/postgres/io/optional.hpp
4/// @brief Optional values I/O support
5/// @ingroup userver_postgres_parse_and_format
6
7#include <optional>
8
9#include <userver/utils/assert.hpp>
10#include <userver/utils/optional_ref.hpp>
11
12#include <userver/storages/postgres/io/buffer_io.hpp>
13#include <userver/storages/postgres/io/buffer_io_base.hpp>
14#include <userver/storages/postgres/io/nullable_traits.hpp>
15#include <userver/storages/postgres/io/traits.hpp>
16
17#include <boost/optional/optional_fwd.hpp>
18
19USERVER_NAMESPACE_BEGIN
20
21namespace storages::postgres::io {
22
23namespace detail {
24
25template <template <typename> class Optional, typename T,
26 bool Categories = false>
27struct OptionalValueParser : BufferParserBase<Optional<T>> {
28 using BaseType = BufferParserBase<Optional<T>>;
29 using ValueParser = typename traits::IO<T>::ParserType;
30
31 using BaseType::BaseType;
32
33 void operator()(const FieldBuffer& buffer) {
34 T val;
35 ValueParser{val}(buffer);
36 this->value = std::move(val);
37 }
38};
39
40template <template <typename> class Optional, typename T>
41struct OptionalValueParser<Optional, T, true> : BufferParserBase<Optional<T>> {
42 using BaseType = BufferParserBase<Optional<T>>;
43 using ValueParser = typename traits::IO<T>::ParserType;
44
45 using BaseType::BaseType;
46
47 void operator()(const FieldBuffer& buffer,
48 const TypeBufferCategory& categories) {
49 T val;
50 ValueParser{val}(buffer, categories);
51 this->value = std::move(val);
52 }
53};
54
55template <template <typename> class Optional, typename T>
56struct OptionalValueFormatter : BufferFormatterBase<Optional<T>> {
57 using BaseType = BufferFormatterBase<Optional<T>>;
58 using ValueFormatter = typename traits::IO<T>::FormatterType;
59
60 using BaseType::BaseType;
61
62 template <typename Buffer>
63 void operator()(const UserTypes& types, Buffer& buffer) const {
64 if (this->value) {
65 ValueFormatter{*this->value}(types, buffer);
66 }
67 }
68};
69
70} // namespace detail
71
72/// Parser specialization for boost::optional
73template <typename T>
77 using BaseType =
80 using BaseType::BaseType;
81};
82
83/// Formatter specialization for boost::optional
84template <typename T>
89 using BaseType::BaseType;
90};
91
92/// Parser specialization for std::optional
93template <typename T>
97 using BaseType =
100 using BaseType::BaseType;
101};
102
103/// Formatter specialization for std::optional
104template <typename T>
109 using BaseType::BaseType;
110};
111
112/// Formatter specialization for utils::OptionalRef
113template <typename T>
114struct BufferFormatter<USERVER_NAMESPACE::utils::OptionalRef<T>,
116 : detail::OptionalValueFormatter<USERVER_NAMESPACE::utils::OptionalRef, T> {
117 using BaseType =
118 detail::OptionalValueFormatter<USERVER_NAMESPACE::utils::OptionalRef, T>;
119 using BaseType::BaseType;
120};
121
122/// Pg mapping specialization for boost::optional
123template <typename T>
125 : CppToPg<T> {};
126
127/// Pg mapping specialization for std::optional
128template <typename T>
130 : CppToPg<T> {};
131
132/// Pg mapping specialization for USERVER_NAMESPACE::utils::OptionalRef
133template <typename T>
134struct CppToPg<USERVER_NAMESPACE::utils::OptionalRef<T>,
136
137namespace traits {
138
139/// Nullability traits for boost::optional
140template <typename T>
141struct IsNullable<boost::optional<T>> : std::true_type {};
142
143template <typename T>
144struct GetSetNull<boost::optional<T>> {
145 using ValueType = boost::optional<T>;
146 inline static bool IsNull(const ValueType& v) { return !v; }
147 inline static void SetNull(ValueType& v) { v = ValueType{}; }
148 inline static void SetDefault(ValueType& v) { v.emplace(); }
149};
150
151template <typename T>
153template <typename T>
155
156template <typename T>
158 : ParserBufferCategory<typename traits::IO<T>::ParserType> {};
159
160/// Nullability traits for std::optional
161template <typename T>
162struct IsNullable<std::optional<T>> : std::true_type {};
163
164template <typename T>
165struct GetSetNull<std::optional<T>> {
166 using ValueType = std::optional<T>;
167 inline static bool IsNull(const ValueType& v) { return !v; }
168 inline static void SetNull(ValueType& v) { v = std::nullopt; }
169 inline static void SetDefault(ValueType& v) { v.emplace(); }
170};
171
172template <typename T>
174template <typename T>
176
177template <typename T>
179 : ParserBufferCategory<typename traits::IO<T>::ParserType> {};
180
181/// Nullability traits for USERVER_NAMESPACE::utils::OptionalRef
182template <typename T>
183struct IsNullable<USERVER_NAMESPACE::utils::OptionalRef<T>> : std::true_type {};
184
185template <typename T>
186struct GetSetNull<USERVER_NAMESPACE::utils::OptionalRef<T>> {
187 using ValueType = USERVER_NAMESPACE::utils::OptionalRef<T>;
188 inline static bool IsNull(const ValueType& v) { return !v; }
189 inline static void SetNull(ValueType&) {
190 static_assert(!sizeof(T), "SetNull not enabled for utils::OptionalRef");
191 }
192 inline static void SetDefault(ValueType&) {
193 static_assert(!sizeof(T), "SetDefault not enabled for utils::OptionalRef");
194 }
195};
196
197template <typename T>
198struct IsMappedToPg<USERVER_NAMESPACE::utils::OptionalRef<T>>
199 : IsMappedToPg<T> {};
200template <typename T>
201struct IsSpecialMapping<USERVER_NAMESPACE::utils::OptionalRef<T>>
202 : IsMappedToPg<T> {};
203
204} // namespace traits
205
206} // namespace storages::postgres::io
207
208USERVER_NAMESPACE_END