General map-like conversions
To repeat what I said on Slack, now that tuple-likes are supported it looks like general maps (where the key is not string-like) would also start working (being treated as sequences of pairs.) If they do work, we need to have a test for it. If they don't, we might want to look into why.
I tested and it does indeed work. For example:
enum class K { A, B, C };
// tag_invoke for K removed for brevity
check(std::map<K, int> {
{ K::A, 1 }, { K::B, 2}, { K::C, 3},
});
I have to comment that serializing maps into arrays is suboptimal. If we could check during compilation that tag_invoke for key produces a json::string then we would be able to serialize them into objects. But that would require a different tag_invoke signature. Something like json::value tag_invoke(value_from_tag, K const&) ( and users could write json::string tag_invoke(value_from_tag, K const&)).
So, since #515 we do support all associative containers. Currently
- If the container has unique keys (checked via the result type of
emplace) and the type of key is StringLike, we convert to/from object - Otherwise we convert to/from array of 2-element arrays.
Should we pursue the former to expand to maps with keys that convert to/from json::string? E.g.
enum class E { e1, e2, e3 };
void tag_invoke(json::value_from_tag, json::value& jv, E e);
std::map<E, X> my_map;
auto jv = value_from(my_map);
I don't know
If #989 is done, this could be supported. E.g.:
enum class E { e1, e2, e3 };
struct E_String { // is_string_like
E e;
E_String(E);
explicit E_String(string_view);
operator string_view() const;
};
namespace boost::json {
template<>
struct serialize_as<E> : mp11::identity<E_String> {};
}
std::map<E, X> my_map;
auto jv = value_from(my_map);
let someone ask for it :)