Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion include/rfl/avro/Writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,13 +348,21 @@ class RFL_API Writer {
}

} else if constexpr (std::is_same_v<Type, float>) {
int result = avro_value_set_float(_val, static_cast<float>(_var));
int result = avro_value_set_float(_val, _var);
if (result != 0) {
throw std::runtime_error(
"Error setting float value: " + std::to_string(result) + ": " +
avro_strerror());
}

} else if constexpr (std::is_same_v<Type, double>) {
int result = avro_value_set_double(_val, _var);
if (result != 0) {
throw std::runtime_error(
"Error setting double value: " + std::to_string(result) + ": " +
avro_strerror());
}

} else if constexpr (std::is_floating_point_v<Type>) {
int result = avro_value_set_double(_val, static_cast<double>(_var));
if (result != 0) {
Expand Down
43 changes: 15 additions & 28 deletions include/rfl/boost_serialization/Reader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,46 +48,30 @@ struct Reader {
static constexpr bool has_custom_constructor = false;

/// Checks if the given Boost archive value is empty.
/// Always returns false for Boost.Serialization as it doesn't have a null concept.
/// Always returns false for Boost.Serialization as it doesn't have a null
/// concept.
/// @param _var The archive variable (unused)
/// @return Always false
bool is_empty(const InputVarType& /*_var*/) const noexcept { return false; }

/// Converts a value from the Boost archive to a basic C++ type.
/// Supports strings, booleans, floating-point numbers, integers, and literal types.
/// Supports strings, booleans, floating-point numbers, integers, and literal
/// types.
/// @tparam T The target C++ type to convert to
/// @param _var The archive variable containing the value
/// @return A Result containing the converted value or an error
template <class T>
rfl::Result<T> to_basic_type(const InputVarType& _var) const noexcept {
try {
if constexpr (std::is_same<std::remove_cvref_t<T>, std::string>()) {
std::string val;
*_var.ar >> val;
return val;
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
bool val = false;
*_var.ar >> val;
return val;
} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
double val = 0.0;
*_var.ar >> val;
return static_cast<T>(val);
} else if constexpr (std::is_unsigned<std::remove_cvref_t<T>>()) {
std::uint64_t val = 0;
*_var.ar >> val;
return static_cast<T>(val);
} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
std::int64_t val = 0;
*_var.ar >> val;
return static_cast<T>(val);
} else if constexpr (internal::is_literal_v<T>) {
if constexpr (internal::is_literal_v<T>) {
std::int64_t val = 0;
*_var.ar >> val;
return T::from_value(
static_cast<typename std::remove_cvref_t<T>::ValueType>(val));
} else {
static_assert(rfl::always_false_v<T>, "Unsupported type.");
T val;
*_var.ar >> val;
return val;
}
} catch (std::exception& e) {
return error(e.what());
Expand Down Expand Up @@ -147,7 +131,8 @@ struct Reader {
}

/// Reads all elements from an array using the provided array reader.
/// @tparam ArrayReader The type of reader that processes individual array elements
/// @tparam ArrayReader The type of reader that processes individual array
/// elements
/// @param _array_reader The reader object that processes each element
/// @param _arr The array structure containing size information
/// @return std::nullopt on success, or an Error if reading fails
Expand Down Expand Up @@ -188,7 +173,8 @@ struct Reader {

/// Reads all fields from an object using the provided object reader.
/// Fields are accessed by their index.
/// @tparam ObjectReader The type of reader that processes individual object fields
/// @tparam ObjectReader The type of reader that processes individual object
/// fields
/// @param _object_reader The reader object that processes each field
/// @param _obj The object structure containing size information
/// @return std::nullopt on success, or an Error if reading fails
Expand All @@ -202,8 +188,9 @@ struct Reader {
return std::nullopt;
}

/// Reads a union (variant) value and converts it to the appropriate variant type.
/// Reads the discriminant first to determine which alternative is active.
/// Reads a union (variant) value and converts it to the appropriate variant
/// type. Reads the discriminant first to determine which alternative is
/// active.
/// @tparam VariantType The C++ variant type to construct
/// @tparam UnionReaderType The type of reader that handles union alternatives
/// @param _union The union structure
Expand Down
14 changes: 2 additions & 12 deletions include/rfl/boost_serialization/Writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,20 +270,10 @@ class Writer {
template <class T>
void new_value(const T& _var) const {
using Type = std::remove_cvref_t<T>;
if constexpr (std::is_same<Type, std::string>()) {
*ar_ << _var;
} else if constexpr (std::is_same<Type, bool>()) {
*ar_ << _var;
} else if constexpr (std::is_floating_point<Type>()) {
*ar_ << static_cast<double>(_var);
} else if constexpr (std::is_unsigned<Type>()) {
*ar_ << static_cast<std::uint64_t>(_var);
} else if constexpr (std::is_integral<Type>()) {
*ar_ << static_cast<std::int64_t>(_var);
} else if constexpr (internal::is_literal_v<Type>) {
if constexpr (internal::is_literal_v<Type>) {
*ar_ << static_cast<std::int64_t>(_var.value());
} else {
static_assert(rfl::always_false_v<T>, "Unsupported type.");
*ar_ << _var;
}
}

Expand Down
30 changes: 23 additions & 7 deletions include/rfl/bson/Writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,20 @@ class RFL_API Writer {
throw std::runtime_error("Could not append bool to array.");
}

} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
} else if constexpr (std::is_same<std::remove_cvref_t<T>, float>()) {
const bool ok = bson_array_builder_append_double(
_parent->val_, static_cast<double>(_var));
_parent->val_, _var);
if (!ok) {
throw std::runtime_error("Could not append float to array.");
}

} else if constexpr (std::is_same<std::remove_cvref_t<T>, double>()) {
const bool ok = bson_array_builder_append_double(
_parent->val_, _var);
if (!ok) {
throw std::runtime_error("Could not append double to array.");
}

} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
const bool ok = bson_array_builder_append_int64(
_parent->val_, static_cast<std::int64_t>(_var));
Expand Down Expand Up @@ -175,12 +182,21 @@ class RFL_API Writer {
std::string(_name) + "' to object.");
}

} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
} else if constexpr (std::is_same<std::remove_cvref_t<T>, float>()) {
const bool ok = bson_append_double(_parent->val_, _name.data(),
static_cast<int>(_name.size()),
_var);
if (!ok) {
throw std::runtime_error("Could not float field '" +
std::string(_name) + "' to object.");
}

} else if constexpr (std::is_same<std::remove_cvref_t<T>, double>()) {
const bool ok = bson_append_double(_parent->val_, _name.data(),
static_cast<int>(_name.size()),
static_cast<double>(_var));
static_cast<int>(_name.size()),
_var);
if (!ok) {
throw std::runtime_error("Could not floating point field '" +
throw std::runtime_error("Could not double field '" +
std::string(_name) + "' to object.");
}

Expand All @@ -195,7 +211,7 @@ class RFL_API Writer {

} else if constexpr (std::is_same<std::remove_cvref_t<T>, bson_oid_t>()) {
const bool ok = bson_append_oid(_parent->val_, _name.data(),
static_cast<int>(_name.size()), &_var);
static_cast<int>(_name.size()), &_var);
if (!ok) {
throw std::runtime_error("Could not oid field '" + std::string(_name) +
"' to object.");
Expand Down
36 changes: 30 additions & 6 deletions include/rfl/capnproto/Writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,18 @@ class RFL_API Writer {
internal::ptr_cast<const unsigned char*>(_var.data()), _var.size());
_parent->val_.set(_parent->ix_++, capnp::Data::Reader(array_ptr));

} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>() ||
std::is_same<std::remove_cvref_t<T>, bool>()) {
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
_parent->val_.set(_parent->ix_++, _var);

} else if constexpr (std::is_same<std::remove_cvref_t<T>, float>()) {
_parent->val_.set(_parent->ix_++, _var);

} else if constexpr (std::is_same<std::remove_cvref_t<T>, double>()) {
_parent->val_.set(_parent->ix_++, _var);

} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
_parent->val_.set(_parent->ix_++, static_cast<double>(_var));

} else if constexpr (std::is_unsigned<std::remove_cvref_t<T>>()) {
_parent->val_.set(_parent->ix_++, static_cast<std::uint64_t>(_var));

Expand Down Expand Up @@ -211,10 +219,18 @@ class RFL_API Writer {
_parent->val_.set(to_kj_string_ptr(_name),
capnp::Data::Reader(array_ptr));

} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>() ||
std::is_same<std::remove_cvref_t<T>, bool>()) {
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
_parent->val_.set(to_kj_string_ptr(_name), _var);

} else if constexpr (std::is_same<std::remove_cvref_t<T>, float>()) {
_parent->val_.set(to_kj_string_ptr(_name), _var);

} else if constexpr (std::is_same<std::remove_cvref_t<T>, double>()) {
_parent->val_.set(to_kj_string_ptr(_name), _var);

} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
_parent->val_.set(to_kj_string_ptr(_name), static_cast<double>(_var));

} else if constexpr (std::is_unsigned<std::remove_cvref_t<T>>()) {
_parent->val_.set(to_kj_string_ptr(_name),
static_cast<std::uint64_t>(_var));
Expand Down Expand Up @@ -246,10 +262,18 @@ class RFL_API Writer {
internal::ptr_cast<const unsigned char*>(_var.data()), _var.size());
_parent->val_.set(field, capnp::Data::Reader(array_ptr));

} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>() ||
std::is_same<std::remove_cvref_t<T>, bool>()) {
} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
_parent->val_.set(field, _var);

} else if constexpr (std::is_same<std::remove_cvref_t<T>, float>()) {
_parent->val_.set(field, _var);

} else if constexpr (std::is_same<std::remove_cvref_t<T>, double>()) {
_parent->val_.set(field, _var);

} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
_parent->val_.set(field, static_cast<double>(_var));

} else if constexpr (std::is_unsigned<std::remove_cvref_t<T>>()) {
_parent->val_.set(field, static_cast<std::uint64_t>(_var));

Expand Down
40 changes: 28 additions & 12 deletions include/rfl/cbor/Writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,36 @@

namespace rfl::cbor {

/// Writer class for serializing C++ objects to CBOR (Concise Binary Object Representation) format.
/// This class provides the interface for converting C++ objects into compact binary CBOR data.
/// CBOR is a binary data serialization format designed to be smaller and faster than JSON.
/// Writer class for serializing C++ objects to CBOR (Concise Binary Object
/// Representation) format. This class provides the interface for converting C++
/// objects into compact binary CBOR data. CBOR is a binary data serialization
/// format designed to be smaller and faster than JSON.
class RFL_API Writer {
using Encoder = jsoncons::cbor::cbor_bytes_encoder;

public:
/// Represents a CBOR array being constructed during serialization.
/// This is a placeholder type as the actual array data is managed by the encoder.
/// This is a placeholder type as the actual array data is managed by the
/// encoder.
struct CBOROutputArray {};

/// Represents a CBOR object being constructed during serialization.
/// This is a placeholder type as the actual object data is managed by the encoder.
/// This is a placeholder type as the actual object data is managed by the
/// encoder.
struct CBOROutputObject {};

/// Represents a CBOR value being constructed during serialization.
/// This is a placeholder type as the actual value data is managed by the encoder.
/// This is a placeholder type as the actual value data is managed by the
/// encoder.
struct CBOROutputVar {};

using OutputArrayType = CBOROutputArray;
using OutputObjectType = CBOROutputObject;
using OutputVarType = CBOROutputVar;

/// Constructs a CBOR Writer with the specified encoder.
/// @param _encoder Pointer to the CBOR encoder that will write the binary output
/// @param _encoder Pointer to the CBOR encoder that will write the binary
/// output
Writer(Encoder* _encoder);

~Writer();
Expand All @@ -49,7 +54,8 @@ class RFL_API Writer {
OutputArrayType array_as_root(const size_t _size) const;

/// Creates a CBOR object as the root element of the output.
/// @param The expected number of fields (unused, reserved for future optimization)
/// @param The expected number of fields (unused, reserved for future
/// optimization)
/// @return An output object that can be populated with key-value pairs
OutputObjectType object_as_root(const size_t) const;

Expand Down Expand Up @@ -84,15 +90,17 @@ class RFL_API Writer {
OutputObjectType* _parent) const;

/// Adds a nested object to a parent array.
/// @param The expected number of fields (unused, reserved for future optimization)
/// @param The expected number of fields (unused, reserved for future
/// optimization)
/// @param _parent Pointer to the parent array to add to
/// @return An output object that can be populated with key-value pairs
OutputObjectType add_object_to_array(const size_t,
OutputArrayType* _parent) const;

/// Adds a nested object to a parent object with the specified field name.
/// @param _name The name of the field in the parent object
/// @param The expected number of fields (unused, reserved for future optimization)
/// @param The expected number of fields (unused, reserved for future
/// optimization)
/// @param _parent Pointer to the parent object to add to
/// @return An output object that can be populated with key-value pairs
OutputObjectType add_object_to_object(const std::string_view& _name,
Expand All @@ -103,7 +111,8 @@ class RFL_API Writer {
/// Supports basic types like strings, numbers, booleans, and byte strings.
/// @tparam T The type of the value to add
/// @param _var The value to add to the array
/// @param _parent Pointer to the parent array (unused as encoder tracks context)
/// @param _parent Pointer to the parent array (unused as encoder tracks
/// context)
/// @return An output variable representing the added value
template <class T>
OutputVarType add_value_to_array(const T& _var,
Expand All @@ -116,7 +125,8 @@ class RFL_API Writer {
/// @tparam T The type of the value to add
/// @param _name The name of the field in the parent object
/// @param _var The value to add to the object
/// @param _parent Pointer to the parent object (unused as encoder tracks context)
/// @param _parent Pointer to the parent object (unused as encoder tracks
/// context)
/// @return An output variable representing the added value
template <class T>
OutputVarType add_value_to_object(const std::string_view& _name,
Expand Down Expand Up @@ -155,19 +165,25 @@ class RFL_API Writer {
OutputVarType new_value(const T& _var) const {
if constexpr (std::is_same<std::remove_cvref_t<T>, std::string>()) {
encoder_->string_value(_var);

} else if constexpr (std::is_same<std::remove_cvref_t<T>,
rfl::Bytestring>() ||
std::is_same<std::remove_cvref_t<T>,
rfl::Vectorstring>()) {
encoder_->byte_string_value(_var);

} else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
encoder_->bool_value(_var);

} else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
encoder_->double_value(static_cast<double>(_var));

} else if constexpr (std::is_unsigned<std::remove_cvref_t<T>>()) {
encoder_->uint64_value(static_cast<std::uint64_t>(_var));

} else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
encoder_->int64_value(static_cast<std::int64_t>(_var));

} else {
static_assert(rfl::always_false_v<T>, "Unsupported type.");
}
Expand Down
3 changes: 2 additions & 1 deletion include/rfl/cereal/Writer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
namespace rfl::cereal {

/// Writer for Cereal serialization library integration.
/// Writes data to Cereal's portable binary archive format for cross-platform serialization.
/// Writes data to Cereal's portable binary archive format for cross-platform
/// serialization.
class Writer {
public:
using CerealArchive = ::cereal::PortableBinaryOutputArchive;
Expand Down
Loading
Loading