PrevUpHome

Future Directions

Analogue of boost::blank

Boost variant also supports a special type boost::blank which it treats as a designated empty state if it is one of the value-types. This allows it to avoid making some of its dynamic allocations -- it behaves more like std::variant then.

This is potentially useful for strict_variant also. It would be nice also if we can be nothrow_move_constructible in this scenario, even when recursive_wrapper are used.

constexpr support

constexpr support is somewhat harder to do well at C++11 standard compared to at C++14. And since constexpr computations cannot make dynamic allocations, it's not consistent with recursive_wrapper which is an essential component of easy_variant. Any constexpr usage would be somewhat orthogonal to the bulk of the development work so far.

It could be added in the future, but for now we simply use placement-new in our storage and there is no constexpr support. We could use a more sophisticated storage object, like the recursive union used in eggs::variant, without changing the existing code much. But again, at C++11 standard, it's much harder to do something useful within a visitor than it is at C++14, so it's not all that attractive.

If you need this, you might want to take a good look at eggs::variant.

Patches are welcome!

allocator support

Since recursive_wrapper makes dynamic allocations on behalf of the variant, a quite natural refinement would be to allow custom allocators to be used with the wrapper.

I'm leery of adding the allocator as a template parameter to variant itself, since it will complicate usage significantly, and no one else does this.

However, a decent compromise is to support only stateless allocators, and to pass these as a second template parameter to recursive_wrapper. Users can make their own version of template alias easy_variant using their custom allcators, which would still be quite ergonomic.

Extract heap objects

One way to mitigate the costs of using recursive_wrapper in the variant would be if it were possible to "take ownership" of the dynamic allocation from the variant. Basically the idea would be to have some kind of "destructive visit" that consumes that variant and passes the stored value to the visitor, putting it in a std::unique_ptr if it was held in a recursive_wrapper.

This is sort of a riff on the "destructive move" proposal:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4158.pdf

Improve noexcept annotations of variant when using recursive_wrapper?

One of the basic design ideas here is to use recursive_wrapper when a type has a throwing move.

However, this has the potential to reduce the quality of our noexcept annotations in certain situations.

The reason is that, recursive_wrapper is supposed to work also when the type is incomplete -- in that case the traits that determine whether special member functions of the variant throw, basically have to assume that they might, since we can't check the actual type.

In cases when the type is complete, we could introduce a different wrapper, say, heap_wrapper or something, which would be the same, but we would be able to interrogate the type to determine situations in which it throws.

Now, usually you would only use heap_wrapper when the type has a throwing move, and in that case, it likely also has a throwing copy. So not much is likely to be gained by heap_wrapper here.

It would be nice if, when recursive_wrapper is used with a type which is incomplete, but doesn't actually throw, we can actually deduce that fact. But as far as I know this isn't feasible -- the noexcept annotations on the variant special member functions must be complete at the point of instantiation of the variant. So we have to assume the worst when the user uses recursive_wrapper, so far as I know.

Support references using std::reference_wrapper?

The boost::variant does this, but it doesn't seem all that useful, and would introduce more complex rules for safety.

Support arrays implicitly using std::array?

It seems simpler to just explicitly forbid arrays, but I didn't do this yet either.

Note that actually, iiuc both references and arrays are forbidden in C++17 std::variant spec.


PrevUpHome