eggs-cpp / variant

Eggs.Variant is a C++11/14/17 generic, type-safe, discriminated union.
http://eggs-cpp.github.io/variant/
Boost Software License 1.0
138 stars 27 forks source link

Allow recursive variants to be defined #12

Closed jbcoe closed 9 years ago

jbcoe commented 9 years ago

I'd like to use eggs variant to represent recursive data structures like JSON which contain maps or lists of more JSON.

K-ballo commented 9 years ago

I'd like that too, but not in an intrusive way as that would imply dynamic memory allocation, and a union performs no dynamic memory allocation implicitly.

A while ago I started working on a value_ptr-like utility to use together with variant, but once it started to get too complex (custom deleter, proper allocator support, etc) I abandoned it in favor of a plain dumb one for internal use only.

As for JSON, I have implemented the data structure on top of eggs::variant. Imagine something on the lines of:

class value;
using object = std::map<std::string, value>;
using array = std::vector<value>;

class value : eggs::variant<null_t, double, std::string, object, array, bool> { /*...*/ };

Except that map and vector were custom containers, with interfaces matching their domain and implementations hand-tailored for the task (names of elements in an object share a single arena, lookup is cache-friendly, etc). Note that C++1z minimal incomplete container support guarantees you vectors of incomplete types but not maps.

What do you have in mind?

jbcoe commented 9 years ago

The example you give looks great. I can use this approach to represent JSON as libc++ and libstdc++ both appear to support maps of incomplete type.

jbcoe commented 9 years ago

Inheritance feels slightly wrong to me. Is there any way to forward declare a template alias?

K-ballo commented 9 years ago

Inheritance feels slightly wrong to me.

Inheritance is private in the snippet. A JSON value is not an eggs::variant, it is implemented in terms of an eggs::variant.

Is there any way to forward declare a template alias?

Not that I know of.

jbcoe commented 9 years ago

Cool. I missed the private inheritance, the example looks perfect. It would be nice to avoid the boilerplate I'll have to write to get value to behave like a variant (visitation etc) but it's not a big deal. eggs::variant can do everything I need it to do - thanks for your hard work on this awesome library.