1// Copyright Louis Dionne 2013-2022
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
5#include <boost/hana.hpp>
6
7#include <functional>
8#include <iostream>
9#include <string>
10#include <type_traits>
11#include <utility>
12namespace hana = boost::hana;
13using namespace hana::literals;
14using namespace std::literals;
15
16
17//////////////////////////////////////////////////////////////////////////////
18// Welcome to Hana!
19//
20// You can play around and press 'Run' at the bottom of this file to compile
21// and run this code.
22//
23// To get you started, here's a small JSON generator written with Hana
24// (this is explained in the tutorial if you're interested):
25//////////////////////////////////////////////////////////////////////////////
26
27// 1. Define some utilities
28template <typename Xs>
29std::string join(Xs&& xs, std::string sep) {
30 return hana::fold(hana::intersperse(std::forward<Xs>(xs), sep), "", std::plus<>{});
31}
32
33std::string quote(std::string s) { return "\"" + s + "\""; }
34
35template <typename T>
36auto to_json(T const& x) -> decltype(std::to_string(x)) {
37 return std::to_string(x);
38}
39
40std::string to_json(char c) { return quote(s: {c}); }
41std::string to_json(std::string s) { return quote(s); }
42
43
44// 2. Define how to print user-defined types
45template <typename T>
46 std::enable_if_t<hana::Struct<T>::value,
47std::string> to_json(T const& x) {
48 auto json = hana::transform(hana::keys(x), [&](auto name) {
49 auto const& member = hana::at_key(x, name);
50 return quote(hana::to<char const*>(name)) + " : " + to_json(member);
51 });
52
53 return "{" + join(std::move(json), ", ") + "}";
54}
55
56// 3. Define how to print Sequences
57template <typename Xs>
58 std::enable_if_t<hana::Sequence<Xs>::value,
59std::string> to_json(Xs const& xs) {
60 auto json = hana::transform(xs, [](auto const& x) {
61 return to_json(x);
62 });
63
64 return "[" + join(std::move(json), ", ") + "]";
65}
66
67
68// 4. Create your own types and make them compatible with Hana.
69// This can be done intrusively or non-intrusively.
70struct Car {
71 BOOST_HANA_DEFINE_STRUCT(Car,
72 (std::string, brand),
73 (std::string, model)
74 );
75};
76
77int main() {
78 // 5. Generate beautiful JSON without hassle. Enjoy!
79 auto cars = hana::make_tuple(
80 Car{.brand: "BMW", .model: "Z3"},
81 Car{.brand: "Audi", .model: "A4"},
82 Car{.brand: "Ferrari", .model: "F40"},
83 Car{.brand: "Lamborghini", .model: "Diablo"}
84 // ...
85 );
86
87 std::cout << to_json(xs: cars) << std::endl;
88}
89

source code of boost/libs/hana/example/wandbox.cpp