Skip to content

Commit 2883ff1

Browse files
committed
conversion of described classes supports private members
1 parent 8f5b635 commit 2883ff1

File tree

8 files changed

+71
-23
lines changed

8 files changed

+71
-23
lines changed

include/boost/json/conversion.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ struct is_null_like
302302
/** Determine if `T` should be treated as a described class
303303
304304
Described classes are serialised as objects with an element for each
305-
described public data member. A described class should not have described
305+
described data member. A described class should not have described
306306
bases or non-public members.<br>
307307
308308
Or more formally, given `L`, a class template
@@ -335,10 +335,10 @@ struct is_null_like
335335
@endcode
336336
337337
Users can also specialize the trait for their own types _with_ described
338-
bases to enable this conversion implementation. In this case the class will
339-
be serialized in a flattened way, that is members of bases will be
340-
serialized as direct elements of the object, and no nested objects will be
341-
created for bases.
338+
bases or described non-public data members to enable this conversion
339+
implementation. In this case the class will be serialized in a flattened
340+
way, that is members of bases will be serialized as direct elements of the
341+
object, and no nested objects will be created for bases.
342342
343343
@see <a href="https://www.boost.org/doc/libs/develop/libs/describe/doc/html/describe.html">Boost.Describe</a>.
344344
*/

include/boost/json/detail/parse_into.hpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -949,9 +949,7 @@ struct struct_element_list_impl
949949
template< class D >
950950
using helper = described_member_t<T, D>;
951951

952-
using type = mp11::mp_transform<
953-
helper,
954-
describe::describe_members<T, describe::mod_public> >;
952+
using type = mp11::mp_transform< helper, described_members<T> >;
955953
};
956954
template< class T >
957955
using struct_element_list = typename struct_element_list_impl<T>::type;
@@ -960,20 +958,17 @@ using struct_element_list = typename struct_element_list_impl<T>::type;
960958

961959
template< class T >
962960
using struct_element_list = mp11::mp_transform_q<
963-
mp11::mp_bind_front< described_member_t, T >,
964-
describe::describe_members<T, describe::mod_public> >;
961+
mp11::mp_bind_front< described_member_t, T >, described_members<T> >;
965962

966963
#endif
967964

