30 std::string_view
name(
bool qualified =
false) {
31 if (!OidIsValid(oid)) {
32 throw std::runtime_error(
"invalid type");
34 return (qualified ? ffi_guarded(::format_type_be_qualified)
35 : ffi_guarded(::format_type_be))(oid);
38 bool operator==(
const type &other)
const {
return oid == other.oid; }
42 static bool is(
type &t) {
49 static bool is(
type &&t) {
return is(std::move(t)); }
51 static type type_for() =
delete;
54template <
typename T>
requires std::is_reference_v<T>
56 static constexpr type type_for() {
71 : value_datum(other.value_datum), ctx(other.ctx) {}
73 : value_datum(std::move(other.value_datum)), ctx(std::move(other.ctx)) {}
75 value_datum = std::move(other.value_datum);
76 ctx = std::move(other.ctx);
80 memory_context &get_memory_context() {
return ctx.get_memory_context(); }
82 datum get_datum()
const {
return value_datum; }
87 void *ptr(
bool tracked =
true)
const {
88 if (tracked && ctx.resets() > 0) {
91 return reinterpret_cast<void *
>(value_datum.operator const ::Datum &());
95static_assert(std::copy_constructible<non_by_value_type>);
98 using non_by_value_type::non_by_value_type;
100 operator void *() {
return VARDATA_ANY(detoasted_ptr()); }
102 datum get_datum()
const {
return value_datum; }
104 bool is_detoasted()
const {
return detoasted !=
nullptr; }
107 void *detoasted =
nullptr;
108 void *detoasted_ptr() {
109 if (detoasted !=
nullptr) {
112 detoasted = ffi_guarded(::pg_detoast_datum)(
reinterpret_cast<::
varlena *
>(ptr()));
118 using varlena::varlena;
120 operator std::string_view() {
121 return {
static_cast<char *
>(this->
operator void *()), VARSIZE_ANY_EXHDR(this->detoasted_ptr())};
125using byte_array = std::span<const std::byte>;
128 using varlena::varlena;
132 auto alloc = ctx.alloc<std::byte>(VARHDRSZ + ba.size_bytes());
133 SET_VARSIZE(alloc, VARHDRSZ + ba.size_bytes());
134 auto ptr = VARDATA_ANY(alloc);
135 std::copy(ba.begin(), ba.end(),
reinterpret_cast<std::byte *
>(ptr));
136 return datum(PointerGetDatum(alloc));
140 operator byte_array() {
141 return {
reinterpret_cast<std::byte *
>(this->
operator void *()),
142 VARSIZE_ANY_EXHDR(this->detoasted_ptr())};
148 { T::type() } -> std::same_as<type>;
149 { t.flat_size() } -> std::same_as<std::size_t>;
150 { t.flatten_into(span) };
151 { T::restore_from(span) } -> std::same_as<T>;
155 using flattenable_type = T;
156 using varlena::varlena;
161 auto *e =
new (ctx.alloc<expanded>()) expanded(T());
162 ctx.register_reset_callback(
164 auto v =
reinterpret_cast<expanded *
>(arg);
169 return std::make_pair(
datum(PointerGetDatum(e)), ctx);
171 detoasted_value(
reinterpret_cast<expanded *
>(DatumGetPointer(value_datum))) {}
174 if (detoasted_value.has_value()) {
175 return detoasted_value.value()->inner;
177 auto *ptr1 =
reinterpret_cast<std::byte *
>(varlena::operator
void *());
179 auto *value =
new (ctx.alloc<expanded>())
180 expanded(T::restore_from(std::span(ptr1, VARSIZE_ANY_EXHDR(detoasted_ptr()))));
181 ctx.register_reset_callback(
183 auto v =
reinterpret_cast<expanded *
>(arg);
187 init(&value->hdr, ctx);
188 detoasted_value = value;
193 datum get_expanded_datum()
const {
194 if (!detoasted_value.has_value()) {
195 throw std::runtime_error(
"hasn't been expanded yet");
197 return datum(EOHPGetRWDatum(&detoasted_value.value()->hdr));
202 expanded(T &&t) : inner(std::move(t)) {}
203 ::ExpandedObjectHeader hdr;
206 std::optional<expanded *> detoasted_value = std::nullopt;
208 static void init(ExpandedObjectHeader *hdr,
memory_context &ctx) {
209 using header = int32_t;
211 static const ::ExpandedObjectMethods eom = {
213 [](ExpandedObjectHeader *eohptr) {
214 auto *e =
reinterpret_cast<expanded *
>(eohptr);
215 T *inner = &e->inner;
216 return inner->flat_size() +
sizeof(header);
219 [](ExpandedObjectHeader *eohptr,
void *result,
size_t allocated_size) {
220 auto *e =
reinterpret_cast<expanded *
>(eohptr);
221 T *inner = &e->inner;
222 SET_VARSIZE(
reinterpret_cast<header *
>(result), allocated_size);
223 auto bytes =
reinterpret_cast<std::byte *
>(result) +
sizeof(header);
224 std::span buffer(bytes, allocated_size -
sizeof(header));
225 inner->flatten_into(buffer);
228 ffi_guarded(::EOH_init_header)(hdr, &eom, ctx);
237 { type_traits<T>::type_for() } -> std::same_as<type>;
Definition: memory.hpp:94
Definition: memory.hpp:61
Definition: memory.hpp:239
Definition: memory.hpp:107
Postgres type.
Definition: type.hpp:20
std::string_view name(bool qualified=false)
Type name as defined in Postgres.
Definition: type.hpp:30