bug fixes

This commit is contained in:
Daniel Larimer 2015-02-27 16:07:50 -05:00
parent c0a4ed77b1
commit f9f965809b
3 changed files with 209 additions and 175 deletions

View file

@ -538,7 +538,7 @@ namespace fc {
pack_static_variant( Stream& s ):stream(s){}
typedef void result_type;
template<typename T> void operator()( const T& v )
template<typename T> void operator()( const T& v )const
{
pack( stream, v );
}
@ -551,7 +551,7 @@ namespace fc {
unpack_static_variant( Stream& s ):stream(s){}
typedef void result_type;
template<typename T> void operator()( T& v )
template<typename T> void operator()( T& v )const
{
unpack( stream, v );
}
@ -561,8 +561,8 @@ namespace fc {
template<typename Stream, typename... T>
void pack( Stream& s, const static_variant<T...>& sv )
{
pack( sv, unsigned_int(s.which()) );
s.visit( pack_static_variant<Stream>(sv) );
pack( s, unsigned_int(sv.which()) );
sv.visit( pack_static_variant<Stream>(s) );
}
template<typename Stream, typename... T> void unpack( Stream& s, static_variant<T...>& sv )

View file

@ -26,6 +26,18 @@ struct position;
template<typename... Ts>
struct type_info;
template<typename StaticVariant>
struct copy_construct
{
StaticVariant& sv;
copy_construct( StaticVariant& s ):sv(s){}
template<typename T>
void operator()( const T& v )const
{
sv.init(v);
}
};
template<int N, typename T, typename... Ts>
struct storage_ops<N, T&, Ts...> {
static void del(int n, void *data) {}
@ -162,17 +174,38 @@ class static_variant {
static_assert(impl::type_info<Types...>::no_reference_types, "Reference types are not permitted in static_variant.");
static_assert(impl::type_info<Types...>::no_duplicates, "static_variant type arguments contain duplicate types.");
int tag;
int _tag;
char storage[impl::type_info<Types...>::size];
static_variant() = delete;
template<typename X>
void init(const X& x) {
tag = impl::position<X, Types...>::pos;
_tag = impl::position<X, Types...>::pos;
new(storage) X(x);
}
template<typename StaticVariant>
friend struct copy_construct;
public:
template<typename X>
struct tag
{
static_assert(
impl::position<X, Types...>::pos != -1,
"Type not in static_variant."
);
static const int value = impl::position<X, Types...>::pos;
};
static_variant()
{
impl::storage_ops<0, Types...>::con(0, storage);
}
template<typename... Other>
static_variant( const static_variant<Other...>& cpy )
{
cpy.apply( impl::copy_construct<static_variant<Types...>>(*this) );
}
template<typename X>
static_variant(const X& v) {
static_assert(
@ -182,7 +215,7 @@ public:
init(v);
}
~static_variant() {
impl::storage_ops<0, Types...>::del(tag, storage);
impl::storage_ops<0, Types...>::del(_tag, storage);
}
template<typename X>
void operator=(const X& v) {
@ -199,7 +232,7 @@ public:
impl::position<X, Types...>::pos != -1,
"Type not in static_variant."
);
if(tag == impl::position<X, Types...>::pos) {
if(_tag == impl::position<X, Types...>::pos) {
return *reinterpret_cast<X*>(storage);
} else {
throw std::runtime_error(
@ -213,7 +246,7 @@ public:
impl::position<X, Types...>::pos != -1,
"Type not in static_variant."
);
if(tag == impl::position<X, Types...>::pos) {
if(_tag == impl::position<X, Types...>::pos) {
return *reinterpret_cast<const X*>(storage);
} else {
throw std::runtime_error(
@ -223,29 +256,30 @@ public:
}
template<typename visitor>
typename visitor::result_type visit(visitor& v) {
return impl::storage_ops<0, Types...>::apply(tag, storage, v);
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
}
template<typename visitor>
typename visitor::result_type visit(const visitor& v) {
return impl::storage_ops<0, Types...>::apply(tag, storage, v);
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
}
template<typename visitor>
typename visitor::result_type visit(visitor& v)const {
return impl::storage_ops<0, Types...>::apply(tag, storage, v);
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
}
template<typename visitor>
typename visitor::result_type visit(const visitor& v)const {
return impl::storage_ops<0, Types...>::apply(tag, storage, v);
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
}
void set_which( int w ) {
this->~static_variant();
impl::storage_ops<0, Types...>::con(tag, storage);
impl::storage_ops<0, Types...>::con(_tag, storage);
}
int which() const {return tag;}
int which() const {return _tag;}
};
template<typename Result>

View file

@ -508,7 +508,7 @@ namespace fc
from_static_variant( variant& dv ):var(dv){}
typedef void result_type;
template<typename T> void operator()( const T& v )
template<typename T> void operator()( const T& v )const
{
to_variant( v, var );
}
@ -520,7 +520,7 @@ namespace fc
to_static_variant( const variant& dv ):var(dv){}
typedef void result_type;
template<typename T> void operator()( T& v )
template<typename T> void operator()( T& v )const
{
to_variant( var, v );
}