JSON Voorhees
Killer JSON for C++
all.hpp
Go to the documentation of this file.
1 /** \file jsonv/all.hpp
2  * A head which includes all other JSON Voorhees headers.
3  *
4  * Copyright (c) 2012-2015 by Travis Gockel. All rights reserved.
5  *
6  * This program is free software: you can redistribute it and/or modify it under the terms of the Apache License
7  * as published by the Apache Software Foundation, either version 2 of the License, or (at your option) any later
8  * version.
9  *
10  * \author Travis Gockel (travis@gockelhut.com)
11 **/
12 #ifndef __JSONV_ALL_HPP_INCLUDED__
13 #define __JSONV_ALL_HPP_INCLUDED__
14 
15 namespace jsonv
16 {
17 
18 /** \mainpage Overview
19  * JSON Voorhees is a JSON library written for the C++ programmer who wants to be productive in this modern world. What
20  * does that mean? There are a ton of JSON libraries floating around touting how they are "modern" C++ and so on. But
21  * who really cares? JSON Voorhees puts the focus more on the resulting C++ than any "modern" feature set. This means
22  * the library does not skip on string encoding details like having full support for UTF-8. Are there "modern"
23  * features? Sure, but this library is not meant to be a gallery of them -- a good API should get out of your way and
24  * let you work. It is hosted on <a href="https://github.com/tgockel/json-voorhees">GitHub</a> and sports an Apache
25  * License, so use it anywhere you need.
26  *
27  * Features include (but are not necessarily limited to):
28  *
29  * - Simple
30  * - A `value` should not feel terribly different from a C++ Standard Library container
31  * - Write valid JSON with `operator<<`
32  * - Simple JSON parsing with `parse`
33  * - Reasonable error messages when parsing fails
34  * - Full support for Unicode-filled JSON (encoded in UTF-8 in C++)
35  * - Efficient
36  * - Minimal overhead to store values (a `value` is 16 bytes on a 64-bit platform)
37  * - No-throw move semantics wherever possible
38  * - Easy
39  * - Convert a `value` into a C++ type using `extract<T>`
40  * - Encode a C++ type into a value using `to_json`
41  * - Safe
42  * - In the best case, illegal code should fail to compile
43  * - An illegal action should throw an exception
44  * - Almost all utility functions have a <a href="http://www.gotw.ca/gotw/082.htm">strong exception guarantee</a>.
45  * - Stable
46  * - Worry less about upgrading -- the API and ABI will not change out from under you
47  * - Documented
48  * - Consumable by human beings
49  * - Answers questions you might actually ask
50  *
51  * \dotfile doc/conversions.dot
52  *
53  * JSON Voorhees is designed with ease-of-use in mind. So let's look at some code!
54  *
55  * \section demo_value The jsonv::value
56  *
57  * The central class of JSON Voorhees is the \c jsonv::value. This class represents a JSON AST and is somewhat of a
58  * dynamic type. This can make things a little bit awkward for C++ programmers who are used to static typing. Don't
59  * worry about it -- you can learn to love it.
60  *
61  * Putting values of different types is super-easy.
62  *
63  * \code
64  * #include <jsonv/value.hpp>
65  * #include <iostream>
66  *
67  * int main()
68  * {
69  * jsonv::value x = jsonv::null;
70  * std::cout << x << std::endl;
71  * x = 5.9;
72  * std::cout << x << std::endl;
73  * x = -100;
74  * std::cout << x << std::endl;
75  * x = "something else";
76  * std::cout << x << std::endl;
77  * x = jsonv::array({ "arrays", "of", "the", 7, "different", "types"});
78  * std::cout << x << std::endl;
79  * x = jsonv::object({
80  * { "objects", jsonv::array({
81  * "Are fun, too.",
82  * "Do what you want."
83  * })
84  * },
85  * { "compose like", "standard library maps" },
86  * });
87  * std::cout << x << std::endl;
88  * }
89  * \endcode
90  *
91  * Output:
92  *
93  * \code
94  * null
95  * 5.9
96  * -100
97  * "something else"
98  * ["arrays","of","the",7,"different","types"]
99  * {"compose like":"standard library maps","objects":["Are fun, too.","Do what you want."]}
100  * \endcode
101  *
102  * If that isn't convenient enough for you, there is a user-defined literal \c _json in the \c jsonv namespace you can
103  * use
104  *
105  * \code
106  * // You can use this hideous syntax if you do not want to bring in the whole jsonv namespace:
107  * using jsonv::operator"" _json;
108  *
109  * jsonv::value x = R"({
110  * "objects": [ "Are fun, too.",
111  * "Do what you want."
112  * ],
113  * "compose like": "You are just writing JSON",
114  * "which I guess": ["is", "also", "neat"]
115  * })"_json;
116  * \endcode
117  *
118  * JSON is dynamic, which makes value access a bit more of a hassle, but JSON Voorhees aims to make it not too
119  * horrifying for you. A \c jsonv::value has a number of accessor methods named things like \c as_integer and
120  * \c as_string which let you access the value as if it was that type. But what if it isn't that type? In that case,
121  * the function will throw a \c jsonv::kind_error with a bit more information as to what rule you violated.
122  *
123  * \code
124  * #include <jsonv/value.hpp>
125  * #include <iostream>
126  *
127  * int main()
128  * {
129  * jsonv::value x = jsonv::null;
130  * try
131  * {
132  * x.as_string();
133  * }
134  * catch (const jsonv::kind_error& err)
135  * {
136  * std::cout << err.what() << std::endl;
137  * }
138  *
139  * x = "now make it a string";
140  * std::cout << x.as_string().size() << std::endl;
141  * std::cout << x.as_string() << "\tis not the same as\t" << x << std::endl;
142  * }
143  * \endcode
144  *
145  * Output:
146  *
147  * \code
148  * Unexpected type: expected string but found null.
149  * 20
150  * now make it a string is not the same as "now make it a string"
151  * \endcode
152  *
153  * You can also deal with container types in a similar manner that you would deal with the equivalent STL container
154  * type, with some minor caveats. Because the \c value_type of a JSON object and JSON array are different, they have
155  * different iterator types in JSON Voorhees. They are aptly-named \c object_iterator and \c array_iterator. The access
156  * methods for these iterators are \c begin_object / \c end_object and \c begin_array / \c end_array, respectively.
157  * The object interface behaves exactly like you would expect a \c std::map<std::string,jsonv::value> to, while the
158  * array interface behaves just like a \c std::deque<jsonv::value> would.
159  *
160  * \code
161  * #include <jsonv/value.hpp>
162  * #include <iostream>
163  *
164  * int main()
165  * {
166  * jsonv::value x = jsonv::object({ { "one", 1 }});
167  * auto iter = x.find("one");
168  * if (iter != x.end_object())
169  * std::cout << iter->first << ": " << iter->second << std::endl;
170  * else
171  * std::cout << "Nothing..." << std::end;
172  *
173  * iter = x.find("two");
174  * if (iter != x.end_object())
175  * std::cout << iter->first << ": " << iter->second << std::endl;
176  * else
177  * std::cout << "Nothing..." << std::end;
178  *
179  * x["two"] = 2;
180  * iter = x.find("two");
181  * if (iter != x.end_object())
182  * std::cout << iter->first << ": " << iter->second << std::endl;
183  * else
184  * std::cout << "Nothing..." << std::end;
185  *
186  * x["two"] = jsonv::array({ "one", "+", x.at("one") });
187  * iter = x.find("two");
188  * if (iter != x.end_object())
189  * std::cout << iter->first << ": " << iter->second << std::endl;
190  * else
191  * std::cout << "Nothing..." << std::end;
192  *
193  * x.erase("one");
194  * iter = x.find("one");
195  * if (iter != x.end_object())
196  * std::cout << iter->first << ": " << iter->second << std::endl;
197  * else
198  * std::cout << "Nothing..." << std::end;
199  * }
200  * \endcode
201  *
202  * Output:
203  *
204  * \code
205  * one: 1
206  * Nothing...
207  * two: 2
208  * two: ["one","+",1]
209  * Nothing...
210  * \endcode
211  *
212  * The iterator types \e work. This means you are free to use all of the C++ things just like you would a regular
213  * container. To use a ranged-based for, simply call \c as_array or \c as_object. Everything from \c <algorithm> and
214  * \c <iterator> or any other library works great with JSON Voorhees. Bring those templates on!
215  *
216  * \code
217  * #include <jsonv/value.hpp>
218  * #include <algorithm>
219  * #include <iostream>
220  *
221  * int main()
222  * {
223  * jsonv::value arr = jsonv::array({ "taco", "cat", 3, -2, jsonv::null, "beef", 4.8, 5 });
224  * std::cout << "Initial: ";
225  * for (const auto& val : arr.as_array())
226  * std::cout << val << '\t';
227  * std::cout << std::endl;
228  *
229  * std::sort(arr.begin_array(), arr.end_array());
230  * std::cout << "Sorted: ";
231  * for (const auto& val : arr.as_array())
232  * std::cout << val << '\t';
233  * std::cout << std::endl;
234  * }
235  * \endcode
236  *
237  * Output:
238  *
239  * \code
240  * Initial: "taco" "cat" 3 -2 null "beef" 4.8 5
241  * Sorted: null -2 3 4.8 5 "beef" "cat" "taco"
242  * \endcode
243  *
244  * \section demo_parsing Encoding and decoding
245  *
246  * Usually, the reason people are using JSON is as a data exchange format, either for communicating with other services
247  * or storing things in a file or a database. To do this, you need to \e encode your \c json::value into an
248  * \c std::string and \e parse it back. JSON Voorhees makes this very easy for you.
249  *
250  * \code
251  * #include <jsonv/value.hpp>
252  * #include <jsonv/encode.hpp>
253  * #include <jsonv/parse.hpp>
254  *
255  * #include <iostream>
256  * #include <fstream>
257  * #include <limits>
258  *
259  * int main()
260  * {
261  * jsonv::value obj = jsonv::object();
262  * obj["taco"] = "cat";
263  * obj["array"] = jsonv::array({ 1, 2, 3, 4, 5 });
264  * obj["infinity"] = std::numeric_limits<double>::infinity();
265  *
266  * {
267  * std::cout << "Saving \"file.json\"... " << obj << std::endl;
268  * std::ofstream file("file.json");
269  * file << obj;
270  * }
271  *
272  * jsonv::value loaded;
273  * {
274  * std::cout << "Loading \"file.json\"...";
275  * std::ifstream file("file.json");
276  * loaded = jsonv::parse(file);
277  * }
278  * std::cout << loaded << std::endl;
279  *
280  * return obj == loaded ? 0 : 1;
281  * }
282  * \endcode
283  *
284  * Output:
285  *
286  * \code
287  * Saving "file.json"... {"array":[1,2,3,4,5],"infinity":null,"taco":"cat"}
288  * Loading "file.json"...{"array":[1,2,3,4,5],"infinity":null,"taco":"cat"}
289  * \endcode
290  *
291  * If you are paying close attention, you might have noticed that the value for the \c "infinity" looks a little bit
292  * more \c null than \c infinity. This is because, much like mathematicians before Anaximander, JSON has no concept of
293  * infinity, so it is actually \e illegal to serialize a token like \c infinity anywhere. By default, when an encoder
294  * encounters an unrepresentable value in the JSON it is trying to encode, it outputs \c null instead. If you wish to
295  * change this behavior, implement your own \c jsonv::encoder (or derive from \c jsonv::ostream_encoder). If you ran
296  * the example program, you might have noticed that the return code was 1, meaning the value you put into the file and
297  * what you got from it were not equal. This is because all the type and value information is still kept around in the
298  * in-memory \c obj. It is only upon encoding that information is lost.
299  *
300  * Getting tired of all this compact rendering of your JSON strings? Want a little more whitespace in your life? Then
301  * \c jsonv::ostream_pretty_encoder is the class for you! Unlike our standard \e compact encoder, this guy will put
302  * newlines and indentation in your JSON so you can present it in a way more readable format.
303  *
304  * \code
305  * #include <jsonv/encode.hpp>
306  * #include <jsonv/parse.hpp>
307  * #include <jsonv/value.hpp>
308  *
309  * #include <iostream>
310  *
311  * int main()
312  * {
313  * // Make a pretty encoder and point to std::cout
314  * jsonv::ostream_pretty_encoder prettifier(std::cout);
315  * prettifier.encode(jsonv::parse(std::cin));
316  * }
317  * \endcode
318  *
319  * Compile that code and you now have your own little JSON prettification program!
320  *
321  * \section serialization Serialization
322  *
323  * Most of the time, you do not want to deal with \c jsonv::value instances directly. Instead, most people prefer to
324  * convert \c jsonv::value instances into their own strong C++ \c class or \c struct. JSON Voorhees provides utilities
325  * to make this easy for you to use. At the end of the day, you should be able to create an arbitrary C++ type with
326  * <tt>jsonv::extract&lt;my_type&gt;(value)</tt> and create a \c jsonv::value from your arbitrary C++ type with
327  * <tt>jsonv::to_json(my_instance)</tt>.
328  *
329  * \subsection serialization_encoding Extracting with extract
330  *
331  * Let's start with converting a \c jsonv::value into a custom C++ type with <tt>jsonv::extract&lt;T&gt;</tt>.
332  *
333  * \code
334  * #include <jsonv/parse.hpp>
335  * #include <jsonv/serialization.hpp>
336  * #include <jsonv/value.hpp>
337  *
338  * #include <iostream>
339  *
340  * int main()
341  * {
342  * jsonv::value val = jsonv::parse(R"({ "a": 1, "b": 2, "c": "Hello!" })");
343  * std::cout << "a=" << jsonv::extract<int>(val.at("a")) << std::endl;
344  * std::cout << "b=" << jsonv::extract<int>(val.at("b")) << std::endl;
345  * std::cout << "c=" << jsonv::extract<std::string>(val.at("c")) << std::endl;
346  * }
347  * \endcode
348  *
349  * Output:
350  *
351  * \code
352  * a=1
353  * b=2
354  * c=Hello!
355  * \endcode
356  *
357  * Overall, this is not very complicated. We did not do anything that could not have been done through a little use of
358  * \c as_integer and \c as_string. So what is this \c extract giving us?
359  *
360  * The real power comes in when we start talking about \c jsonv::formats. These objects provide a set of rules to
361  * encode and decode arbitrary types. So let's make a C++ \c class for our JSON object and write a special constructor
362  * for it.
363  *
364  * \code
365  * #include <jsonv/parse.hpp>
366  * #include <jsonv/serialization.hpp>
367  * #include <jsonv/serialization_util.hpp>
368  * #include <jsonv/value.hpp>
369  *
370  * #include <iostream>
371  *
372  * class my_type
373  * {
374  * public:
375  * my_type(const jsonv::value& from, const jsonv::extraction_context& context) :
376  * a(context.extract_sub<int>(from, "a")),
377  * b(context.extract_sub<int>(from, "b")),
378  * c(context.extract_sub<std::string>(from, "c"))
379  * { }
380  *
381  * static const jsonv::extractor* get_extractor()
382  * {
383  * static jsonv::extractor_construction<my_type> instance;
384  * return &instance;
385  * }
386  *
387  * friend std::ostream& operator<<(std::ostream& os, const my_type& self)
388  * {
389  * return os << "{ a=" << self.a << ", b=" << self.b << ", c=" << self.c << " }";
390  * }
391  *
392  * private:
393  * int a;
394  * int b;
395  * std::string c;
396  * };
397  *
398  * int main()
399  * {
400  * jsonv::formats local_formats;
401  * local_formats.register_extractor(my_type::get_extractor());
402  * jsonv::formats format = jsonv::formats::compose({ jsonv::formats::defaults(), local_formats });
403  *
404  * jsonv::value val = jsonv::parse(R"({ "a": 1, "b": 2, "c": "Hello!" })");
405  * my_type x = jsonv::extract<my_type>(val, format);
406  * std::ostream << x << std::endl;
407  * }
408  * \endcode
409  *
410  * Output:
411  *
412  * \code
413  * { a=1, b=2, c=Hello! }
414  * \endcode
415  *
416  * There is a lot going on in that example, so let's take it one step at a time. First, we are creating a \c my_type
417  * object to store our values, which is nice. Then, we gave it a funny-looking constructor:
418  *
419  * \code
420  * my_type(const jsonv::value& from, const jsonv::extraction_context& context) :
421  * a(context.extract_sub<int>(from, "a")),
422  * b(context.extract_sub<int>(from, "b")),
423  * c(context.extract_sub<std::string>(from, "c"))
424  * { }
425  * \endcode
426  *
427  * This is an <i>extracting constructor</i>. All that means is that it has those two arguments: a \c jsonv::value and
428  * a \c jsonv::extraction_context. The \c jsonv::extraction_context is an optional, but extremely helpful class. Inside
429  * the constructor, we use the \c jsonv::extraction_context to access the values of the incoming JSON object in order
430  * to build our object.
431  *
432  * \code
433  * static const jsonv::extractor* get_extractor()
434  * {
435  * static jsonv::extractor_construction<my_type> instance;
436  * return &instance;
437  * }
438  * \endcode
439  *
440  * A \c jsonv::extractor is a type that knows how to take a \c jsonv::value and create some C++ type out of it. In this
441  * case, we are creating a \c jsonv::extractor_construction, which is a subtype that knows how to call the constructor
442  * of a type. There are all sorts of \c jsonv::extractor implementations in \c jsonv/serialization.hpp, so you should
443  * be able to find one that fits your needs.
444  *
445  * \code
446  * jsonv::formats local_formats;
447  * local_formats.register_extractor(my_type::get_extractor());
448  * jsonv::formats format = jsonv::formats::compose({ jsonv::formats::defaults(), local_formats });
449  * \endcode
450  *
451  * Now things are starting to get interesting. The \c jsonv::formats object is a collection of
452  * <tt>jsonv::extractor</tt>s, so we create one of our own and add the \c jsonv::extractor* from the static function of
453  * \c my_type. Now, \c local_formats \e only knows how to extract instances of \c my_type -- it does \e not know even
454  * the most basic things like how to extract an \c int. We use \c jsonv::formats::compose to create a new instance of
455  * \c jsonv::formats that combines the qualities of \c local_formats (which knows how to deal with \c my_type) and the
456  * \c jsonv::formats::defaults (which knows how to deal with things like \c int and \c std::string). The \c formats
457  * instance now has the power to do everything we need!
458  *
459  * \code
460  * my_type x = jsonv::extract<my_type>(val, format);
461  * \endcode
462  *
463  * This is not terribly different from the example before, but now we are explicitly passing a \c jsonv::formats object
464  * to the function. If we had not provided \c format as an argument here, the function would have thrown a
465  * \c jsonv::extraction_error complaining about how it did not know how to extract a \c my_type.
466  *
467  * \subsection serialization_to_json Serialization with to_json
468  *
469  * JSON Voorhees also allows you to convert from your C++ structures into JSON values, using \c jsonv::to_json. It
470  * should feel like a mirror \c jsonv::extract, with similar argument types and many shared concepts. Just like
471  * extraction, \c jsonv::to_json uses the \c jsonv::formats class, but it uses a \c jsonv::serializer to convert from
472  * C++ into JSON.
473  *
474  * \code
475  * #include <jsonv/serialization.hpp>
476  * #include <jsonv/serialization_util.hpp>
477  * #include <jsonv/value.hpp>
478  *
479  * #include <iostream>
480  *
481  * class my_type
482  * {
483  * public:
484  * my_type(int a, int b, std::string c) :
485  * a(a),
486  * b(b),
487  * c(std::move(c))
488  * { }
489  *
490  * static const jsonv::serializer* get_serializer()
491  * {
492  * static auto instance = jsonv::make_serializer<my_type>
493  * (
494  * [] (const jsonv::serialization_context& context, const my_type& self)
495  * {
496  * return jsonv::object({ { "a", context.to_json(self.a) },
497  * { "b", context.to_json(self.b) },
498  * { "c", context.to_json(self.c) }
499  * }
500  * );
501  * }
502  * );
503  * return &instance;
504  * }
505  *
506  * private:
507  * int a;
508  * int b;
509  * std::string c;
510  * };
511  *
512  * int main()
513  * {
514  * jsonv::formats local_formats;
515  * local_formats.register_serializer(my_type::get_serializer());
516  * jsonv::formats format = jsonv::formats::compose({ jsonv::formats::defaults(), local_formats });
517  *
518  * my_type x(5, 6, "Hello");
519  * std::ostream << jsonv::to_json(x, format) << std::endl;
520  * }
521  * \endcode
522  *
523  * Output:
524  *
525  * \code
526  * {"a":5,"b":6,"c":"Hello"}
527  * \endcode
528  *
529  * \subsection serialization_composition Composing Type Adapters
530  *
531  * Does all this seem a little bit \e manual to you? Creating an \c extractor and \c serializer for every single type
532  * can get a little bit tedious. Unfortunately, until C++ has a standard way to do reflection, we must specify the
533  * conversions manually. However, there \e is an easier way! That way is the
534  * \ref serialization_builder_dsl "Serialization Builder DSL".
535  *
536  * Let's start with a couple of simple structures:
537  *
538  * \code
539  * struct foo
540  * {
541  * int a;
542  * int b;
543  * std::string c;
544  * };
545  *
546  * struct bar
547  * {
548  * foo x;
549  * foo y;
550  * std::string z;
551  * std::string w;
552  * };
553  * \endcode
554  *
555  * Let's make a \c formats for them using the DSL:
556  *
557  * \code
558  * jsonv::formats formats =
559  * jsonv::formats_builder()
560  * .type<foo>()
561  * .member("a", &foo::a)
562  * .member("b", &foo::b)
563  * .default_value(10)
564  * .member("c", &foo::c)
565  * .type<bar>()
566  * .member("x", &bar::x)
567  * .member("y", &bar::y)
568  * .member("z", &bar::z)
569  * .since(jsonv::version(2, 0))
570  * .member("w", &bar::w)
571  * .until(jsonv::version(5, 0))
572  * ;
573  * \endcode
574  *
575  * What is going on there? The giant chain of function calls is building up a collection of type adapters into a
576  * \c formats for you. The indentation shows the intent -- the <tt>.member("a", &foo::a)</tt> is attached to the type
577  * \c adapter for \c foo (if you tried to specify \c &bar::y in that same place, it would fail to compile). Each
578  * function call returns a reference back to the builder so you can chain as many of these together as you want to. The
579  * \c jsonv::formats_builder is a proper object, so if you wish to spread out building your type adapters into multiple
580  * functions, you can do that by passing around an instance.
581  *
582  * The two most-used functions are \c type and \c member. \c type defines a \c jsonv::adapter for the C++ class
583  * provided at the template parameter. All of the calls before the second \c type call modify the adapter for \c foo.
584  * There, we attach members with the \c member function. This tells the \c formats how to encode and extract each of
585  * the specified members to and from a JSON object using the provided string as the key. The extra function calls like
586  * \c default_value, \c since and \c until are just a could of the many functions available to modify how the members
587  * of the type get transformed.
588  *
589  * The \c formats we built would be perfectly capable of serializing to and extracting from this JSON document:
590  *
591  * \code
592  * {
593  * "x": { "a": 50, "b": 20, "c": "Blah" },
594  * "y": { "a": 10, "c": "No B?" },
595  * "z": "Only serialized in 2.0+",
596  * "w": "Only serialized before 5.0"
597  * }
598  * \endcode
599  *
600  * For a more in-depth reference, see the \ref serialization_builder_dsl "Serialization Builder DSL page".
601  *
602  * \section demo_algorithm Algorithms
603  *
604  * JSON Voorhees takes a "batteries included" approach. A few building blocks for powerful operations can be found in
605  * the \c algorithm.hpp header file.
606  *
607  * One of the simplest operations you can perform is the \c map operation. This operation takes in some \c jsonv::value
608  * and returns another. Let's try it.
609  *
610  * \code
611  * #include <jsonv/algorithm.hpp>
612  * #include <jsonv/value.hpp>
613  *
614  * #include <iostream>
615  *
616  * int main()
617  * {
618  * jsonv::value x = 5;
619  * std::cout << jsonv::map([] (const jsonv::value& y) { return y.as_integer() * 2; }, x) << std::endl;
620  * }
621  * \endcode
622  *
623  * If everything went right, you should see a number:
624  *
625  * \code
626  * 10
627  * \endcode
628  *
629  * Okay, so that was not very interesting. To be fair, that is not the most interesting example of using \c map, but it
630  * is enough to get the general idea of what is going on. This operation is so common that it is a member function of
631  * \c value as \c jsonv::value::map. Let's make things a bit more interesting and \c map an \c array...
632  *
633  * \code
634  * #include <jsonv/value.hpp>
635  *
636  * #include <iostream>
637  *
638  * int main()
639  * {
640  * std::cout << jsonv::array({ 1, 2, 3, 4, 5 })
641  * .map([] (const jsonv::value& y) { return y.as_integer() * 2; })
642  * << std::endl;
643  * }
644  * \endcode
645  *
646  * Now we're starting to get somewhere!
647  *
648  * \code
649  * [2,4,6,8,10]
650  * \endcode
651  *
652  * The \c map function maps over whatever the contents of the \c jsonv::value happens to be and returns something for
653  * you based on the \c kind. This simple concept is so ubiquitous that <a href="http://www.disi.unige.it/person/MoggiE/">
654  * Eugenio Moggi</a> named it a <a href="http://stackoverflow.com/questions/44965/what-is-a-monad">monad</a>. If you're
655  * feeling adventurous, try using \c map with an \c object or chaining multiple \c map operations together.
656  *
657  * Another common building block is the function \c jsonv::traverse. This function walks a JSON structure and calls a
658  * some user-provided function.
659  *
660  * \code
661  * #include <jsonv/algorithm.hpp>
662  * #include <jsonv/parse.hpp>
663  * #include <jsonv/value.hpp>
664  *
665  * #include <iostream>
666  *
667  * int main()
668  * {
669  * jsonv::traverse(jsonv::parse(std::cin),
670  * [] (const jsonv::path& path, const jsonv::value& value)
671  * {
672  * std::cout << path << "=" << value << std::endl;
673  * },
674  * true
675  * );
676  * }
677  * \endcode
678  *
679  * Now we have a tiny little program! Here's what happens when I pipe <tt>{ "bar": [1, 2, 3], "foo": "hello" }</tt>
680  * into the program:
681  *
682  * \code
683  * .bar[0]=1
684  * .bar[1]=2
685  * .bar[2]=3
686  * .foo="hello"
687  * \endcode
688  *
689  * Imagine the possibilities!
690  *
691  * All of the \e really powerful functions can be found in \c util.hpp. My personal favorite is \c jsonv::merge. The
692  * idea is simple: it merges two (or more) JSON values into one.
693  *
694  * \code
695  * #include <jsonv/util.hpp>
696  * #include <jsonv/value.hpp>
697  *
698  * #include <iostream>
699  *
700  * int main()
701  * {
702  * jsonv::value a = jsonv::object({ { "a", "taco" }, { "b", "cat" } });
703  * jsonv::value b = jsonv::object({ { "c", "burrito" }, { "d", "dog" } });
704  * jsonv::value merged = jsonv::merge(std::move(a), std::move(b));
705  * std::cout << merged << std::endl;
706  * }
707  * \endcode
708  *
709  * Output:
710  *
711  * \code
712  * {"a":"taco","b":"cat","c":"burrito","d":"dog"}
713  * \endcode
714  *
715  * You might have noticed the use of \c std::move into the \c merge function. Like most functions in JSON Voorhees,
716  * \c merge takes advantage of move semantics. In this case, the implementation will move the contents of the values
717  * instead of copying them around. While it may not matter in this simple case, if you have large JSON structures, the
718  * support for movement will save you a ton of memory.
719  *
720  * \see https://github.com/tgockel/json-voorhees
721  * \see http://json.org/
722 **/
723 
724 }
725 
726 #include "algorithm.hpp"
727 #include "coerce.hpp"
728 #include "config.hpp"
729 #include "demangle.hpp"
730 #include "encode.hpp"
731 #include "forward.hpp"
732 #include "functional.hpp"
733 #include "parse.hpp"
734 #include "path.hpp"
735 #include "serialization.hpp"
736 #include "serialization_builder.hpp"
737 #include "serialization_util.hpp"
738 #include "string_view.hpp"
739 #include "tokenizer.hpp"
740 #include "util.hpp"
741 #include "value.hpp"
742 
743 #endif/*__JSONV_ALL_HPP_INCLUDED__*/
A collection of algorithms a la <algorithm>.
Copyright (c) 2015 by Travis Gockel.
Helper types and functions for serialization.
DSL for building formats.
Copyright (c) 2014-2019 by Travis Gockel.
Support for JSONPath.
Classes and functions for encoding JSON values to various representations.
Copyright (c) 2012-2014 by Travis Gockel.
Deprecated.
Conversion between C++ types and JSON values.
Pulls in an implementation of string_view.
A stream-based tokenizer meant to help with creating custom parsers.
A jsonv::value has a number of as_X operators, which strictly performs a transformation to a C++ data...
Copyright (c) 2012-2014 by Travis Gockel.
Copyright (c) 2012-2018 by Travis Gockel.
A collection of function objects a la <functional>.