Skip to content

Commit ec93054

Browse files
committed
Implement swap as per standard (GCC 5.2 warns -Wmaybe-uninitialized tmp)
1 parent 613156c commit ec93054

File tree

3 files changed

+75
-15
lines changed

3 files changed

+75
-15
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,15 +359,17 @@ variant: Allows to copy-emplace elements from intializer-list based on type (C++
359359
variant: Allows to move-emplace elements from intializer-list based on type (C++11)
360360
variant: Allows to copy-emplace elements from intializer-list based on index (C++11)
361361
variant: Allows to move-emplace elements from intializer-list based on index (C++11)
362-
variant: Allows to swap variants (member)
362+
variant: Allows to swap variants, same index (member)
363+
variant: Allows to swap variants, different index (member)
363364
variant: Allows to visit contents (non-standard: always returning variant)
364365
variant: Allows to check for content by type
365366
variant: Allows to get element by type
366367
variant: Allows to get element by index
367368
variant: Allows to get pointer to element or NULL by type
368369
variant: Allows to get pointer to element or NULL by index
369370
variant: Allows to compare variants
370-
variant: Allows to swap variants (non-member)
371+
variant: Allows to swap variants, same index (non-member)
372+
variant: Allows to swap variants, different index (non-member)
371373
monostate: Allows to make variant default-constructible
372374
bad_variant_access: Indicates invalid variant access
373375
variant_size<>: Allows to obtain number of element types (non-standard: max 7)

include/nonstd/variant.hpp

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -966,9 +966,20 @@ class variant
966966

967967
void swap( variant & other ) variant_noexcept
968968
{
969-
variant temp = *this;
970-
*this = other;
971-
other = temp;
969+
if ( valueless_by_exception() && other.valueless_by_exception() )
970+
{
971+
// no effect
972+
}
973+
else if ( index() == other.index() )
974+
{
975+
this->swap_value( index(), other );
976+
}
977+
else
978+
{
979+
variant tmp( *this );
980+
*this = other;
981+
other = tmp;
982+
}
972983
}
973984

974985
//
@@ -1007,6 +1018,20 @@ class variant
10071018
return *as<const T>();
10081019
}
10091020

1021+
template< std::size_t I >
1022+
typename variant_alternative< I, variant >::type &
1023+
get()
1024+
{
1025+
return this->template get< typename detail::typelist_type_at< variant_types, I >::type >();
1026+
}
1027+
1028+
template< std::size_t I >
1029+
typename variant_alternative< I, variant >::type const &
1030+
get() const
1031+
{
1032+
return this->template get< typename detail::typelist_type_at< variant_types, I >::type >();
1033+
}
1034+
10101035
private:
10111036
typedef typename helper_type::type_index_t type_index_t;
10121037

@@ -1132,8 +1157,23 @@ class variant
11321157
}
11331158
return *this;
11341159
}
1135-
1136-
#endif
1160+
1161+
#endif // variant_CPP11_OR_GREATER
1162+
1163+
void swap_value( std::size_t index, variant & other )
1164+
{
1165+
using std::swap;
1166+
switch( index )
1167+
{
1168+
case 0: swap( this->template get<0>(), other.template get<0>() ); break;
1169+
case 1: swap( this->template get<1>(), other.template get<1>() ); break;
1170+
case 2: swap( this->template get<2>(), other.template get<2>() ); break;
1171+
case 3: swap( this->template get<3>(), other.template get<3>() ); break;
1172+
case 4: swap( this->template get<4>(), other.template get<4>() ); break;
1173+
case 5: swap( this->template get<5>(), other.template get<5>() ); break;
1174+
case 6: swap( this->template get<6>(), other.template get<6>() ); break;
1175+
}
1176+
}
11371177

11381178
private:
11391179
enum { data_size = detail::typelist_max< variant_types >::value };
@@ -1194,9 +1234,7 @@ get( variant<T0, T1, T2, T3, T4, T5, T6> & v, in_place_index_t(I) = in_place<I>
11941234
throw bad_variant_access();
11951235
}
11961236

1197-
typedef variant_TL7(T0, T1, T2, T3, T4, T5, T6) variant_types;
1198-
1199-
return v.template get< typename detail::typelist_type_at< variant_types, I >::type >();
1237+
return v.template get<I>();
12001238
}
12011239

12021240
template< std::size_t I, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >
@@ -1208,9 +1246,7 @@ get( variant<T0, T1, T2, T3, T4, T5, T6> const & v, in_place_index_t(I) = in_pla
12081246
throw bad_variant_access();
12091247
}
12101248

1211-
typedef variant_TL7(T0, T1, T2, T3, T4, T5, T6) variant_types;
1212-
1213-
return v.template get< typename detail::typelist_type_at< variant_types, I >::type >();
1249+
return v.template get<I>();
12141250
}
12151251

12161252
template< class T, class T0, class T1, class T2, class T3, class T4, class T5, class T6 >

test/variant.t.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,18 @@ CASE( "variant: Allows to move-emplace elements from intializer-list based on in
760760
#endif
761761
}
762762

763-
CASE( "variant: Allows to swap variants (member)" )
763+
CASE( "variant: Allows to swap variants, same index (member)" )
764+
{
765+
variant<int, S> var1( 1 );
766+
variant<int, S> var2( 2 );
767+
768+
var1.swap( var2 );
769+
770+
EXPECT( get<int>( var1 ) == 2 );
771+
EXPECT( get<int>( var2 ) == 1 );
772+
}
773+
774+
CASE( "variant: Allows to swap variants, different index (member)" )
764775
{
765776
S s( 7 );
766777
variant<int, S> vari( 3 );
@@ -873,7 +884,18 @@ CASE( "variant: Allows to compare variants" )
873884
EXPECT_NOT( v >= w );
874885
}
875886

876-
CASE( "variant: Allows to swap variants (non-member)" )
887+
CASE( "variant: Allows to swap variants, same index (non-member)" )
888+
{
889+
variant<int, S> var1( 1 );
890+
variant<int, S> var2( 2 );
891+
892+
swap( var1, var2 );
893+
894+
EXPECT( get<int>( var1 ) == 2 );
895+
EXPECT( get<int>( var2 ) == 1 );
896+
}
897+
898+
CASE( "variant: Allows to swap variants, different index (non-member)" )
877899
{
878900
S s( 7 );
879901
variant<int, S> vari( 3 );

0 commit comments

Comments
 (0)