impl/visit.hpp

100.0% Lines (44/44) 100.0% Functions (3/3)
impl/visit.hpp
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/json
8 //
9
10 #ifndef BOOST_JSON_IMPL_VISIT_HPP
11 #define BOOST_JSON_IMPL_VISIT_HPP
12
13 namespace boost {
14 namespace json {
15
16 namespace detail {
17
18 extern
19 BOOST_JSON_DECL
20 std::nullptr_t stable_np;
21
22 } // namespace detail
23
24 template<class Visitor>
25 auto
26 16 visit(
27 Visitor&& v,
28 value& jv) -> decltype(
29 static_cast<Visitor&&>(v)( std::declval<std::nullptr_t&>() ) )
30 {
31 16 switch(jv.kind())
32 {
33 2 default: // unreachable()?
34 2 case kind::string: return static_cast<Visitor&&>(v)( jv.get_string() );
35 2 case kind::array: return static_cast<Visitor&&>(v)( jv.get_array() );
36 2 case kind::object: return static_cast<Visitor&&>(v)( jv.get_object() );
37 2 case kind::bool_: return static_cast<Visitor&&>(v)( jv.get_bool() );
38 2 case kind::int64: return static_cast<Visitor&&>(v)( jv.get_int64() );
39 2 case kind::uint64: return static_cast<Visitor&&>(v)( jv.get_uint64() );
40 2 case kind::double_: return static_cast<Visitor&&>(v)( jv.get_double() );
41 2 case kind::null: return static_cast<Visitor&&>(v)( detail::stable_np ) ;
42 }
43 }
44
45 template<class Visitor>
46 auto
47 264 visit(
48 Visitor&& v,
49 value const& jv) -> decltype(
50 static_cast<Visitor&&>(v)( std::declval<std::nullptr_t const&>() ) )
51 {
52 264 detail::scalar const& sc = detail::access::get_scalar(jv);
53 264 switch(jv.kind())
54 {
55 46 default: // unreachable()?
56 46 case kind::string: return static_cast<Visitor&&>(v)( jv.get_string() );
57 12 case kind::array: return static_cast<Visitor&&>(v)( jv.get_array() );
58 22 case kind::object: return static_cast<Visitor&&>(v)( jv.get_object() );
59 // local variables work around a bug in older clangs
60 30 case kind::bool_: {
61 30 bool const& b = sc.b;
62 30 return static_cast<Visitor&&>(v)(b);
63 }
64 92 case kind::int64: {
65 92 std::int64_t const& i = sc.i;
66 92 return static_cast<Visitor&&>(v)(i);
67 }
68 18 case kind::uint64: {
69 18 std::uint64_t const& u = sc.u;
70 18 return static_cast<Visitor&&>(v)(u);
71 }
72 10 case kind::double_: {
73 10 double const& d = sc.d;
74 10 return static_cast<Visitor&&>(v)(d);
75 }
76 34 case kind::null: {
77 34 auto const& np = detail::stable_np;
78 34 return static_cast<Visitor&&>(v)(np) ;
79 }
80 }
81 }
82
83
84 template<class Visitor>
85 auto
86 24 visit(
87 Visitor&& v,
88 value&& jv) -> decltype(
89 static_cast<Visitor&&>(v)( std::declval<std::nullptr_t&&>() ) )
90 {
91 24 switch(jv.kind())
92 {
93 3 default: // unreachable()?
94 3 case kind::string: return static_cast<Visitor&&>(v)(std::move( jv.get_string() ));
95 3 case kind::array: return static_cast<Visitor&&>(v)(std::move( jv.get_array() ));
96 3 case kind::object: return static_cast<Visitor&&>(v)(std::move( jv.get_object() ));
97 3 case kind::bool_: return static_cast<Visitor&&>(v)(std::move( detail::access::get_scalar(jv).b ));
98 3 case kind::int64: return static_cast<Visitor&&>(v)(std::move( detail::access::get_scalar(jv).i ));
99 3 case kind::uint64: return static_cast<Visitor&&>(v)(std::move( detail::access::get_scalar(jv).u ));
100 3 case kind::double_: return static_cast<Visitor&&>(v)(std::move( detail::access::get_scalar(jv).d ));
101 3 case kind::null: return static_cast<Visitor&&>(v)(std::move( detail::stable_np )) ;
102 }
103 }
104
105 } // namespace json
106 } // namespace boost
107
108 #endif
109