From 2a4d1a17d1cb36b27349bb0244a807db46b1325a Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Tue, 17 Dec 2024 23:01:09 +0100 Subject: [PATCH 1/5] Use static_cast for the pointer transformations --- include/rfl/Result.hpp | 11 +++++------ include/rfl/Tuple.hpp | 11 +++++------ include/rfl/Variant.hpp | 18 ++++++++++-------- include/rfl/bson/Reader.hpp | 9 ++++----- include/rfl/bson/Writer.hpp | 6 +++--- include/rfl/bson/read.hpp | 4 ++-- include/rfl/bson/write.hpp | 8 ++++---- include/rfl/cbor/Writer.hpp | 7 ++++--- include/rfl/cbor/read.hpp | 6 +++--- include/rfl/cbor/write.hpp | 6 +++--- include/rfl/flexbuf/Reader.hpp | 4 ++-- include/rfl/flexbuf/read.hpp | 4 ++-- include/rfl/flexbuf/write.hpp | 6 +++--- include/rfl/internal/ptr_cast.hpp | 22 ++++++++++++++++++++++ include/rfl/msgpack/Reader.hpp | 9 ++++----- include/rfl/parsing/NamedTupleParser.hpp | 6 +++--- include/rfl/parsing/Parser_array.hpp | 5 +++-- include/rfl/parsing/Parser_default.hpp | 6 +++--- include/rfl/parsing/TupleParser.hpp | 7 ++++--- include/rfl/ubjson/Reader.hpp | 8 ++++---- include/rfl/ubjson/write.hpp | 7 ++++--- 21 files changed, 97 insertions(+), 73 deletions(-) create mode 100644 include/rfl/internal/ptr_cast.hpp diff --git a/include/rfl/Result.hpp b/include/rfl/Result.hpp index c4471dc1..12b4a58e 100644 --- a/include/rfl/Result.hpp +++ b/include/rfl/Result.hpp @@ -10,6 +10,7 @@ #include #include "internal/is_array.hpp" +#include "internal/ptr_cast.hpp" #include "internal/to_std_array.hpp" namespace rfl { @@ -314,20 +315,18 @@ class Result { } } - T& get_t() noexcept { - return *std::launder((reinterpret_cast(t_or_err_.data()))); - } + T& get_t() noexcept { return *internal::ptr_cast(t_or_err_.data()); } const T& get_t() const noexcept { - return *std::launder((reinterpret_cast(t_or_err_.data()))); + return *internal::ptr_cast(t_or_err_.data()); } Error& get_err() noexcept { - return *std::launder((reinterpret_cast(t_or_err_.data()))); + return *internal::ptr_cast(t_or_err_.data()); } const Error& get_err() const noexcept { - return *std::launder((reinterpret_cast(t_or_err_.data()))); + return *internal::ptr_cast(t_or_err_.data()); } void move_from_other(Result& _other) noexcept { diff --git a/include/rfl/Tuple.hpp b/include/rfl/Tuple.hpp index 85e38bc4..a2cffe80 100644 --- a/include/rfl/Tuple.hpp +++ b/include/rfl/Tuple.hpp @@ -14,6 +14,7 @@ #include #include "internal/nth_element_t.hpp" +#include "internal/ptr_cast.hpp" #include "internal/tuple/calculate_positions.hpp" namespace rfl { @@ -59,14 +60,14 @@ class Tuple { template constexpr auto& get() { using Type = internal::nth_element_t<_index, Types...>; - return *std::bit_cast(data_.data() + pos<_index>()); + return *internal::ptr_cast(data_.data() + pos<_index>()); } /// Gets an element by index. template constexpr const auto& get() const { using Type = internal::nth_element_t<_index, Types...>; - return *std::bit_cast(data_.data() + pos<_index>()); + return *internal::ptr_cast(data_.data() + pos<_index>()); } /// Assigns the underlying object. @@ -100,8 +101,7 @@ class Tuple { }; return [&](std::integer_sequence) { return (true && ... && is_same(std::integral_constant{})); - } - (std::make_integer_sequence()); + }(std::make_integer_sequence()); } /// Three-way comparison operator. @@ -122,8 +122,7 @@ class Tuple { auto ordering = std::strong_ordering::equivalent; (compare(&ordering, std::integral_constant{}), ...); return ordering; - } - (std::make_integer_sequence()); + }(std::make_integer_sequence()); } private: diff --git a/include/rfl/Variant.hpp b/include/rfl/Variant.hpp index 5b648281..fbee31a7 100644 --- a/include/rfl/Variant.hpp +++ b/include/rfl/Variant.hpp @@ -43,16 +43,18 @@ class Variant { struct TypeWrapper {}; public: - Variant() { + Variant() : index_(IndexType()), data_(DataType()) { using FirstAlternative = internal::nth_element_t<0, AlternativeTypes...>; move_from_type(FirstAlternative()); } - Variant(const Variant& _other) { + Variant(const Variant& _other) + : index_(IndexType()), data_(DataType()) { copy_from_other(_other); } - Variant(Variant&& _other) noexcept { + Variant(Variant&& _other) noexcept + : index_(IndexType()), data_(DataType()) { move_from_other(std::move(_other)); } @@ -60,7 +62,7 @@ class Variant { typename std::enable_if(), bool>::type = true> - Variant(const T& _t) { + Variant(const T& _t) : index_(IndexType()), data_(DataType()) { copy_from_type(_t); } @@ -68,7 +70,7 @@ class Variant { typename std::enable_if(), bool>::type = true> - Variant(T&& _t) noexcept { + Variant(T&& _t) noexcept : index_(IndexType()), data_(DataType()) { move_from_type(std::forward(_t)); } @@ -80,7 +82,7 @@ class Variant { auto t = T{std::forward(_args)...}; destroy_if_necessary(); move_from_type(std::move(t)); - return *std::launder(reinterpret_cast(data_.data())); + return *internal::ptr_cast(data_.data()); } /// Emplaces a new element into the variant. @@ -384,13 +386,13 @@ class Variant { template auto& get_alternative() noexcept { using CurrentType = internal::nth_element_t<_i, AlternativeTypes...>; - return *std::launder(reinterpret_cast(data_.data())); + return *internal::ptr_cast(data_.data()); } template const auto& get_alternative() const noexcept { using CurrentType = internal::nth_element_t<_i, AlternativeTypes...>; - return *std::launder(reinterpret_cast(data_.data())); + return *internal::ptr_cast(data_.data()); } void move_from_other(Variant&& _other) noexcept { diff --git a/include/rfl/bson/Reader.hpp b/include/rfl/bson/Reader.hpp index 386efc49..28302493 100644 --- a/include/rfl/bson/Reader.hpp +++ b/include/rfl/bson/Reader.hpp @@ -4,7 +4,6 @@ #include #include -#include #include #include #include @@ -23,6 +22,7 @@ #include "../Bytestring.hpp" #include "../Result.hpp" #include "../always_false.hpp" +#include "../internal/ptr_cast.hpp" namespace rfl { namespace bson { @@ -46,9 +46,8 @@ struct Reader { using InputVarType = BSONInputVar; template - static constexpr bool has_custom_constructor = (requires(InputVarType var) { - T::from_bson_obj(var); - }); + static constexpr bool has_custom_constructor = + (requires(InputVarType var) { T::from_bson_obj(var); }); rfl::Result get_field_from_array( const size_t _idx, const InputArrayType& _arr) const noexcept; @@ -85,7 +84,7 @@ struct Reader { "bytestring."); } return rfl::Bytestring( - std::bit_cast(value.v_binary.data), + internal::ptr_cast(value.v_binary.data), value.v_binary.data_len); } else if constexpr (std::is_same, bool>()) { if (btype != BSON_TYPE_BOOL) { diff --git a/include/rfl/bson/Writer.hpp b/include/rfl/bson/Writer.hpp index dd85cf74..27307c23 100644 --- a/include/rfl/bson/Writer.hpp +++ b/include/rfl/bson/Writer.hpp @@ -3,7 +3,6 @@ #include -#include #include #include #include @@ -20,6 +19,7 @@ #include "../Ref.hpp" #include "../Result.hpp" #include "../always_false.hpp" +#include "../internal/ptr_cast.hpp" namespace rfl { namespace bson { @@ -104,7 +104,7 @@ class Writer { rfl::Bytestring>()) { bson_array_builder_append_binary( _parent->val_, BSON_SUBTYPE_BINARY, - std::bit_cast(_var.c_str()), + internal::ptr_cast(_var.c_str()), static_cast(_var.size())); } else if constexpr (std::is_same, bool>()) { bson_array_builder_append_bool(_parent->val_, _var); @@ -134,7 +134,7 @@ class Writer { rfl::Bytestring>()) { bson_append_binary(_parent->val_, _name.data(), static_cast(_name.size()), BSON_SUBTYPE_BINARY, - std::bit_cast(_var.c_str()), + internal::ptr_cast(_var.c_str()), static_cast(_var.size())); } else if constexpr (std::is_same, bool>()) { bson_append_bool(_parent->val_, _name.data(), diff --git a/include/rfl/bson/read.hpp b/include/rfl/bson/read.hpp index 5333cfb6..0ac57d60 100644 --- a/include/rfl/bson/read.hpp +++ b/include/rfl/bson/read.hpp @@ -3,11 +3,11 @@ #include -#include #include #include #include "../Processors.hpp" +#include "../internal/ptr_cast.hpp" #include "../internal/wrap_in_rfl_array_t.hpp" #include "Parser.hpp" #include "Reader.hpp" @@ -42,7 +42,7 @@ auto read(const uint8_t* _bytes, const size_t _size) { /// Parses an BSON object using reflection. template auto read(const char* _bytes, const size_t _size) { - return read(std::bit_cast(_bytes), _size); + return read(internal::ptr_cast(_bytes), _size); } /// Parses an object from BSON using reflection. diff --git a/include/rfl/bson/write.hpp b/include/rfl/bson/write.hpp index 6c4b633b..86b2d2ff 100644 --- a/include/rfl/bson/write.hpp +++ b/include/rfl/bson/write.hpp @@ -3,13 +3,13 @@ #include -#include #include #include #include #include #include "../Processors.hpp" +#include "../internal/ptr_cast.hpp" #include "../parsing/Parent.hpp" #include "Parser.hpp" @@ -45,8 +45,8 @@ std::pair to_buffer(const auto& _obj) noexcept { template std::vector write(const auto& _obj) noexcept { auto [buf, len] = to_buffer(_obj); - const auto result = std::vector(std::bit_cast(buf), - std::bit_cast(buf) + len); + const auto result = std::vector(internal::ptr_cast(buf), + internal::ptr_cast(buf) + len); bson_free(buf); return result; } @@ -55,7 +55,7 @@ std::vector write(const auto& _obj) noexcept { template std::ostream& write(const auto& _obj, std::ostream& _stream) noexcept { auto [buf, len] = to_buffer(_obj); - _stream.write(std::bit_cast(buf), len); + _stream.write(internal::ptr_cast(buf), len); bson_free(buf); return _stream; } diff --git a/include/rfl/cbor/Writer.hpp b/include/rfl/cbor/Writer.hpp index 9fa5e21e..2a41d09e 100644 --- a/include/rfl/cbor/Writer.hpp +++ b/include/rfl/cbor/Writer.hpp @@ -3,7 +3,6 @@ #include -#include #include #include #include @@ -19,6 +18,7 @@ #include "../Ref.hpp" #include "../Result.hpp" #include "../always_false.hpp" +#include "../internal/ptr_cast.hpp" namespace rfl { namespace cbor { @@ -106,8 +106,9 @@ class Writer { cbor_encode_text_string(_parent, _var.c_str(), _var.size()); } else if constexpr (std::is_same, rfl::Bytestring>()) { - cbor_encode_byte_string( - _parent, std::bit_cast(_var.c_str()), _var.size()); + cbor_encode_byte_string(_parent, + internal::ptr_cast(_var.c_str()), + _var.size()); } else if constexpr (std::is_same, bool>()) { cbor_encode_boolean(_parent, _var); } else if constexpr (std::is_floating_point>()) { diff --git a/include/rfl/cbor/read.hpp b/include/rfl/cbor/read.hpp index a9be4443..6b1df88d 100644 --- a/include/rfl/cbor/read.hpp +++ b/include/rfl/cbor/read.hpp @@ -3,11 +3,11 @@ #include -#include #include #include #include "../Processors.hpp" +#include "../internal/ptr_cast.hpp" #include "../internal/wrap_in_rfl_array_t.hpp" #include "Parser.hpp" #include "Reader.hpp" @@ -31,8 +31,8 @@ Result> read(const char* _bytes, const size_t _size) { CborParser parser; InputVarType doc; - cbor_parser_init(std::bit_cast(_bytes), _size, 0, &parser, - &doc.val_); + cbor_parser_init(internal::ptr_cast(_bytes), _size, 0, + &parser, &doc.val_); auto result = read(doc); return result; } diff --git a/include/rfl/cbor/write.hpp b/include/rfl/cbor/write.hpp index 3878a1c1..a8e878e4 100644 --- a/include/rfl/cbor/write.hpp +++ b/include/rfl/cbor/write.hpp @@ -3,13 +3,13 @@ #include -#include #include #include #include #include #include +#include "../internal/ptr_cast.hpp" #include "../parsing/Parent.hpp" #include "Parser.hpp" @@ -21,7 +21,7 @@ void write_into_buffer(const auto& _obj, CborEncoder* _encoder, std::vector* _buffer) noexcept { using T = std::remove_cvref_t; using ParentType = parsing::Parent; - cbor_encoder_init(_encoder, std::bit_cast(_buffer->data()), + cbor_encoder_init(_encoder, internal::ptr_cast(_buffer->data()), _buffer->size(), 0); const auto writer = Writer(_encoder); Parser>::write(writer, _obj, @@ -41,7 +41,7 @@ std::vector write(const auto& _obj) noexcept { write_into_buffer(_obj, &encoder, &buffer); } const auto length = cbor_encoder_get_buffer_size( - &encoder, std::bit_cast(buffer.data())); + &encoder, internal::ptr_cast(buffer.data())); buffer.resize(length); return buffer; } diff --git a/include/rfl/flexbuf/Reader.hpp b/include/rfl/flexbuf/Reader.hpp index b6e9e997..ee6a7621 100644 --- a/include/rfl/flexbuf/Reader.hpp +++ b/include/rfl/flexbuf/Reader.hpp @@ -3,7 +3,6 @@ #include -#include #include #include #include @@ -17,6 +16,7 @@ #include "../Bytestring.hpp" #include "../Result.hpp" #include "../always_false.hpp" +#include "../internal/ptr_cast.hpp" namespace rfl { namespace flexbuf { @@ -65,7 +65,7 @@ struct Reader { return rfl::Error("Could not cast to a bytestring."); } const auto blob = _var.AsBlob(); - return rfl::Bytestring(std::bit_cast(blob.data()), + return rfl::Bytestring(internal::ptr_cast(blob.data()), blob.size()); } else if constexpr (std::is_same, bool>()) { if (!_var.IsBool()) { diff --git a/include/rfl/flexbuf/read.hpp b/include/rfl/flexbuf/read.hpp index d270c3cd..26f80103 100644 --- a/include/rfl/flexbuf/read.hpp +++ b/include/rfl/flexbuf/read.hpp @@ -3,12 +3,12 @@ #include -#include #include #include #include "../Processors.hpp" #include "../Result.hpp" +#include "../internal/ptr_cast.hpp" #include "Parser.hpp" namespace rfl { @@ -27,7 +27,7 @@ auto read(const InputVarType& _obj) { template auto read(const char* _bytes, const size_t _size) { const InputVarType root = - flexbuffers::GetRoot(std::bit_cast(_bytes), _size); + flexbuffers::GetRoot(internal::ptr_cast(_bytes), _size); return read(root); } diff --git a/include/rfl/flexbuf/write.hpp b/include/rfl/flexbuf/write.hpp index 95360524..48ba4217 100644 --- a/include/rfl/flexbuf/write.hpp +++ b/include/rfl/flexbuf/write.hpp @@ -3,7 +3,6 @@ #include -#include #include #include #include @@ -11,6 +10,7 @@ #include "../Processors.hpp" #include "../Ref.hpp" +#include "../internal/ptr_cast.hpp" #include "../parsing/Parent.hpp" #include "Parser.hpp" @@ -32,7 +32,7 @@ std::vector to_buffer(const auto& _obj) { template std::vector write(const auto& _obj) { const auto buffer = to_buffer(_obj); - const auto data = std::bit_cast(buffer.data()); + const auto data = internal::ptr_cast(buffer.data()); return std::vector(data, data + buffer.size()); } @@ -40,7 +40,7 @@ std::vector write(const auto& _obj) { template std::ostream& write(const auto& _obj, std::ostream& _stream) { const auto buffer = to_buffer(_obj); - const auto data = std::bit_cast(buffer.data()); + const auto data = internal::ptr_cast(buffer.data()); _stream.write(data, buffer.size()); return _stream; } diff --git a/include/rfl/internal/ptr_cast.hpp b/include/rfl/internal/ptr_cast.hpp new file mode 100644 index 00000000..9efba7aa --- /dev/null +++ b/include/rfl/internal/ptr_cast.hpp @@ -0,0 +1,22 @@ +#ifndef RFL_INTERNAL_PTRCAST_HPP_ +#define RFL_INTERNAL_PTRCAST_HPP_ + +namespace rfl::internal { + +/// Normally, we would use std::launder(reinterpret_cast<...>(...)), +/// but there are weird issues on GCC 12 under certain compiler settings, +/// so we are using this workaround instead. + +template +inline T1 ptr_cast(T2* _ptr) { + return static_cast(static_cast(_ptr)); +} + +template +inline T1 ptr_cast(const T2* _ptr) { + return static_cast(static_cast(_ptr)); +} + +} // namespace rfl::internal + +#endif diff --git a/include/rfl/msgpack/Reader.hpp b/include/rfl/msgpack/Reader.hpp index bf93fcf6..6085c6f1 100644 --- a/include/rfl/msgpack/Reader.hpp +++ b/include/rfl/msgpack/Reader.hpp @@ -3,7 +3,6 @@ #include -#include #include #include #include @@ -13,6 +12,7 @@ #include "../Bytestring.hpp" #include "../Result.hpp" #include "../always_false.hpp" +#include "../internal/ptr_cast.hpp" namespace rfl { namespace msgpack { @@ -23,9 +23,8 @@ struct Reader { using InputVarType = msgpack_object; template - static constexpr bool has_custom_constructor = (requires(InputVarType var) { - T::from_msgpack_obj(var); - }); + static constexpr bool has_custom_constructor = + (requires(InputVarType var) { T::from_msgpack_obj(var); }); rfl::Result get_field_from_array( const size_t _idx, const InputArrayType _arr) const noexcept; @@ -50,7 +49,7 @@ struct Reader { return Error("Could not cast to a bytestring."); } const auto bin = _var.via.bin; - return rfl::Bytestring(std::bit_cast(bin.ptr), + return rfl::Bytestring(internal::ptr_cast(bin.ptr), bin.size); } else if constexpr (std::is_same, bool>()) { if (type != MSGPACK_OBJECT_BOOLEAN) { diff --git a/include/rfl/parsing/NamedTupleParser.hpp b/include/rfl/parsing/NamedTupleParser.hpp index a87224ac..4cf8d203 100644 --- a/include/rfl/parsing/NamedTupleParser.hpp +++ b/include/rfl/parsing/NamedTupleParser.hpp @@ -2,7 +2,6 @@ #define RFL_PARSING_NAMEDTUPLEPARSER_HPP_ #include -#include #include #include #include @@ -20,6 +19,7 @@ #include "../internal/is_skip.hpp" #include "../internal/no_duplicate_field_names.hpp" #include "../internal/nth_element_t.hpp" +#include "../internal/ptr_cast.hpp" #include "../internal/strings/replace_all.hpp" #include "../to_view.hpp" #include "AreReaderAndWriter.hpp" @@ -40,7 +40,7 @@ namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct NamedTupleParser { using InputVarType = typename R::InputVarType; @@ -86,7 +86,7 @@ struct NamedTupleParser { internal::no_duplicate_field_names()); alignas(NamedTuple) unsigned char buf[sizeof(NamedTuple)]; - auto ptr = std::bit_cast*>(&buf); + auto ptr = internal::ptr_cast*>(&buf); auto view = rfl::to_view(*ptr); using ViewType = std::remove_cvref_t; const auto [set, err] = diff --git a/include/rfl/parsing/Parser_array.hpp b/include/rfl/parsing/Parser_array.hpp index 96613aa2..d83f2e6a 100644 --- a/include/rfl/parsing/Parser_array.hpp +++ b/include/rfl/parsing/Parser_array.hpp @@ -10,6 +10,7 @@ #include "../Ref.hpp" #include "../Result.hpp" #include "../always_false.hpp" +#include "../internal/ptr_cast.hpp" #include "ArrayReader.hpp" #include "Parent.hpp" #include "Parser_base.hpp" @@ -19,7 +20,7 @@ namespace rfl { namespace parsing { template -requires AreReaderAndWriter> + requires AreReaderAndWriter> struct Parser, ProcessorsType> { public: using InputArrayType = typename R::InputArrayType; @@ -33,7 +34,7 @@ struct Parser, ProcessorsType> { [&](const InputArrayType& _arr) -> Result> { alignas( std::array) unsigned char buf[sizeof(std::array)]; - auto ptr = std::bit_cast*>(&buf); + auto ptr = internal::ptr_cast*>(&buf); const auto array_reader = ArrayReader(&_r, ptr); auto err = _r.read_array(array_reader, _arr); diff --git a/include/rfl/parsing/Parser_default.hpp b/include/rfl/parsing/Parser_default.hpp index 809b881b..88dd8422 100644 --- a/include/rfl/parsing/Parser_default.hpp +++ b/include/rfl/parsing/Parser_default.hpp @@ -1,7 +1,6 @@ #ifndef RFL_PARSING_PARSER_DEFAULT_HPP_ #define RFL_PARSING_PARSER_DEFAULT_HPP_ -#include #include #include #include @@ -19,6 +18,7 @@ #include "../internal/is_underlying_enums_v.hpp" #include "../internal/is_validator.hpp" #include "../internal/processed_t.hpp" +#include "../internal/ptr_cast.hpp" #include "../internal/to_ptr_named_tuple.hpp" #include "../to_view.hpp" #include "../type_name_t.hpp" @@ -34,7 +34,7 @@ namespace parsing { /// Default case - anything that cannot be explicitly matched. template -requires AreReaderAndWriter + requires AreReaderAndWriter struct Parser { public: using InputVarType = typename R::InputVarType; @@ -256,7 +256,7 @@ struct Parser { /// fields might not be default-constructible. static Result read_struct(const R& _r, const InputVarType& _var) { alignas(T) unsigned char buf[sizeof(T)]{}; - auto ptr = std::bit_cast(&buf); + auto ptr = internal::ptr_cast(&buf); auto view = ProcessorsType::template process(to_view(*ptr)); using ViewType = std::remove_cvref_t; const auto [set, err] = diff --git a/include/rfl/parsing/TupleParser.hpp b/include/rfl/parsing/TupleParser.hpp index 00989aa2..0ce06f4a 100644 --- a/include/rfl/parsing/TupleParser.hpp +++ b/include/rfl/parsing/TupleParser.hpp @@ -11,6 +11,7 @@ #include "../Tuple.hpp" #include "../always_false.hpp" #include "../internal/nth_element_t.hpp" +#include "../internal/ptr_cast.hpp" #include "Parent.hpp" #include "TupleReader.hpp" #include "call_destructors_on_tuple_where_necessary.hpp" @@ -20,7 +21,7 @@ namespace rfl::parsing { template -requires AreReaderAndWriter + requires AreReaderAndWriter struct TupleParser { public: using InputArrayType = typename R::InputArrayType; @@ -31,8 +32,8 @@ struct TupleParser { static Result read(const R& _r, const InputVarType& _var) noexcept { const auto parse = [&](const InputArrayType& _arr) -> Result { - alignas(TupleType) unsigned char buf[sizeof(TupleType)]; - auto ptr = std::bit_cast(&buf); + alignas(TupleType) unsigned char buf[sizeof(TupleType)]{}; + auto ptr = internal::ptr_cast(&buf); const auto tuple_reader = TupleReader(&_r, ptr); diff --git a/include/rfl/ubjson/Reader.hpp b/include/rfl/ubjson/Reader.hpp index 64d7656d..84b308f4 100644 --- a/include/rfl/ubjson/Reader.hpp +++ b/include/rfl/ubjson/Reader.hpp @@ -12,6 +12,7 @@ #include "../Bytestring.hpp" #include "../Result.hpp" #include "../always_false.hpp" +#include "../internal/ptr_cast.hpp" namespace rfl::ubjson { @@ -38,9 +39,8 @@ class Reader { ~Reader() = default; template - static constexpr bool has_custom_constructor = (requires(InputVarType var) { - T::from_ubjson_obj(var); - }); + static constexpr bool has_custom_constructor = + (requires(InputVarType var) { T::from_ubjson_obj(var); }); rfl::Result get_field_from_array( const size_t _idx, const InputArrayType& _arr) const noexcept; @@ -63,7 +63,7 @@ class Reader { return Error("Could not cast to bytestring."); } const auto vec = _var.val_->as>(); - return rfl::Bytestring(std::bit_cast(vec.data()), + return rfl::Bytestring(internal::ptr_cast(vec.data()), vec.size()); } else if constexpr (std::is_same, bool>()) { if (!_var.val_->is_bool()) { diff --git a/include/rfl/ubjson/write.hpp b/include/rfl/ubjson/write.hpp index 7f5d5ea2..65d341db 100644 --- a/include/rfl/ubjson/write.hpp +++ b/include/rfl/ubjson/write.hpp @@ -1,7 +1,6 @@ #ifndef RFL_UBJSON_WRITE_HPP_ #define RFL_UBJSON_WRITE_HPP_ -#include #include #include #include @@ -9,6 +8,7 @@ #include #include +#include "../internal/ptr_cast.hpp" #include "../parsing/Parent.hpp" #include "Parser.hpp" @@ -24,8 +24,9 @@ std::vector write(const auto& _obj) noexcept { const auto writer = Writer(&encoder); Parser>::write(writer, _obj, typename ParentType::Root{}); - return std::vector(std::bit_cast(buffer.data()), - std::bit_cast(buffer.data() + buffer.size())); + return std::vector( + internal::ptr_cast(buffer.data()), + internal::ptr_cast(buffer.data() + buffer.size())); } /// Writes a UBJSON into an ostream. From 72cda49089df2e95a37fd3aa39bb45b8aa7d73bb Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Tue, 17 Dec 2024 23:35:17 +0100 Subject: [PATCH 2/5] Try going back to bit_cast --- include/rfl/internal/ptr_cast.hpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/include/rfl/internal/ptr_cast.hpp b/include/rfl/internal/ptr_cast.hpp index 9efba7aa..739bde3d 100644 --- a/include/rfl/internal/ptr_cast.hpp +++ b/include/rfl/internal/ptr_cast.hpp @@ -1,6 +1,8 @@ #ifndef RFL_INTERNAL_PTRCAST_HPP_ #define RFL_INTERNAL_PTRCAST_HPP_ +#include + namespace rfl::internal { /// Normally, we would use std::launder(reinterpret_cast<...>(...)), @@ -9,13 +11,14 @@ namespace rfl::internal { template inline T1 ptr_cast(T2* _ptr) { - return static_cast(static_cast(_ptr)); + return std::bit_cast(_ptr); + // return static_cast(static_cast(_ptr)); } - +/* template inline T1 ptr_cast(const T2* _ptr) { - return static_cast(static_cast(_ptr)); -} + //return static_cast(static_cast(_ptr)); +}*/ } // namespace rfl::internal From 3d8fcac93014c937a9ffab69768ecd949e6380e5 Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Tue, 17 Dec 2024 23:52:16 +0100 Subject: [PATCH 3/5] Go back to static_cast --- include/rfl/internal/ptr_cast.hpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/include/rfl/internal/ptr_cast.hpp b/include/rfl/internal/ptr_cast.hpp index 739bde3d..0ca80450 100644 --- a/include/rfl/internal/ptr_cast.hpp +++ b/include/rfl/internal/ptr_cast.hpp @@ -11,14 +11,13 @@ namespace rfl::internal { template inline T1 ptr_cast(T2* _ptr) { - return std::bit_cast(_ptr); - // return static_cast(static_cast(_ptr)); + return static_cast(static_cast(_ptr)); } -/* + template inline T1 ptr_cast(const T2* _ptr) { - //return static_cast(static_cast(_ptr)); -}*/ + return static_cast(static_cast(_ptr)); +} } // namespace rfl::internal From 8076d1651fbd121491e6d1aad6e085b05824cc55 Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Tue, 17 Dec 2024 23:52:24 +0100 Subject: [PATCH 4/5] Use reinterpret_cast in Result --- include/rfl/Result.hpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/include/rfl/Result.hpp b/include/rfl/Result.hpp index 12b4a58e..b762c2e9 100644 --- a/include/rfl/Result.hpp +++ b/include/rfl/Result.hpp @@ -315,18 +315,24 @@ class Result { } } - T& get_t() noexcept { return *internal::ptr_cast(t_or_err_.data()); } + T& get_t() noexcept { + // return *internal::ptr_cast(t_or_err_.data()); + return *std::launder(reinterpret_cast(t_or_err_.data())); + } const T& get_t() const noexcept { - return *internal::ptr_cast(t_or_err_.data()); + // return *internal::ptr_cast(t_or_err_.data()); + return *std::launder(reinterpret_cast(t_or_err_.data())); } Error& get_err() noexcept { - return *internal::ptr_cast(t_or_err_.data()); + // return *internal::ptr_cast(t_or_err_.data()); + return *std::launder(reinterpret_cast(t_or_err_.data())); } const Error& get_err() const noexcept { - return *internal::ptr_cast(t_or_err_.data()); + // return *internal::ptr_cast(t_or_err_.data()); + return *std::launder(reinterpret_cast(t_or_err_.data())); } void move_from_other(Result& _other) noexcept { From 850990a6108fdbf812138e38d4bbf2f99383fbb8 Mon Sep 17 00:00:00 2001 From: "Dr. Patrick Urbanke" Date: Wed, 18 Dec 2024 00:15:17 +0100 Subject: [PATCH 5/5] Remove code that was commented out --- include/rfl/Result.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/rfl/Result.hpp b/include/rfl/Result.hpp index b762c2e9..a21e239c 100644 --- a/include/rfl/Result.hpp +++ b/include/rfl/Result.hpp @@ -316,22 +316,18 @@ class Result { } T& get_t() noexcept { - // return *internal::ptr_cast(t_or_err_.data()); return *std::launder(reinterpret_cast(t_or_err_.data())); } const T& get_t() const noexcept { - // return *internal::ptr_cast(t_or_err_.data()); return *std::launder(reinterpret_cast(t_or_err_.data())); } Error& get_err() noexcept { - // return *internal::ptr_cast(t_or_err_.data()); return *std::launder(reinterpret_cast(t_or_err_.data())); } const Error& get_err() const noexcept { - // return *internal::ptr_cast(t_or_err_.data()); return *std::launder(reinterpret_cast(t_or_err_.data())); }