FC Updates from BitShares and myself #21

Closed
nathanielhourt wants to merge 687 commits from dapp-support into latest-fc
5 changed files with 119 additions and 4 deletions
Showing only changes of commit bcdaaaa651 - Show all commits

View file

@ -87,6 +87,9 @@ void throw_bad_enum_cast( const char* k, const char* e );
visitor.TEMPLATE operator()<member_type,type,&type::elem>( BOOST_PP_STRINGIZE(elem) ); \
}
#define FC_REFLECT_VISIT_MEMBER_I( r, visitor, I, elem ) \
case I: FC_REFLECT_VISIT_MEMBER( r, visitor, elem ) break;
#define FC_REFLECT_BASE_MEMBER_COUNT( r, OP, elem ) \
OP fc::reflector<elem>::total_member_count
@ -99,6 +102,13 @@ template<typename Visitor>\
static inline void visit( const Visitor& v ) { \
BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_VISIT_BASE, v, INHERITS ) \
BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_VISIT_MEMBER, v, MEMBERS ) \
}\
template<typename Visitor, typename IndexType>\
static inline void visit_local_member( const Visitor& v, IndexType index ) { \
switch( index ) {\
BOOST_PP_SEQ_FOR_EACH_I( FC_REFLECT_VISIT_MEMBER_I, v, MEMBERS ) \
default: break;\
}\
}
#define FC_REFLECT_DERIVED_IMPL_EXT( TYPE, INHERITS, MEMBERS ) \

View file

@ -10,6 +10,8 @@
*
**/
#pragma once
#include <functional>
#include <stdexcept>
#include <typeinfo>
#include <fc/exception/exception.hpp>
@ -176,6 +178,36 @@ 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,22 +340,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<typename visitor>
static typename visitor::result_type visit( tag_type tag, visitor& v, void* data )
{
static auto wrappers = init_wrappers<visitor,void*,Types...>();
FC_ASSERT( tag >= 0 && 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, void* data )
{
static auto wrappers = init_wrappers<const visitor,void*,Types...>();
FC_ASSERT( tag >= 0 && 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 auto wrappers = init_const_wrappers<visitor,const void*,Types...>();
FC_ASSERT( tag >= 0 && 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 auto wrappers = init_const_wrappers<const visitor,const void*,Types...>();
FC_ASSERT( tag >= 0 && tag < count(), "Unsupported type ${tag}!", ("tag",tag) );
return wrappers[tag]( v, data );
}
static int count() { return impl::type_info<Types...>::count; }

View file

@ -92,6 +92,8 @@ namespace fc
void to_variant( const uint64_t& var, variant& vo, uint32_t max_depth = 1 );
void to_variant( const int64_t& var, variant& vo, uint32_t max_depth = 1 );
void to_variant( const bool& var, variant& vo, uint32_t max_depth = 1 );
void to_variant( const variant_object& var, variant& vo, uint32_t max_depth );
void from_variant( const variant& var, variant_object& vo, uint32_t max_depth );
void to_variant( const mutable_variant_object& var, variant& vo, uint32_t max_depth );

View file

@ -629,6 +629,7 @@ void from_variant( const variant& var, uint64_t& vo, uint32_t max_depth )
vo = var.as_uint64();
}
void to_variant( const bool& var, variant& vo, uint32_t max_depth ) { vo = uint64_t(var); }
void from_variant( const variant& var, bool& vo, uint32_t max_depth )
{
vo = var.as_bool();

View file

@ -1,9 +1,15 @@
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string.hpp>
#include <signal.h>
#include <fc/stacktrace.hpp>
#include <fc/static_variant.hpp>
#include <fc/thread/thread.hpp>
#include <iostream>
BOOST_AUTO_TEST_SUITE(fc_stacktrace)
BOOST_AUTO_TEST_CASE(stacktrace_test)
@ -40,6 +46,38 @@ BOOST_AUTO_TEST_CASE(threaded_stacktrace_test)
#endif
}
#if BOOST_VERSION / 100000 >= 1 && ((BOOST_VERSION / 100) % 1000) >= 65
class _svdt_visitor
{
public:
typedef std::string result_type;
std::string operator()( int64_t i )const
{
std::stringstream ss;
fc::print_stacktrace(ss);
return ss.str();
}
template<typename T>
std::string operator()( T i )const { return "Unexpected!"; }
};
BOOST_AUTO_TEST_CASE(static_variant_depth_test)
{
int64_t i = 1;
fc::static_variant<uint8_t,uint16_t,uint32_t,uint64_t,int8_t,int16_t,int32_t,int64_t> test(i);
std::string stacktrace = test.visit( _svdt_visitor() );
//std::cerr << stacktrace << "\n";
std::vector<std::string> lines;
boost::split( lines, stacktrace, boost::is_any_of("\n") );
int count = 0;
for( const auto& line : lines )
if( line.find("_svdt_visitor") != std::string::npos ) count++;
BOOST_CHECK_LT( 3, count ); // test.visit(), static_variant::visit, function object, visitor
BOOST_CHECK_GT( 8, count ); // some is implementation-dependent
}
#endif
/* this test causes a segfault on purpose to test the event handler
BOOST_AUTO_TEST_CASE(cause_segfault)
{