2#ifndef CEL_RUNTIME_VALUE_HPP
3#define CEL_RUNTIME_VALUE_HPP
5#include <cel/runtime/value_type.hpp>
28 const value_type& element;
29 const std::byte* data;
34struct concrete_adapter;
59 std::unique_ptr<detail::owned_payload> _payload;
60 friend struct detail::value_access;
62 friend struct detail::concrete_adapter;
65 explicit value(std::unique_ptr<detail::owned_payload> payload);
71 void copy_leaf(
const value_type& expected,
void* destination)
const;
76 static value aggregate(
value_type type, std::span<const value> fields);
81 static value array_owned(
value_type element, std::span<value> children);
83 static const std::byte* raw_data(
const value& owner)
noexcept;
86 static detail::array_view array_data(
const std::byte* data)
noexcept;
92 void (*write)(
const void*,
const value_type&, std::byte*));
97 static void write_array(
const value_type& element,
98 std::byte* destination,
101 void (*write)(
const void*, std::size_t,
const value_type&, std::byte*));
105 static void destroy_fields(
const value_type&
type, std::byte* data, std::size_t count)
noexcept;
117 value(const value& other);
119 value(value&& other) noexcept;
125 value& operator=(const value& other);
128 value& operator=(value&& other) noexcept;
138 static value
from(const T& source) {
139 return detail::concrete_adapter<std::remove_cv_t<T>>
::from(source);
148 return detail::concrete_adapter<std::remove_cv_t<T>>
::as(*
this);
162 static value
tuple(std::span<const value> fields);
184 value
at(std::size_t index)
const;
191 void set(std::size_t index,
const value& replacement);
195 value
field(std::string_view name)
const;
201 void set_field(std::string_view name,
const value& replacement);
209struct concrete_adapter {
214 static value from(
const T& source) {
return value::from_leaf(type(), &source); }
217 static T as(
const value& source) {
218 std::array<std::byte,
sizeof(T)> bytes{};
219 source.copy_leaf(type(), bytes.data());
220 return std::bit_cast<T>(bytes);
225 static T read(
const value_type&,
const std::byte* data) {
226 assert(data !=
nullptr);
227 std::array<std::byte,
sizeof(T)> bytes{};
228 std::memcpy(bytes.data(), data, bytes.size());
229 return std::bit_cast<T>(bytes);
233 static void write(
const T& source,
const value_type&, std::byte* data) {
234 static_assert(std::is_trivially_copyable_v<T>);
235 std::memcpy(data, &source,
sizeof(T));
240template <
class T,
class Allocator>
241struct concrete_adapter<std::vector<T, Allocator>> {
243 static value_type type() {
249 static value from(
const std::vector<T, Allocator>& source) {
250 return value::from_concrete(
251 type(), &source, [](
const void*
object,
const value_type& shape, std::byte* data) {
252 write(*
static_cast<const std::vector<T, Allocator>*
>(
object), shape, data);
258 static void write(
const std::vector<T, Allocator>& source,
259 const value_type& shape,
261 value::write_array(shape.element(), data, source.size(), &source,
262 [](
const void*
object, std::size_t index,
const value_type& element,
265 *static_cast<const std::vector<T, Allocator>*>(object);
266 concrete_adapter<T>::write(input[index], element, target);
271 static std::vector<T, Allocator> as(
const value& source) {
272 if (!source.type().same_shape(type()))
throw std::invalid_argument(
"wrong vector type");
273 return read(source.type(), value::raw_data(source));
278 static std::vector<T, Allocator> read(
const value_type&,
const std::byte* data) {
279 std::vector<T, Allocator> result;
280 const auto children = value::array_data(data);
281 result.reserve(children.size);
283 for (std::size_t i = 0; i != children.size; ++i)
284 result.push_back(concrete_adapter<T>::read(
285 children.element, children.data ? children.data + i * children.stride :
nullptr));
292struct concrete_adapter<std::
tuple<T...>> {
295 static value_type type() {
296 static const auto descriptor = [] {
297 const std::array<value_type,
sizeof...(T)> fields{concrete_adapter<T>::type()...};
304 static value from(
const std::tuple<T...>& source) {
305 return value::from_concrete(
306 type(), &source, [](
const void*
object,
const value_type& shape, std::byte* data) {
307 write(*
static_cast<const std::tuple<T...
>*>(
object), shape, data);
312 template <std::size_t... I>
313 static void write_fields(
const std::tuple<T...>& source,
314 const value_type& shape,
316 std::index_sequence<I...>) {
317 std::size_t completed = 0;
319 ((concrete_adapter<T>::write(std::get<I>(source), shape.fields()[I],
320 data ? data + shape.offsets()[I] :
nullptr),
324 value::destroy_fields(shape, data, completed);
330 static void write(
const std::tuple<T...>& source,
const value_type& shape, std::byte* data) {
331 write_fields(source, shape, data, std::index_sequence_for<T...>{});
335 template <std::size_t... I>
336 static std::tuple<T...> extract(
const value_type& shape,
337 const std::byte* data,
338 std::index_sequence<I...>) {
339 return {concrete_adapter<T>::read(shape.fields()[I],
340 data ? data + shape.offsets()[I] :
nullptr)...};
344 static std::tuple<T...> as(
const value& source) {
345 if (!source.type().same_shape(type()))
throw std::invalid_argument(
"wrong tuple type");
346 return read(source.type(), value::raw_data(source));
351 static std::tuple<T...> read(
const value_type& shape,
const std::byte* data) {
352 return extract(shape, data, std::index_sequence_for<T...>{});
364 return detail::concrete_adapter<std::remove_cvref_t<T>>::type();
Shares an immutable, complete semantic type and canonical byte layout. Leaf identity is concrete C++ ...
Definition value_type.hpp:55
static value_type array(value_type element)
Creates an array descriptor retaining the element's complete shape and capabilities....
static value_type leaf()
Returns T's descriptor as an opaque, trivially copyable leaf. Rejects nontrivial T at compile time....
Definition value_type.hpp:93
static value_type tuple(std::span< const value_type > fields)
Creates a tuple descriptor with canonical source-order fields; empty fields describe unit....
std::size_t size() const
Returns array length, fixed aggregate arity, or range endpoint count. Throws std::invalid_argument fo...
T as() const
Returns a concrete copy of the exact requested leaf, vector, or tuple type. Returned vectors and tupl...
Definition value.hpp:147
static value array(value_type element, std::span< const value > elements)
Copies a sequence of elements with the specified complete shape and ownership operations....
void set(std::size_t index, const value &replacement)
Replaces one child with a copy of the exact expected shape and ownership operations....
value() noexcept
Creates source unit without allocating payload storage.
value field(std::string_view name) const
Copies a named record field; throws std::invalid_argument for non-record/missing name....
static value tuple(std::span< const value > fields)
Copies source-order fields into a canonical tuple; empty fields are source unit. Leaves input fields ...
const value_type & type() const
Borrows the complete descriptor until this value is assigned or destroyed. Example: value::from(true)...
static value range(value_type type, std::span< const value > endpoints)
Copies endpoints in source order for the given range descriptor. Throws std::invalid_argument for a n...
static value from(const T &source)
Copies a concrete leaf or recursively nested owning vector/tuple into a runtime value....
Definition value.hpp:138
static value record(value_type type, std::span< const value > fields)
Copies source-order fields into a record of the specified nominal type. Throws std::invalid_argument ...
value at(std::size_t index) const
Copies a source-order child under the class's aggregate and callable copy semantics....
void set_field(std::string_view name, const value &replacement)
Replaces a named record field with a copy of the exact expected shape. Throws std::invalid_argument f...
value_type native_type()
Returns the runtime's complete descriptor for a trusted native value type. Removes cv/reference quali...
Definition value.hpp:363
@ tuple
Stores ordered, canonically laid-out fields.
Definition value_type.hpp:34
Provides byte extents for stack reservation and type descriptors.
Definition callable.hpp:6