HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Movable and copyable variant

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
andvariantcopyablemovable

Problem

What do you think about this variant class?

Some hype: no RTTI needed, no heap allocation, supports copying.

```
#pragma once
#ifndef VARIANT_HPP
# define VARIANT_HPP

#include

#include

#include

#include

#include

namespace detail
{

template
struct max_align_type
{
using type = typename ::std::conditional alignof(typename max_align_type::type)),
A,
typename max_align_type::type
>::type;
};

template
struct max_align_type
{
using type = typename ::std::conditional alignof(B)), A, B>::type;
};

template
struct max_align_type
{
using type = A;
};

template
struct max_size_type
{
using type = typename ::std::conditional sizeof(typename max_size_type::type)),
A,
typename max_size_type::type
>::type;
};

template
struct max_size_type
{
using type = typename ::std::conditional sizeof(B)), A, B>::type;
};

template
struct max_size_type
{
using type = A;
};

template
struct index_of :
::std::integral_constant{} ?
0 :
(-1 == index_of{}) ? -1 : 1 + index_of{}
>
{
};

template
struct index_of :
::std::integral_constant{} - 1>
{
};

template
struct has_duplicates :
::std::integral_constant{} ? has_duplicates{} : true)
>
{
};

template
struct has_duplicates :
::std::integral_constant
{
};

template
struct compatible_index_of :
::std::integral_constant{} ?
0 :
(-1 == compatible_index_of{}) ?
-1 :
1 + compatible_index_of{}
>
{
};

template
struct compatible_index_of :
::std::integral_constant{} - 1>
{
};

template
struct compatible_type
{
using type = typename ::std::conditional{},
B,
typename compatible_type::type
>::type;
};

template
struct compatible_type
{
using type = typename ::std::conditional{}, B, void>::type;
};

template
struct is_streamable : ::std::false_type { };

template
struct is_streamable()
()))))
> : ::std::true_type
{
};

template
struct type_at : type_at
{
};

template
struct type_at
{
using type = A;
};

template
using

Solution

I can think of one small improvement you can make.

In the assignment operator (for both variant and U arguments), if the typeid of the argument is the same as store_type_, you can move the argument directly into store instead of deleting and re-newing.

Otherwise, this is a pretty cool class -- always interesting to see what's possible with C++, though I'd have to see a fairly deep series of unit tests to be fully confident this code is correct. Some ideas for test cases:

  • std::unique_ptr with custom deleters moved into a variant



  • types with different alignments stored in the same variant



  • variants stored in a variant



  • trying to store a non-movable type fails to compile



  • Simple things, like



  • get fails to compile if U isn't one of the types (e.g. if it's a subtype of one of the types)



  • get throws when U isn't currently stored



  • contains works correctly



  • variant v(Foo()); Foo foo = std::move(v.get()); works correctly.



Some of these are a bit paranoid, but this is certainly the type of class where I'd like to push into the corner cases to ensure that they work as I expect.

Context

StackExchange Code Review Q#28939, answer score: 4

Revisions (0)

No revisions yet.