#pragma once #include #include #include #include #include #include namespace fc { namespace detail { template struct cast_visitor : value::const_visitor { cast_visitor( T& out ) :m_out(out){} virtual void operator()( const int8_t& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const int16_t& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const int32_t& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const int64_t& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const uint8_t& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const uint16_t& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const uint32_t& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const uint64_t& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const float& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const double& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const bool& v ){ m_out = fc::numeric_cast(v); } virtual void operator()( const fc::string& v ) { m_out = fc::lexical_cast(v); } virtual void operator()( const value::object& ) { FC_THROW_MSG("bad cast"); } virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast"); } virtual void operator()( ) { FC_THROW_MSG("bad cast"); } private: T& m_out; }; template<> struct cast_visitor : value::const_visitor { cast_visitor( fc::string& out ) :m_out(out){} virtual void operator()( const int8_t& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const int16_t& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const int32_t& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const int64_t& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const uint8_t& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const uint16_t& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const uint32_t& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const uint64_t& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const float& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const double& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const bool& v ){ m_out = fc::lexical_cast(v); } virtual void operator()( const fc::string& v ){ m_out = v; } virtual void operator()( const value::object& ) { FC_THROW_MSG("bad cast"); } virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast"); } virtual void operator()( ) { FC_THROW_MSG("bad cast"); } private: fc::string& m_out; }; template<> struct cast_visitor : value::const_visitor { cast_visitor( value::array& out ) :m_out(out){} virtual void operator()( const int8_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const int16_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const int32_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const int64_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const uint8_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const uint16_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const uint32_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const uint64_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const float& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const double& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const bool& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const fc::string& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const value::object& ) { FC_THROW_MSG("bad cast");} virtual void operator()( const value::array& a ) { m_out = a; } virtual void operator()( ) { FC_THROW_MSG("bad cast");} private: value::array& m_out; }; template<> struct cast_visitor : value::const_visitor { cast_visitor( value::object& out ) :m_out(out){} virtual void operator()( const int8_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const int16_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const int32_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const int64_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const uint8_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const uint16_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const uint32_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const uint64_t& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const float& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const double& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const bool& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const fc::string& v ){ FC_THROW_MSG("bad cast");} virtual void operator()( const value::object& a ) { m_out = a; } virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast");} virtual void operator()( ) { FC_THROW_MSG("bad cast");} private: value::object& m_out; }; template<> struct cast_visitor : value::value::const_visitor { virtual void operator()( const int8_t& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const int16_t& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const int32_t& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const int64_t& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const uint8_t& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const uint16_t& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const uint32_t& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const uint64_t& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const float& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const double& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const bool& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const fc::string& v ) { FC_THROW_MSG("bad cast");} virtual void operator()( const value::object& a ) { FC_THROW_MSG("bad cast");} virtual void operator()( const value::array& ) { FC_THROW_MSG("bad cast");} virtual void operator()( ) { } }; template struct cast_if_reflected { template static T cast( const value& v ) { T out; v.visit(cast_visitor(out)); return out; } }; template<> struct cast_if_reflected { template static T cast( const value& v ) { T tmp; unpack(v,tmp); return tmp; } }; class value_visitor; struct value_holder { virtual ~value_holder(); virtual const char* type()const; virtual void visit( value::const_visitor&& v )const; virtual void visit( value_visitor&& v ); virtual void clear(); virtual size_t size()const; virtual void resize( size_t ); virtual void reserve( size_t ); virtual value& at( size_t ); virtual const value& at( size_t )const; virtual void push_back( value&& v ); virtual value_holder* move_helper( char* c ); virtual value_holder* copy_helper( char* c )const; }; } // namespace detail /** * Convert from value v to T * * Performs the following conversions * true -> 1.0, 1, "true" * * Not all casts are 'clean', the following conversions * could cause errors: * * signed int -> unsigned * large int -> smaller int * real -> int * non-numeric string -> number * object -> string or number * array -> string or number * number,string,array -> object */ template T value_cast( const value& v ) { return detail::cast_if_reflected::is_defined>::template cast(v); } template value::value( T&& v ) { new (holder) detail::value_holder(); fc::pack( *this, std::forward(v) ); } }