]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/hana/example/misc/from_json.cpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / libs / hana / example / misc / from_json.cpp
CommitLineData
b32b8144 1// Copyright Louis Dionne 2013-2017
7c673cae
FG
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/assert.hpp>
6#include <boost/hana/at.hpp>
7#include <boost/hana/at_key.hpp>
8#include <boost/hana/concept/sequence.hpp>
9#include <boost/hana/concept/struct.hpp>
10#include <boost/hana/define_struct.hpp>
11#include <boost/hana/for_each.hpp>
12#include <boost/hana/keys.hpp>
13#include <boost/hana/length.hpp>
14#include <boost/hana/not_equal.hpp>
15#include <boost/hana/tuple.hpp>
16
17#include <iostream>
18#include <limits>
19#include <sstream>
20#include <string>
21#include <type_traits>
22namespace hana = boost::hana;
23
24
25struct Car {
26 BOOST_HANA_DEFINE_STRUCT(Car,
27 (std::string, brand),
28 (std::string, model)
29 );
30};
31
32struct Person {
33 BOOST_HANA_DEFINE_STRUCT(Person,
34 (std::string, name),
35 (std::string, last_name),
36 (int, age)
37 );
38};
39
40template <typename T>
41 std::enable_if_t<std::is_same<T, int>::value,
42T> from_json(std::istream& in) {
43 T result;
44 in >> result;
45 return result;
46}
47
48template <typename T>
49 std::enable_if_t<std::is_same<T, std::string>::value,
50T> from_json(std::istream& in) {
51 char quote;
52 in >> quote;
53
54 T result;
55 char c;
56 while (in.get(c) && c != '"') {
57 result += c;
58 }
59 return result;
60}
61
62
63template <typename T>
64 std::enable_if_t<hana::Struct<T>::value,
65T> from_json(std::istream& in) {
66 T result;
67 char brace;
68 in >> brace;
69
b32b8144
FG
70 // CAREFUL: This only works if the input JSON contains the fields in the
71 // same order as the struct declares them.
7c673cae
FG
72 hana::for_each(hana::keys(result), [&](auto key) {
73 in.ignore(std::numeric_limits<std::streamsize>::max(), ':');
74 auto& member = hana::at_key(result, key);
75 using Member = std::remove_reference_t<decltype(member)>;
76 member = from_json<Member>(in);
77 });
78 in >> brace;
79 return result;
80}
81
82template <typename Xs>
83 std::enable_if_t<hana::Sequence<Xs>::value,
84Xs> from_json(std::istream& in) {
85 Xs result;
86 char bracket;
87 in >> bracket;
88 hana::length(result).times.with_index([&](auto i) {
89 if (i != 0u) {
90 char comma;
91 in >> comma;
92 }
93
94 auto& element = hana::at(result, i);
95 using Element = std::remove_reference_t<decltype(element)>;
96 element = from_json<Element>(in);
97 });
98 in >> bracket;
99 return result;
100}
101
102
103int main() {
104 std::istringstream json(R"EOS(
105 [
106 {
107 "name": "John",
108 "last_name": "Doe",
109 "age": 30
110 },
111 {
112 "brand": "BMW",
113 "model": "Z3"
114 },
115 {
116 "brand": "Audi",
117 "model": "A4"
118 }
119 ]
120 )EOS");
121
122 auto actual = from_json<hana::tuple<Person, Car, Car>>(json);
123
124 auto expected = hana::make_tuple(Person{"John", "Doe", 30},
125 Car{"BMW", "Z3"},
126 Car{"Audi", "A4"});
127
128 BOOST_HANA_RUNTIME_CHECK(actual == expected);
129}