void to_stream( T& os, const variant& v, json::output_formatting format ) { switch( v.get_type() ) { case variant::null_type: os << "null"; return; case variant::int64_type: { int64_t i = v.as_int64(); if( format == json::stringify_large_ints_and_doubles && i > 0xffffffff ) os << '"'<<v.as_string()<<'"'; else os << i; return; } case variant::uint64_type: { uint64_t i = v.as_uint64(); if( format == json::stringify_large_ints_and_doubles && i > 0xffffffff ) os << '"'<<v.as_string()<<'"'; else os << i; return; } case variant::double_type: if (format == json::stringify_large_ints_and_doubles) os << '"'<<v.as_string()<<'"'; else os << v.as_string(); return; case variant::bool_type: os << v.as_string(); return; case variant::string_type: escape_string( v.get_string(), os ); return; case variant::blob_type: escape_string( v.as_string(), os ); return; case variant::array_type: { const variants& a = v.get_array(); to_stream( os, a, format ); return; } case variant::object_type: { const variant_object& o = v.get_object(); to_stream(os, o, format ); return; } } }
void to_stream( T& os, const variant& v, json::output_formatting format, uint32_t max_depth ) { FC_ASSERT( max_depth > 0, "Too many nested objects!" ); switch( v.get_type() ) { case variant::null_type: os << "null"; return; case variant::int64_type: if( format == json::stringify_large_ints_and_doubles && ( v.as_int64() > INT32_MAX || v.as_int64() < INT32_MIN ) ) os << '"'<<v.as_string()<<'"'; else os << v.as_int64(); return; case variant::uint64_type: if( format == json::stringify_large_ints_and_doubles && v.as_uint64() > 0xffffffff ) os << '"'<<v.as_string()<<'"'; else os << v.as_uint64(); return; case variant::double_type: if (format == json::stringify_large_ints_and_doubles) os << '"'<<v.as_string()<<'"'; else os << v.as_string(); return; case variant::bool_type: os << v.as_string(); return; case variant::string_type: escape_string( v.get_string(), os ); return; case variant::blob_type: escape_string( v.as_string(), os ); return; case variant::array_type: to_stream( os, v.get_array(), format, max_depth - 1 ); return; case variant::object_type: to_stream(os, v.get_object(), format, max_depth - 1 ); return; default: FC_THROW_EXCEPTION( fc::invalid_arg_exception, "Unsupported variant type: ${type}", ( "type", v.get_type() ) ); } }
variant::variant( const variant& v ) { switch( v.get_type() ) { case object_type: *reinterpret_cast<variant_object**>(this) = new variant_object(**reinterpret_cast<const const_variant_object_ptr*>(&v)); set_variant_type( this, object_type ); return; case array_type: *reinterpret_cast<variants**>(this) = new variants(**reinterpret_cast<const const_variants_ptr*>(&v)); set_variant_type( this, array_type ); return; case string_type: *reinterpret_cast<string**>(this) = new string(**reinterpret_cast<const const_string_ptr*>(&v) ); set_variant_type( this, string_type ); return; default: memcpy( this, &v, sizeof(v) ); } }
//////////////////////////////////////////////////////////////////////////////////////// TEST_CASE("constructor - invoke general", "[constructor]") { type t = type::get<ctor_invoke_test>(); REQUIRE(t.is_valid() == true); SECTION("invoke default ctor") { constructor ctor = t.get_constructor(); REQUIRE(ctor.is_valid() == true); variant var = ctor.invoke(); CHECK(var.is_valid() == true); CHECK(var.get_type() == type::get<ctor_invoke_test*>()); ctor_invoke_test* obj = var.get_value<ctor_invoke_test*>(); CHECK(obj->default_ctor_invoked == true); CHECK(t.get_destructor().invoke(var) == true); } SECTION("invoke copy-ctor") { constructor ctor = t.get_constructor({type::get<ctor_invoke_test>()}); REQUIRE(ctor.is_valid() == true); variant var = ctor.invoke(12); CHECK(var.is_valid() == false); ctor_invoke_test obj_default; var = ctor.invoke(obj_default);
inline void pack( Stream& s, const variant& v ) { pack( s, uint8_t(v.get_type()) ); v.visit( variant_packer<Stream>(s) ); }