Replaced visitors with constant-time implementations
This commit is contained in:
parent
72a8168b2b
commit
b4da12643f
1 changed files with 62 additions and 10 deletions
|
|
@ -10,6 +10,8 @@
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
#include <fc/exception/exception.hpp>
|
#include <fc/exception/exception.hpp>
|
||||||
|
|
@ -176,6 +178,34 @@ struct type_info<> {
|
||||||
|
|
||||||
} // namespace impl
|
} // 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>
|
template<typename... Types>
|
||||||
class static_variant {
|
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_reference_types, "Reference types are not permitted in static_variant.");
|
||||||
|
|
@ -308,32 +338,54 @@ public:
|
||||||
}
|
}
|
||||||
template<typename visitor>
|
template<typename visitor>
|
||||||
typename visitor::result_type visit(visitor& v) {
|
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>
|
template<typename visitor>
|
||||||
typename visitor::result_type visit(const visitor& v) {
|
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>
|
template<typename visitor>
|
||||||
typename visitor::result_type visit(visitor& v)const {
|
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>
|
template<typename visitor>
|
||||||
typename visitor::result_type visit(const visitor& v)const {
|
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>
|
template<typename visitor>
|
||||||
static typename visitor::result_type visit(visitor& v) {
|
static typename visitor::result_type visit( tag_type tag, visitor& v, void* data )
|
||||||
return impl::storage_ops<0, Types...>::apply((const tag_type)w, (const void*)nullptr, v);
|
{
|
||||||
|
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>
|
template<typename visitor>
|
||||||
static typename visitor::result_type visit(const visitor& v) {
|
static typename visitor::result_type visit( tag_type tag, const visitor& v, void* data )
|
||||||
return impl::storage_ops<0, Types...>::apply((const tag_type)w, (const void*)nullptr, v);
|
{
|
||||||
|
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; }
|
static int count() { return impl::type_info<Types...>::count; }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue