getml / reflect-cpp

A C++20 library for fast serialization, deserialization and validation using reflection. Supports JSON, BSON, CBOR, flexbuffers, msgpack, TOML, UBJSON, XML, YAML / msgpack.org[C++20]
https://getml.github.io/reflect-cpp/
MIT License
1.12k stars 101 forks source link

`rfl::DefaultIfMissing` processor + Reflector<FixedVector> #260

Open AnsiV01 opened 7 hours ago

AnsiV01 commented 7 hours ago

Hello

I am working on a mini-game where I am using reflect-cpp as a parser for json files and more. At some point I needed to implement support for a custom FixedVector class from the fixed_container library (https://github.com/teslamotors/fixed-containers). And here I ran into a problem, because the compiler cannot handle this class if I add a DefaultIfMissing processor when using rfl::json::(read/load). Below MRE.

#include <rfl/json.hpp>
#include <rfl/parsing/CustomParser.hpp>
#include <fixed_containers/fixed_string.hpp>

namespace rfl
{
    template <typename T, size_t Size>
    struct Reflector<fixed_containers::FixedVector<T, Size>>
    {
        using ReflType = std::vector<T>;
        static constexpr fixed_containers::FixedVector<T, Size> to(const ReflType& v)
        {
            if (v.size() > Size)
                throw std::exception("v.size() > Size");

            fixed_containers::FixedVector<T, Size> cont{};
            cont.assign(v.begin(), v.end());
            return cont;
        }

        static constexpr ReflType from(const fixed_containers::FixedVector<T, Size>& v)
        {
            ReflType cont{};
            cont.assign(v.begin(), v.end());
            return cont;
        }
    };
}

enum class Attributes
{
    NONE,
    MOVE_SPEED,
    ATTACK_SPEED,
    MAX_HP,
    MAX_MP,
};

struct Data
{
    fixed_containers::FixedVector<std::pair<Attributes, long long>, 3> attributes{};
};

int main()
{
    auto json1 = rfl::json::read<Data>(""); //this is OK
    auto json2 = rfl::json::load<Data>("data.json"); // this is OK

    auto json3 = rfl::json::read<Data, rfl::DefaultIfMissing>(""); //this fail
    auto json4 = rfl::json::load<Data, rfl::DefaultIfMissing>("data.json"); // this fail
}

The compiler (MSVC) reports a problem with the use of the deleted function:

Błąd C2280 „fixed_containers::FixedVector<std::pair<Attributes,__int64>,3,fixed_containers::customize::SequenceContainerAbortChecking<T,3>> &fixed_containers::FixedVector<T,3,fixed_containers::customize::SequenceContainerAbortChecking<T,3>>::operator =(const fixed_containers::FixedVector<T,3,fixed_containers::customize::SequenceContainerAbortChecking<T,3>> &)”: próba odwania do usuniętej funkcji with [ T=std::pair<Attributes,__int64> ] 121 E:\ecpp\ecpp\_third\rfl\parsing\ViewReaderWithDefault.hpp

And when I click on the error it redirects me to this code from the rfl\parsing\ViewReaderWithDefault.hpp:

template <class Target, class Source>
static void move_to(Target* _t, Source* _s) {
  if constexpr (std::is_const_v<Target>) {
    return move_to(const_cast<std::remove_const_t<Target>*>(_t), _s);
  } else if constexpr (!rfl::internal::is_array_v<Source> &&
                       !std::is_array_v<Target>) {
    *_t = Target(std::move(*_s));            <<-- ERROR HAPPENED HERE
  } else if constexpr (rfl::internal::is_array_v<Source>) {
    static_assert(std::is_array_v<Target>,
                  "Expected target to be a c-array.");
    for (size_t i = 0; i < _s->arr_.size(); ++i) {
      move_to(&((*_t)[i]), &(_s->arr_[i]));
    }
  } else {
    for (size_t i = 0; i < _s->size(); ++i) {
      move_to(&((*_t)[i]), &((*_s)[i]));
    }
  }
}

My question is whether there is a workaround or fix for this situation, or whether this is a problem that cannot be circumvented by the way the fixed_container library is implemented?

Thanks for any information.

liuzicheng1987 commented 6 hours ago

Hi @AnsiV01 , it appears that the move operation is failing. Could you translate the error message to English?

AnsiV01 commented 6 hours ago

@liuzicheng1987 Sure:

Severity    Code    Description Line    File    Project Suppression State   Details
Error   C2280   'fixed_containers::FixedVector<std::pair<Attributes,__int64>,3,fixed_containers::customize::SequenceContainerAbortChecking<T,3>> &fixed_containers::FixedVector<T,3,fixed_containers::customize::SequenceContainerAbortChecking<T,3>>::operator =(const fixed_containers::FixedVector<T,3,fixed_containers::customize::SequenceContainerAbortChecking<T,3>> &)': attempting to reference a deleted function
        with
        [
            T=std::pair<Attributes,__int64>
        ]   121 E:\ecpp\ecpp\_third\rfl\parsing\ViewReaderWithDefault.hpp   Common