Skip to content

FR: Deserialization to std::set with custom comparator #690

Description

@PapeCoding

Problem

During testing your library I noticed that I can easily serialize and de-serialize data structures containing std::sets. Unfortunately as soon as I add a custom comparator to a std::set and try to deserialize it does not compile anymore.

'emplace_back': is not a member of 'std::set<data,CustomComp,std::allocator>'

Small example to reproduce:

#include <set>
#include <rfl/json/write.hpp>
#include <rfl/json/read.hpp>
#include <iostream>

struct CustomComp
{
	template <typename T>
	bool operator()(const T& lhs, const T& rhs) const
	{
		return lhs.myInt < rhs.myInt;
	}
};

struct data {
	int myInt = 0;
};

struct dataFrame {
	std::set<data, CustomComp> dataset;
};

int main(int argc, char* argv[]) {
	dataFrame a;
	a.dataset.insert({ 0 });
	a.dataset.insert({ 1 });
	a.dataset.insert({ 2 });
	a.dataset.insert({ 0 });

	std::string result = rfl::json::write(a);
	std::cout << result << std::endl;
	rfl::json::read<dataFrame>(result).value();

	return 0;
}

Easy Solution Proposal:

This happens as std::set with a custom comparator (and/or custom allocator for that matter) are not included in your rfl::parsing::is_set_like structure. Thus including the following snipped in my code does the trick. Including it in your list would do the same:

#include <rfl/parsing/is_set_like.hpp>

template <class T, typename C>
class rfl::parsing::is_set_like<std::set<T, C>> : public std::true_type
{
};

Better Solution Proposal?:

It fails at this point in VectorReader.hpp

if constexpr (is_map_like_v<VecType> || is_set_like_v<VecType>) {
  vec_->insert(std::move(_var));
} else {
  vec_->emplace_back(std::move(_var));
}

Maybe rather use a concept like HasInsert to not hard-code a list of classes here. While my feature-request is about std::set<A,B> the same should be true for std::unordered_set<A,B> and all the other not in the hard-coded list. I am not sure if a HasInsert concept is restrictive enough though.

Request:

It would be nice if you find a solution that does not involve patching on the users side somehow. While my easy solution works, you would probably need to extend the list quite a bit for all the other classes and template args as well. Maybe the concept approach would be more future-proof here.

Best regards,
Sebastian

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions