In the documentation of Boost Describe, there is an example for automatic conversion of a struct to JSON (https://www.boost.org/doc/libs/1_78_0/libs/describe/doc/html/describe.html#example_to_json). However, when adding a pointer as a member of the struct, the code example does not work. I guess that the tag_invoke function needs to be modified in order to handle the pointer.
I tried the following, based on the example:
#include <boost/describe.hpp>
#include <boost/json.hpp>
#include <boost/mp11.hpp>
#include <fstream>
#include <iostream>
#include <map>
#include <type_traits>
#include <vector>
namespace app{
template <
class T,
class D1 = boost::describe::describe_members<
T, boost::describe::mod_public | boost::describe::mod_protected>, //
class D2 =
boost::describe::describe_members<T, boost::describe::mod_private>, //
class En = std::enable_if_t<boost::mp11::mp_empty<D2>::value &&
!std::is_union<T>::value> //
>
void tag_invoke(boost::json::value_from_tag const &, boost::json::value &v,
T const &t) {
auto &obj = v.emplace_object();
boost::mp11::mp_for_each<D1>(
[&](auto D) { obj[D.name] = boost::json::value_from(t.*D.pointer); });
}
int b = 0;
struct A {
int *i;
};
BOOST_DESCRIBE_STRUCT(A, (), (i));
A a{&b};
}
int main() {
std::cout << boost::json::value_from(app::a)
<< std::endl;
return 0;
}
If your pointers are to user-defined types, you can "just" overload for the pointer:
This works because of ADL:
Live On Coliru
Printing
Primitive Types
However your type is not user-defined. Primitive types like
int
do not have any associated namespace. The above doesn't work...You would either have to explicitly include the overload, which requires modifying library code, or you can make the pointer-handling explicit in your code:
This will work. Live On Coliru
Printing
Notes
Note that raw pointers are problematic at best. It will be completely unclear what to do when deserializing instead. I suspect you might want to look at Boost Serialization instead if you need that kind of support.