mirror of
https://github.com/boostorg/json.git
synced 2026-01-19 04:12:14 +00:00
rvalue ref overload for visit
This commit is contained in:
@@ -10,41 +10,9 @@
|
||||
#ifndef BOOST_JSON_IMPL_VISIT_HPP
|
||||
#define BOOST_JSON_IMPL_VISIT_HPP
|
||||
|
||||
#include <boost/type_traits/copy_cv_ref.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace json {
|
||||
namespace detail {
|
||||
|
||||
template<class Visitor, class Value>
|
||||
auto
|
||||
visit(
|
||||
Visitor&& v,
|
||||
Value&& jv) -> decltype(
|
||||
static_cast<Visitor&&>(v)(
|
||||
std::declval< copy_cv_ref_t<std::nullptr_t, Value&&> >() ) )
|
||||
{
|
||||
auto&& vis_ref = static_cast<Visitor&&>(v);
|
||||
auto&& arg_ref = static_cast<Value&&>(jv);
|
||||
switch(jv.kind())
|
||||
{
|
||||
default: // unreachable()?
|
||||
case kind::bool_: return vis_ref( arg_ref.get_bool() );
|
||||
case kind::int64: return vis_ref( arg_ref.get_int64() );
|
||||
case kind::uint64: return vis_ref( arg_ref.get_uint64() );
|
||||
case kind::double_: return vis_ref( arg_ref.get_double() );
|
||||
case kind::string: return vis_ref( arg_ref.get_string() );
|
||||
case kind::array: return vis_ref( arg_ref.get_array() );
|
||||
case kind::object: return vis_ref( arg_ref.get_object() );
|
||||
case kind::null: {
|
||||
std::nullptr_t np;
|
||||
using Ref = copy_cv_ref_t<std::nullptr_t, Value&&>;
|
||||
return vis_ref( static_cast<Ref>(np) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class Visitor>
|
||||
auto
|
||||
@@ -53,7 +21,21 @@ visit(
|
||||
value& jv) -> decltype(
|
||||
static_cast<Visitor&&>(v)( std::declval<std::nullptr_t&>() ) )
|
||||
{
|
||||
return detail::visit( static_cast<Visitor&&>(v), jv );
|
||||
switch(jv.kind())
|
||||
{
|
||||
default: // unreachable()?
|
||||
case kind::string: return static_cast<Visitor&&>(v)( jv.get_string() );
|
||||
case kind::array: return static_cast<Visitor&&>(v)( jv.get_array() );
|
||||
case kind::object: return static_cast<Visitor&&>(v)( jv.get_object() );
|
||||
case kind::bool_: return static_cast<Visitor&&>(v)( jv.get_bool() );
|
||||
case kind::int64: return static_cast<Visitor&&>(v)( jv.get_int64() );
|
||||
case kind::uint64: return static_cast<Visitor&&>(v)( jv.get_uint64() );
|
||||
case kind::double_: return static_cast<Visitor&&>(v)( jv.get_double() );
|
||||
case kind::null: {
|
||||
auto np = nullptr;
|
||||
return static_cast<Visitor&&>(v)(np) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Visitor>
|
||||
@@ -63,7 +45,43 @@ visit(
|
||||
value const& jv) -> decltype(
|
||||
static_cast<Visitor&&>(v)( std::declval<std::nullptr_t const&>() ) )
|
||||
{
|
||||
return detail::visit( static_cast<Visitor&&>(v), jv );
|
||||
switch(jv.kind())
|
||||
{
|
||||
default: // unreachable()?
|
||||
case kind::string: return static_cast<Visitor&&>(v)( jv.get_string() );
|
||||
case kind::array: return static_cast<Visitor&&>(v)( jv.get_array() );
|
||||
case kind::object: return static_cast<Visitor&&>(v)( jv.get_object() );
|
||||
case kind::bool_: return static_cast<Visitor&&>(v)( jv.get_bool() );
|
||||
case kind::int64: return static_cast<Visitor&&>(v)( jv.get_int64() );
|
||||
case kind::uint64: return static_cast<Visitor&&>(v)( jv.get_uint64() );
|
||||
case kind::double_: return static_cast<Visitor&&>(v)( jv.get_double() );
|
||||
case kind::null: {
|
||||
auto const np = nullptr;
|
||||
return static_cast<Visitor&&>(v)(np) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Visitor>
|
||||
auto
|
||||
visit(
|
||||
Visitor&& v,
|
||||
value&& jv) -> decltype(
|
||||
static_cast<Visitor&&>(v)( std::declval<std::nullptr_t&&>() ) )
|
||||
{
|
||||
switch(jv.kind())
|
||||
{
|
||||
default: // unreachable()?
|
||||
case kind::string: return static_cast<Visitor&&>(v)( std::move( jv.get_string() ) );
|
||||
case kind::array: return static_cast<Visitor&&>(v)( std::move( jv.get_array() ) );
|
||||
case kind::object: return static_cast<Visitor&&>(v)( std::move( jv.get_object() ) );
|
||||
case kind::bool_: return static_cast<Visitor&&>(v)( std::move( jv.get_bool() ) );
|
||||
case kind::int64: return static_cast<Visitor&&>(v)( std::move( jv.get_int64() ) );
|
||||
case kind::uint64: return static_cast<Visitor&&>(v)( std::move( jv.get_uint64() ) );
|
||||
case kind::double_: return static_cast<Visitor&&>(v)( std::move( jv.get_double() ) );
|
||||
case kind::null: return static_cast<Visitor&&>(v)( std::nullptr_t() ) ;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
|
||||
@@ -40,6 +40,13 @@ visit(
|
||||
Visitor &&v,
|
||||
value const &jv) -> decltype(
|
||||
static_cast<Visitor&&>(v)( std::declval<std::nullptr_t const&>() ) );
|
||||
|
||||
template<class Visitor>
|
||||
auto
|
||||
visit(
|
||||
Visitor &&v,
|
||||
value&& jv) -> decltype(
|
||||
static_cast<Visitor&&>(v)( std::declval<std::nullptr_t&&>() ) );
|
||||
/** @} */
|
||||
|
||||
} // namespace json
|
||||
|
||||
@@ -60,6 +60,50 @@ public:
|
||||
BOOST_TEST(visit(f{k}, v));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
check_rvalue(kind k, T t)
|
||||
{
|
||||
struct f
|
||||
{
|
||||
kind k;
|
||||
bool operator()(std::nullptr_t&&) && { return k == kind::null; }
|
||||
bool operator()(bool&&) && { return k == kind::bool_; }
|
||||
bool operator()(std::int64_t&&) && { return k == kind::int64; }
|
||||
bool operator()(std::uint64_t&&) && { return k == kind::uint64; }
|
||||
bool operator()(double&&) && { return k == kind::double_; }
|
||||
bool operator()(string&&) && { return k == kind::string; }
|
||||
bool operator()(array&&) && { return k == kind::array; }
|
||||
bool operator()(object&&) && { return k == kind::object; }
|
||||
bool operator()(...) && { return false; }
|
||||
};
|
||||
value v(t);
|
||||
f f_{k};
|
||||
BOOST_TEST(visit( std::move(f_), std::move(v) ));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void
|
||||
check_nonref(kind k, T t)
|
||||
{
|
||||
struct f
|
||||
{
|
||||
kind k;
|
||||
bool operator()(std::nullptr_t) && { return k == kind::null; }
|
||||
bool operator()(bool) && { return k == kind::bool_; }
|
||||
bool operator()(std::int64_t) && { return k == kind::int64; }
|
||||
bool operator()(std::uint64_t) && { return k == kind::uint64; }
|
||||
bool operator()(double) && { return k == kind::double_; }
|
||||
bool operator()(string) && { return k == kind::string; }
|
||||
bool operator()(array) && { return k == kind::array; }
|
||||
bool operator()(object) && { return k == kind::object; }
|
||||
bool operator()(...) && { return false; }
|
||||
};
|
||||
value v(t);
|
||||
f f_{k};
|
||||
BOOST_TEST(visit( std::move(f_), std::move(v) ));
|
||||
}
|
||||
|
||||
void
|
||||
testVisit()
|
||||
{
|
||||
@@ -80,6 +124,24 @@ public:
|
||||
check_mutable(kind::string, string_kind);
|
||||
check_mutable(kind::array, array_kind);
|
||||
check_mutable(kind::object, object_kind);
|
||||
|
||||
check_rvalue(kind::null, nullptr);
|
||||
check_rvalue(kind::bool_, true);
|
||||
check_rvalue(kind::int64, -1);
|
||||
check_rvalue(kind::uint64, 1U);
|
||||
check_rvalue(kind::double_, 3.14);
|
||||
check_rvalue(kind::string, string_kind);
|
||||
check_rvalue(kind::array, array_kind);
|
||||
check_rvalue(kind::object, object_kind);
|
||||
|
||||
check_nonref(kind::null, nullptr);
|
||||
check_nonref(kind::bool_, true);
|
||||
check_nonref(kind::int64, -1);
|
||||
check_nonref(kind::uint64, 1U);
|
||||
check_nonref(kind::double_, 3.14);
|
||||
check_nonref(kind::string, string_kind);
|
||||
check_nonref(kind::array, array_kind);
|
||||
check_nonref(kind::object, object_kind);
|
||||
}
|
||||
|
||||
void run()
|
||||
|
||||
Reference in New Issue
Block a user