Skip to content

Commit b07a034

Browse files
committed
fix references used in visit
1. Fix references in return type 2. Pass nullptr to the visitor with the same value category as the argument. This is done for uniformity.
1 parent ed3a618 commit b07a034

File tree

3 files changed

+47
-36
lines changed

3 files changed

+47
-36
lines changed

include/boost/json/impl/visit.hpp

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,49 +10,60 @@
1010
#ifndef BOOST_JSON_IMPL_VISIT_HPP
1111
#define BOOST_JSON_IMPL_VISIT_HPP
1212

13+
#include <boost/type_traits/copy_cv_ref.hpp>
14+
1315
namespace boost {
1416
namespace json {
17+
namespace detail {
1518

16-
template<class Visitor>
19+
template<class Visitor, class Value>
1720
auto
1821
visit(
1922
Visitor&& v,
20-
value& jv) -> decltype(
21-
std::declval<Visitor>()(nullptr))
23+
Value&& jv) -> decltype(
24+
static_cast<Visitor&&>(v)(
25+
std::declval< copy_cv_ref_t<std::nullptr_t, Value&&> >() ) )
2226
{
27+
auto&& vis_ref = static_cast<Visitor&&>(v);
28+
auto&& arg_ref = static_cast<Value&&>(jv);
2329
switch(jv.kind())
2430
{
2531
default: // unreachable()?
26-
case kind::null: return std::forward<Visitor>(v)(nullptr);
27-
case kind::bool_: return std::forward<Visitor>(v)(jv.get_bool());
28-
case kind::int64: return std::forward<Visitor>(v)(jv.get_int64());
29-
case kind::uint64: return std::forward<Visitor>(v)(jv.get_uint64());
30-
case kind::double_: return std::forward<Visitor>(v)(jv.get_double());
31-
case kind::string: return std::forward<Visitor>(v)(jv.get_string());
32-
case kind::array: return std::forward<Visitor>(v)(jv.get_array());
33-
case kind::object: return std::forward<Visitor>(v)(jv.get_object());
32+
case kind::bool_: return vis_ref( arg_ref.get_bool() );
33+
case kind::int64: return vis_ref( arg_ref.get_int64() );
34+
case kind::uint64: return vis_ref( arg_ref.get_uint64() );
35+
case kind::double_: return vis_ref( arg_ref.get_double() );
36+
case kind::string: return vis_ref( arg_ref.get_string() );
37+
case kind::array: return vis_ref( arg_ref.get_array() );
38+
case kind::object: return vis_ref( arg_ref.get_object() );
39+
case kind::null: {
40+
std::nullptr_t np;
41+
using Ref = copy_cv_ref_t<std::nullptr_t, Value&&>;
42+
return vis_ref( static_cast<Ref>(np) );
43+
}
3444
}
3545
}
3646

47+
} // namespace detail
48+
49+
template<class Visitor>
50+
auto
51+
visit(
52+
Visitor&& v,
53+
value& jv) -> decltype(
54+
static_cast<Visitor&&>(v)( std::declval<std::nullptr_t&>() ) )
55+
{
56+
return detail::visit( static_cast<Visitor&&>(v), jv );
57+
}
58+
3759
template<class Visitor>
3860
auto
3961
visit(
4062
Visitor&& v,
4163
value const& jv) -> decltype(
42-
std::declval<Visitor>()(nullptr))
64+
static_cast<Visitor&&>(v)( std::declval<std::nullptr_t const&>() ) )
4365
{
44-
switch (jv.kind())
45-
{
46-
default: // unreachable()?
47-
case kind::null: return std::forward<Visitor>(v)(nullptr);
48-
case kind::bool_: return std::forward<Visitor>(v)(jv.get_bool());
49-
case kind::int64: return std::forward<Visitor>(v)(jv.get_int64());
50-
case kind::uint64: return std::forward<Visitor>(v)(jv.get_uint64());
51-
case kind::double_: return std::forward<Visitor>(v)(jv.get_double());
52-
case kind::string: return std::forward<Visitor>(v)(jv.get_string());
53-
case kind::array: return std::forward<Visitor>(v)(jv.get_array());
54-
case kind::object: return std::forward<Visitor>(v)(jv.get_object());
55-
}
66+
return detail::visit( static_cast<Visitor&&>(v), jv );
5667
}
5768

5869
} // namespace json

include/boost/json/visit.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ auto
3232
visit(
3333
Visitor&& v,
3434
value& jv) -> decltype(
35-
std::declval<Visitor>()(nullptr));
35+
static_cast<Visitor&&>(v)( std::declval<std::nullptr_t&>() ) );
3636

3737
template<class Visitor>
3838
auto
3939
visit(
4040
Visitor &&v,
4141
value const &jv) -> decltype(
42-
std::declval<Visitor>()(nullptr));
42+
static_cast<Visitor&&>(v)( std::declval<std::nullptr_t const&>() ) );
4343
/** @} */
4444

4545
} // namespace json

test/visit.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ class visit_test
2525
struct f
2626
{
2727
kind k;
28-
bool operator()(std::nullptr_t) { return k == kind::null; }
29-
bool operator()(bool) { return k == kind::bool_; }
30-
bool operator()(std::int64_t) { return k == kind::int64; }
31-
bool operator()(std::uint64_t) { return k == kind::uint64; }
32-
bool operator()(double) { return k == kind::double_; }
33-
bool operator()(string const&) { return k == kind::string; }
34-
bool operator()(array const&) { return k == kind::array; }
35-
bool operator()(object const&) { return k == kind::object; }
36-
bool operator()(...) { return false; }
28+
bool operator()(std::nullptr_t const&) const { return k == kind::null; }
29+
bool operator()(bool const&) const { return k == kind::bool_; }
30+
bool operator()(std::int64_t const&) const { return k == kind::int64; }
31+
bool operator()(std::uint64_t const&) const { return k == kind::uint64; }
32+
bool operator()(double const&) const { return k == kind::double_; }
33+
bool operator()(string const&) const { return k == kind::string; }
34+
bool operator()(array const&) const { return k == kind::array; }
35+
bool operator()(object const&) const { return k == kind::object; }
36+
bool operator()(...) const { return false; }
3737
};
3838
value const v(t);
3939
BOOST_TEST(visit(f{k}, v));
@@ -46,7 +46,7 @@ class visit_test
4646
struct f
4747
{
4848
kind k;
49-
bool operator()(std::nullptr_t) { return k == kind::null; }
49+
bool operator()(std::nullptr_t&) { return k == kind::null; }
5050
bool operator()(bool&) { return k == kind::bool_; }
5151
bool operator()(std::int64_t&) { return k == kind::int64; }
5252
bool operator()(std::uint64_t&) { return k == kind::uint64; }

0 commit comments

Comments
 (0)