introspection.json.cpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. // Copyright Louis Dionne 2013-2017
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  4. #include <boost/hana.hpp>
  5. #include <iostream>
  6. #include <string>
  7. #include <type_traits>
  8. #include <utility>
  9. namespace hana = boost::hana;
  10. using namespace std::literals;
  11. //! [utilities]
  12. template <typename Xs>
  13. std::string join(Xs&& xs, std::string sep) {
  14. return hana::fold(hana::intersperse(std::forward<Xs>(xs), sep), "", hana::_ + hana::_);
  15. }
  16. std::string quote(std::string s) { return "\"" + s + "\""; }
  17. template <typename T>
  18. auto to_json(T const& x) -> decltype(std::to_string(x)) {
  19. return std::to_string(x);
  20. }
  21. std::string to_json(char c) { return quote({c}); }
  22. std::string to_json(std::string s) { return quote(s); }
  23. //! [utilities]
  24. //! [Struct]
  25. template <typename T>
  26. std::enable_if_t<hana::Struct<T>::value,
  27. std::string> to_json(T const& x) {
  28. auto json = hana::transform(hana::keys(x), [&](auto name) {
  29. auto const& member = hana::at_key(x, name);
  30. return quote(hana::to<char const*>(name)) + " : " + to_json(member);
  31. });
  32. return "{" + join(std::move(json), ", ") + "}";
  33. }
  34. //! [Struct]
  35. //! [Sequence]
  36. template <typename Xs>
  37. std::enable_if_t<hana::Sequence<Xs>::value,
  38. std::string> to_json(Xs const& xs) {
  39. auto json = hana::transform(xs, [](auto const& x) {
  40. return to_json(x);
  41. });
  42. return "[" + join(std::move(json), ", ") + "]";
  43. }
  44. //! [Sequence]
  45. int main() {
  46. //! [usage]
  47. struct Car {
  48. BOOST_HANA_DEFINE_STRUCT(Car,
  49. (std::string, brand),
  50. (std::string, model)
  51. );
  52. };
  53. struct Person {
  54. BOOST_HANA_DEFINE_STRUCT(Person,
  55. (std::string, name),
  56. (std::string, last_name),
  57. (int, age)
  58. );
  59. };
  60. Car bmw{"BMW", "Z3"}, audi{"Audi", "A4"};
  61. Person john{"John", "Doe", 30};
  62. auto tuple = hana::make_tuple(john, audi, bmw);
  63. std::cout << to_json(tuple) << std::endl;
  64. //! [usage]
  65. }