968965
struct struct_accessor
969966
{
970967
template< class T, class I >
971968
auto operator()( T* t, I ) const
972-
-> described_member_t<T,
973-
mp11::mp_at<
974-
describe::describe_members<T, describe::mod_public>, I> >*
969+
-> described_member_t<T, mp11::mp_at< described_members<T>, I> >*
975970
{
976-
using Ds = describe::describe_members<T, describe::mod_public>;
971+
using Ds = described_members<T>;
977972
using D = mp11::mp_at<Ds, I>;
978973
return &(t->*D::pointer);
979974
}
@@ -1008,7 +1003,7 @@ class converting_handler<described_class_conversion_tag, V, P>
10081003

10091004
std::string key_;
10101005

1011-
using Dm = describe::describe_members<V, describe::mod_public>;
1006+
using Dm = described_members<V>;
10121007

10131008
handler_tuple< converting_handler, struct_element_list<V> > handlers_;
10141009
int inner_active_ = -1;

include/boost/json/detail/value_from.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,8 +155,7 @@ value_from_impl( no_conversion_tag, value&, T&&, Ctx const& )
155155
template< class Ctx, class T >
156156
struct from_described_member
157157
{
158-
using Ds = describe::describe_members<
159-
remove_cvref<T>, describe::mod_public | describe::mod_inherited>;
158+
using Ds = described_members< remove_cvref<T> >;
160159

161160
object& obj;
162161
Ctx const& ctx;

include/boost/json/detail/value_to.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,7 @@ value_to_impl(
342342
template< class Ctx, class T, bool non_throwing = true >
343343
struct to_described_member
344344
{
345-
using Ds = describe::describe_members<
346-
T, describe::mod_public | describe::mod_inherited>;
345+
using Ds = described_members<T>;
347346

348347
using result_type = mp11::mp_eval_if_c<
349348
!non_throwing, T, system::result, T>;

include/boost/json/impl/conversion.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ using described_member_t = remove_cvref<decltype(
297297

298298
#endif
299299

300+
template< class T >
301+
using described_members = describe::describe_members<
302+
T, describe::mod_any_access | describe::mod_inherited>;
303+
300304
// user conversion (via tag_invoke)
301305
template< class Ctx, class T, class Dir >
302306
using user_conversion_category = mp11::mp_cond<

test/parse_into.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,37 @@ bool operator==( Y const& y1, Y const& y2 )
5252
return y1.v == y2.v && y1.m == y2.m;
5353
}
5454

55+
struct Z : X
56+
{
57+
Z() = default;
58+
Z(X x, bool b) : X(x), d(b)
59+
{}
60+
61+
private:
62+
bool d = false;
63+
64+
friend
65+
bool operator==( Z const& z1, Z const& z2 )
66+
{
67+
X const& x1 = z1;
68+
X const& x2 = z2;
69+
return (x1 == x2) && z1.d == z2.d;
70+
}
71+
72+
BOOST_DESCRIBE_CLASS(Z, (X), (), (), (d))
73+
};
74+
75+
5576
BOOST_DEFINE_ENUM_CLASS(E, x, y, z)
5677

5778
namespace boost {
5879
namespace json {
5980

81+
template<>
82+
struct is_described_class<Z>
83+
: std::true_type
84+
{ };
85+
6086
class parse_into_test
6187
{
6288
public:
@@ -340,6 +366,9 @@ class parse_into_test
340366
testParseInto<Y>( {} );
341367
testParseInto<Y>( { { { 1, 1.0f, "one" }, { 2, 2.0f, "two" } }, { { "one", { 1, 1.1f, "1" } }, { "two", { 2, 2.2f, "2" } } } } );
342368

369+
testParseInto<Z>( {} );
370+
testParseInto<Z>( { {1, 3.14f, "hello"}, true } );
371+
343372
testParseIntoErrors<X>( error::not_object, 1 );
344373
testParseIntoErrors<X>(
345374
error::unknown_name,

test/value_from.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,18 @@ BOOST_DESCRIBE_STRUCT(T10, (), (n, d))
183183
struct T11 : T10
184184
{
185185
std::string s;
186+
187+
void
188+
set_b(bool v)
189+
{
190+
b = v;
191+
}
192+
193+
private:
194+
bool b;
195+
196+
BOOST_DESCRIBE_CLASS(T11, (T10), (s), (), (b))
186197
};
187-
BOOST_DESCRIBE_STRUCT(T11, (T10), (s))
188198

189199
//----------------------------------------------------------
190200

@@ -488,8 +498,9 @@ class value_from_test
488498
t11.n = 67;
489499
t11.d = -.12;
490500
t11.s = "qwerty";
501+
t11.set_b(true);
491502
jv = value_from( t11, ctx... );
492-
BOOST_TEST(( jv == value{{"n", 67}, {"d", -.12}, {"s", "qwerty"}} ));
503+
BOOST_TEST(( jv == value{{"n", 67}, {"d", -.12}, {"s", "qwerty"}, {"b", true}} ));
493504

494505
::value_from_test_ns::E1 e1 = ::value_from_test_ns::E1::a;
495506
BOOST_TEST( value_from( e1, ctx... ) == "a" );

test/value_to.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,18 @@ BOOST_DESCRIBE_STRUCT(T6, (), (n, d))
119119
struct T7 : T6
120120
{
121121
std::string s;
122+
123+
bool
124+
get_b() const
125+
{
126+
return b;
127+
}
128+
129+
private:
130+
bool b = false;
131+
132+
BOOST_DESCRIBE_CLASS(T7, (T6), (s), (), (b))
122133
};
123-
BOOST_DESCRIBE_STRUCT(T7, (T6), (s))
124134

125135
//----------------------------------------------------------
126136

@@ -425,13 +435,14 @@ class value_to_test
425435
value_to<::value_to_test_ns::T6>( jv ));
426436
}
427437
{
428-
value jv = {{"n", 1}, {"d", 2}, {"s", "xyz"}};
438+
value jv = {{"n", 1}, {"d", 2}, {"s", "xyz"}, {"b", true}};
429439
auto res = try_value_to<::value_to_test_ns::T7>(
430440
jv, ctx... );
431441
BOOST_TEST( res );
432442
BOOST_TEST( res->n == 1 );
433443
BOOST_TEST( res->d == 2 );
434444
BOOST_TEST( res->s == "xyz" );
445+
BOOST_TEST( res->get_b() == true );
435446
}
436447

437448
BOOST_TEST_THROWS_WITH_LOCATION(

0 commit comments

Comments
 (0)