FC Updates from BitShares and myself #21

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

View file

@ -358,17 +358,21 @@ namespace fc {
const uint32_t max_depth;
};
// Default pack/unpack functions for classes (if_class<fc::true_type>) are removed due to recursion issue.
// Default pack/unpack functions for classes are removed due to recursion issue.
// Classes should implement pack/unpack functions explicitly.
template<typename IsClass=fc::true_type>
template<typename T, typename Dummy = void>
struct if_class;
template<>
struct if_class<fc::false_type> {
template<typename Stream, typename T>
template<typename T>
struct if_class<T, std::enable_if_t<!std::is_class<T>::value>> {
template<typename Stream>
static inline void pack( Stream& s, const T v, uint32_t _max_depth ) = delete;
template<typename Stream, typename T>
template<typename Stream>
static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) = delete;
};
template<>
struct if_class<int64_t, void> {
template<typename Stream>
static inline void pack( Stream& s, const int64_t v, uint32_t _max_depth ) {
boost::endian::little_int64_buf_t tmp;
@ -381,6 +385,10 @@ namespace fc {
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
};
template<>
struct if_class<uint64_t, void> {
template<typename Stream>
static inline void pack( Stream& s, const uint64_t v, uint32_t _max_depth ) {
boost::endian::little_uint64_buf_t tmp;
@ -393,6 +401,10 @@ namespace fc {
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
};
template<>
struct if_class<int32_t, void> {
template<typename Stream>
static inline void pack( Stream& s, const int32_t v, uint32_t _max_depth ) {
boost::endian::little_int32_buf_t tmp;
@ -405,6 +417,10 @@ namespace fc {
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
};
template<>
struct if_class<uint32_t, void> {
template<typename Stream>
static inline void pack( Stream& s, const uint32_t v, uint32_t _max_depth ) {
boost::endian::little_uint32_buf_t tmp;
@ -417,6 +433,10 @@ namespace fc {
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
};
template<>
struct if_class<int16_t, void> {
template<typename Stream>
static inline void pack( Stream& s, const int16_t v, uint32_t _max_depth ) {
boost::endian::little_int16_buf_t tmp;
@ -429,6 +449,10 @@ namespace fc {
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
};
template<>
struct if_class<uint16_t, void> {
template<typename Stream>
static inline void pack( Stream& s, const uint16_t v, uint32_t _max_depth ) {
boost::endian::little_uint16_buf_t tmp;
@ -441,6 +465,10 @@ namespace fc {
s.read( (char*)&tmp, sizeof(tmp) );
v = tmp.value();
}
};
template<>
struct if_class<int8_t, void> {
template<typename Stream>
static inline void pack( Stream& s, const int8_t v, uint32_t _max_depth ) {
s.write( (char*)&v, 1 );
@ -449,6 +477,10 @@ namespace fc {
static inline void unpack( Stream& s, int8_t& v, uint32_t _max_depth ) {
s.read( (char*)&v, 1 );
}
};
template<>
struct if_class<uint8_t, void> {
template<typename Stream>
static inline void pack( Stream& s, const uint8_t v, uint32_t _max_depth ) {
s.write( (char*)&v, 1 );
@ -459,27 +491,29 @@ namespace fc {
}
};
template<typename IsEnum=fc::false_type>
struct if_enum {
template<typename Stream, typename T>
template<typename T, typename Dummy=void>
struct if_enum;
template<typename T>
struct if_enum<T, std::enable_if_t<!std::is_enum<T>::value>> {
template<typename Stream>
static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
fc::reflector<T>::visit( pack_object_visitor<Stream,T>( v, s, _max_depth - 1 ) );
}
template<typename Stream, typename T>
template<typename Stream>
static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
fc::reflector<T>::visit( unpack_object_visitor<Stream,T>( v, s, _max_depth - 1 ) );
}
};
template<>
struct if_enum<fc::true_type> {
template<typename Stream, typename T>
template<typename T>
struct if_enum<T, std::enable_if_t<std::is_enum<T>::value>> {
template<typename Stream>
static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
fc::raw::pack( s, (int64_t)v, _max_depth - 1 );
}
template<typename Stream, typename T>
template<typename Stream>
static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
int64_t temp;
@ -488,30 +522,30 @@ namespace fc {
}
};
template<typename IsReflected=fc::false_type>
template<typename IsReflected=std::false_type>
struct if_reflected {
template<typename Stream, typename T>
static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
if_class<typename fc::is_class<T>::type>::pack( s, v, _max_depth - 1 );
if_class<T>::pack( s, v, _max_depth - 1 );
}
template<typename Stream, typename T>
static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
if_class<typename fc::is_class<T>::type>::unpack( s, v, _max_depth - 1 );
if_class<T>::unpack( s, v, _max_depth - 1 );
}
};
template<>
struct if_reflected<fc::true_type> {
struct if_reflected<std::true_type> {
template<typename Stream, typename T>
static inline void pack( Stream& s, const T& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
if_enum< typename fc::reflector<T>::is_enum >::pack( s, v, _max_depth - 1 );
if_enum<T>::pack( s, v, _max_depth - 1 );
}
template<typename Stream, typename T>
static inline void unpack( Stream& s, T& v, uint32_t _max_depth ) {
FC_ASSERT( _max_depth > 0 );
if_enum< typename fc::reflector<T>::is_enum >::unpack( s, v, _max_depth - 1 );
if_enum<T>::unpack( s, v, _max_depth - 1 );
}
};

View file

@ -7,7 +7,6 @@
*/
#include <fc/string.hpp>
#include <fc/utility.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/enum.hpp>
@ -16,6 +15,7 @@
#include <boost/preprocessor/stringize.hpp>
#include <stdint.h>
#include <string.h>
#include <type_traits>
#include <fc/reflect/typename.hpp>
@ -33,8 +33,7 @@ namespace fc {
template<typename T>
struct reflector{
typedef T type;
typedef fc::false_type is_defined;
typedef fc::false_type is_enum;
typedef std::false_type is_defined;
/**
* @tparam Visitor a function object of the form:
@ -137,8 +136,7 @@ void fc::reflector<TYPE>::visit( const Visitor& v ) { \
#define FC_REFLECT_ENUM( ENUM, FIELDS ) \
namespace fc { \
template<> struct reflector<ENUM> { \
typedef fc::true_type is_defined; \
typedef fc::true_type is_enum; \
typedef std::true_type is_defined; \
static const char* to_string(ENUM elem) { \
switch( elem ) { \
BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_ENUM_TO_STRING, ENUM, FIELDS ) \
@ -215,8 +213,7 @@ namespace fc { \
template<> struct get_typename<TYPE> { static const char* name() { return BOOST_PP_STRINGIZE(TYPE); } }; \
template<> struct reflector<TYPE> {\
typedef TYPE type; \
typedef fc::true_type is_defined; \
typedef fc::false_type is_enum; \
typedef std::true_type is_defined; \
enum member_count_enum { \
local_member_count = 0 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_MEMBER_COUNT, +, MEMBERS ),\
total_member_count = local_member_count BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_BASE_MEMBER_COUNT, +, INHERITS )\
@ -228,8 +225,7 @@ namespace fc { \
template<BOOST_PP_SEQ_ENUM(TEMPLATE_ARGS)> struct get_typename<TYPE> { static const char* name() { return BOOST_PP_STRINGIZE(TYPE); } }; \
template<BOOST_PP_SEQ_ENUM(TEMPLATE_ARGS)> struct reflector<TYPE> {\
typedef TYPE type; \
typedef fc::true_type is_defined; \
typedef fc::false_type is_enum; \
typedef std::true_type is_defined; \
enum member_count_enum { \
local_member_count = 0 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_MEMBER_COUNT, +, MEMBERS ),\
total_member_count = local_member_count BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_BASE_MEMBER_COUNT, +, INHERITS )\
@ -266,7 +262,7 @@ namespace fc { \
template<> struct get_typename<TYPE> { static const char* name() { return BOOST_PP_STRINGIZE(TYPE); } }; \
template<> struct reflector<TYPE> {\
typedef TYPE type; \
typedef fc::true_type is_defined; \
typedef std::true_type is_defined; \
enum member_count_enum { \
local_member_count = BOOST_PP_SEQ_SIZE(MEMBERS), \
total_member_count = local_member_count BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_BASE_MEMBER_COUNT, +, INHERITS )\

View file

@ -63,17 +63,17 @@ namespace fc
const uint32_t _max_depth;
};
template<typename IsEnum=fc::false_type>
struct if_enum
template<typename T, typename Dummy = void>
struct if_enum;
template<typename T>
struct if_enum<T, std::enable_if_t<!std::is_enum<T>::value>>
{
template<typename T>
static inline void to_variant( const T& v, fc::variant& vo, uint32_t max_depth )
{
mutable_variant_object mvo;
fc::reflector<T>::visit( to_variant_visitor<T>( mvo, v, max_depth ) );
vo = std::move(mvo);
}
template<typename T>
static inline void from_variant( const fc::variant& v, T& o, uint32_t max_depth )
{
const variant_object& vo = v.get_object();
@ -81,15 +81,13 @@ namespace fc
}
};
template<>
struct if_enum<fc::true_type>
template<typename T>
struct if_enum<T, std::enable_if_t<std::is_enum<T>::value>>
{
template<typename T>
static inline void to_variant( const T& o, fc::variant& v, uint32_t max_depth = 1 )
{
v = fc::reflector<T>::to_fc_string(o);
}
template<typename T>
static inline void from_variant( const fc::variant& v, T& o, uint32_t max_depth = 1 )
{
if( v.is_string() )
@ -103,12 +101,12 @@ namespace fc
template<typename T>
void to_variant( const T& o, variant& v, uint32_t max_depth )
{
if_enum<typename fc::reflector<T>::is_enum>::to_variant( o, v, max_depth );
if_enum<T>::to_variant( o, v, max_depth );
}
template<typename T>
void from_variant( const variant& v, T& o, uint32_t max_depth )
{
if_enum<typename fc::reflector<T>::is_enum>::from_variant( v, o, max_depth );
if_enum<T>::from_variant( v, o, max_depth );
}
}

View file

@ -1,18 +0,0 @@
#pragma once
#include <stdint.h>
#include <cstdlib>
namespace fc {
using std::size_t;
struct true_type { enum _value { value = 1 }; };
struct false_type { enum _value { value = 0 }; };
namespace detail {
template<typename T> fc::true_type is_class_helper(void(T::*)());
template<typename T> fc::false_type is_class_helper(...);
}
template<typename T>
struct is_class { typedef decltype(detail::is_class_helper<T>(0)) type; enum value_enum { value = type::value }; };
}