Replaced visitors with constant-time implementations

This commit is contained in:
Peter Conrad 2018-10-09 17:55:34 +02:00
parent 72a8168b2b
commit b4da12643f

View file

@ -10,6 +10,8 @@
*
**/
#pragma once
#include <functional>
#include <stdexcept>
#include <typeinfo>
#include <fc/exception/exception.hpp>
@ -176,6 +178,34 @@ struct type_info<> {
} // namespace impl
template<typename Visitor,typename Data>
std::vector<std::function<typename Visitor::result_type(Visitor&,Data)>> init_wrappers()
{
return std::vector<std::function<typename Visitor::result_type(Visitor&,Data)>>();
}
template<typename Visitor,typename Data, typename T, typename ... Types>
std::vector<std::function<typename Visitor::result_type(Visitor&,Data)>> init_wrappers()
{
std::vector<std::function<typename Visitor::result_type(Visitor&,Data)>> result = init_wrappers<Visitor,Data,Types...>();
result.insert( result.begin(), [] ( Visitor& v, Data d ) { return v( *reinterpret_cast<T*>( d ) ); } );
return result;
}
template<typename Visitor,typename Data>
std::vector<std::function<typename Visitor::result_type(Visitor&,Data)>> init_const_wrappers()
{
return std::vector<std::function<typename Visitor::result_type(Visitor&,Data)>>();
}
template<typename Visitor,typename Data, typename T, typename ... Types>
std::vector<std::function<typename Visitor::result_type(Visitor&,Data)>> init_const_wrappers()
{
std::vector<std::function<typename Visitor::result_type(Visitor&,Data)>> result = init_const_wrappers<Visitor,Data,Types...>();
result.insert( result.begin(), [] ( Visitor& v, Data d ) { return v( *reinterpret_cast<const T*>( d ) ); } );
return result;
}
template<typename... Types>
class static_variant {
static_assert(impl::type_info<Types...>::no_reference_types, "Reference types are not permitted in static_variant.");
@ -308,32 +338,54 @@ public:
}
template<typename visitor>
typename visitor::result_type visit(visitor& v) {
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
return visit( _tag, v, (void*) storage );
}
template<typename visitor>
typename visitor::result_type visit(const visitor& v) {
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
return visit( _tag, v, (void*) storage );
}
template<typename visitor>
typename visitor::result_type visit(visitor& v)const {
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
return visit( _tag, v, (const void*) storage );
}
template<typename visitor>
typename visitor::result_type visit(const visitor& v)const {
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
return visit( _tag, v, (const void*) storage );
}
template<tag_type w, typename visitor>
static typename visitor::result_type visit(visitor& v) {
return impl::storage_ops<0, Types...>::apply((const tag_type)w, (const void*)nullptr, v);
template<typename visitor>
static typename visitor::result_type visit( tag_type tag, visitor& v, void* data )
{
static std::vector<std::function<typename visitor::result_type(visitor&,void*)>> wrappers = init_wrappers<visitor,void*,Types...>();
FC_ASSERT( tag < count(), "Unsupported type ${tag}!", ("tag",tag) );
return wrappers[tag]( v, data );
}
template<tag_type w, typename visitor>
static typename visitor::result_type visit(const visitor& v) {
return impl::storage_ops<0, Types...>::apply((const tag_type)w, (const void*)nullptr, v);
template<typename visitor>
static typename visitor::result_type visit( tag_type tag, const visitor& v, void* data )
{
static std::vector<std::function<typename visitor::result_type(const visitor&,void*)>> wrappers = init_wrappers<const visitor,void*,Types...>();
FC_ASSERT( tag < count(), "Unsupported type ${tag}!", ("tag",tag) );
return wrappers[tag]( v, data );
}
template<typename visitor>
static typename visitor::result_type visit( tag_type tag, visitor& v, const void* data )
{
static std::vector<std::function<typename visitor::result_type(visitor&,const void*)>> wrappers = init_const_wrappers<visitor,const void*,Types...>();
FC_ASSERT( tag < count(), "Unsupported type ${tag}!", ("tag",tag) );
return wrappers[tag]( v, data );
}
template<typename visitor>
static typename visitor::result_type visit( tag_type tag, const visitor& v, const void* data )
{
static std::vector<std::function<typename visitor::result_type(const visitor&,const void*)>> wrappers = init_const_wrappers<const visitor,const void*,Types...>();
FC_ASSERT( tag < count(), "Unsupported type ${tag}!", ("tag",tag) );
return wrappers[tag]( v, data );
}
static int count() { return impl::type_info<Types...>::count; }