Trading System API  3.0
Library for Simulating and Deploying Trading and Investment Strategies
TSAJSON.h
1 #ifndef TSA_JSON__INCLUDED
2 #define TSA_JSON__INCLUDED
3 
4 /* json11
5 *
6 * json11 is a tiny JSON library for C++11, providing JSON parsing and serialization.
7 *
8 * The core object provided by the library is json11::Json. A Json object represents any JSON
9 * value: null, bool, number (int or double), string (std::string), array (std::vector), or
10 * object (std::map).
11 *
12 * Json objects act like values: they can be assigned, copied, moved, compared for equality or
13 * order, etc. There are also helper methods Json::dump, to serialize a Json to a string, and
14 * Json::parse (static) to parse a std::string as a Json object.
15 *
16 * Internally, the various types of Json object are represented by the JsonValue class
17 * hierarchy.
18 *
19 * A note on numbers - JSON specifies the syntax of number formatting but not its semantics,
20 * so some JSON implementations distinguish between integers and floating-point numbers, while
21 * some don't. In json11, we choose the latter. Because some JSON implementations (namely
22 * Javascript itself) treat all numbers as the same type, distinguishing the two leads
23 * to JSON that will be *silently* changed by a round-trip through those implementations.
24 * Dangerous! To avoid that risk, json11 stores all numbers as double internally, but also
25 * provides integer helpers.
26 *
27 * Fortunately, double-precision IEEE754 ('double') can precisely store any integer in the
28 * range +/-2^53, which includes every 'int' on most systems. (Timestamps often use int64
29 * or long long to avoid the Y2038K problem; a double storing microseconds since some epoch
30 * will be exact for +/- 275 years.)
31 */
32 
33 /* Copyright (c) 2013 Dropbox, Inc.
34 *
35 * Permission is hereby granted, free of charge, to any person obtaining a copy
36 * of this software and associated documentation files (the "Software"), to deal
37 * in the Software without restriction, including without limitation the rights
38 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39 * copies of the Software, and to permit persons to whom the Software is
40 * furnished to do so, subject to the following conditions:
41 *
42 * The above copyright notice and this permission notice shall be included in
43 * all copies or substantial portions of the Software.
44 *
45 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51 * THE SOFTWARE.
52 */
53 
54 #pragma once
55 
56 #include <string>
57 #include <vector>
58 #include <map>
59 #include <memory>
60 #include <initializer_list>
61 
62 #include "TSATypeDef.h"
63 #include "TSATime.h"
64 
65 namespace tsa{
66 
67  class json_value;
68 
81  class json final {
82  public:
83 
87  enum Type {
88  NUL, NUMBER, BOOL, STRING, ARRAY, OBJECT
89  };
90 
91  // Array and object typedefs
92  typedef std::vector<json> array;
93  typedef std::map<std::string, json> object;
94 
95  // Constructors for the various types of JSON value.
97  //json(const json::object&);
99  json() noexcept; // NUL
101  json(std::nullptr_t) noexcept; // NUL
103  json(double value); // NUMBER
105  json(int value); // NUMBER
107  json(int64_t value); // NUMBER
109  json(uint64_t value); // NUMBER
111  json(bool value); // BOOL
113  json(const date_time& value); // STRING
115  json(const date& value); // STRING
117  json(const std::string &value); // STRING
119  json(std::string &&value); // STRING
121  json(const char * value); // STRING
123  json(const array &values); // ARRAY
125  json(array &&values); // ARRAY
127  json(const object &values); // OBJECT
129  json(object &&values); // OBJECT
131  explicit json(const variant&);
132 
134  template <class T, class = decltype(&T::to_json)>
135  json(const T & t) : json(t.to_json()) {}
136 
138  template <class M, typename std::enable_if<
139  std::is_constructible<std::string, typename M::key_type>::value
140  && std::is_constructible<json, typename M::mapped_type>::value, int>::type = 0>
141  json(const M & m) : json(object(m.begin(), m.end())) {}
142 
144  template <class V, typename std::enable_if<
145  std::is_constructible<json, typename V::value_type>::value, int>::type = 0>
146  json(const V & v) : json(array(v.begin(), v.end())) {}
147 
150  json(void *) = delete;
151 
153  Type type() const;
154 
155  bool is_defined() const { return type() != NUL; }
157  bool is_null() const { return type() == NUL; }
159  bool is_number() const { return type() == NUMBER; }
161  bool is_bool() const { return type() == BOOL; }
163  bool is_string() const { return type() == STRING; }
165  bool is_array() const { return type() == ARRAY; }
167  bool is_object() const { return type() == OBJECT; }
168 
169 
170  template<typename T> T get(void) const;
171 
172  /*
173  * @brief Return the enclosed value if this is a number, 0 otherwise. Note that json11 does not
174  * distinguish between integer and non-integer numbers - number_value() and int_value()
175  * can both be applied to a NUMBER-typed object.
176  * @return The total number of value.
177  */
178  double number_value() const;
179  //
180  //double get_number()const;
182  double float64()const;
183 
188  int int_value(void) const;
190  int int32(void)const;
191 
193  int64_t int64(void)const{
194  double value = float64();
195  int64_t integer = (int64_t)value;
196  if ((double)integer != value)
197  throw std::exception("json cannot return number as int64_t, conversion error");
198  return integer;
199  }
201 
202  tsa::identifier_t id(void)const {
203  return int64();
204  }
206  int64_t uint64(void)const{
207  double value = float64();
208  uint64_t integer = (int64_t)value;
209  if ((double)integer != value)
210  throw std::exception("json cannot return number as uint64_t, conversion error");
211  return integer;
212  }
217  bool bool_value(void) const;
219  bool boolean(void)const;
224  const std::string& string_value(void) const;
225  //
226  //const std::string& get_string(void) const;
228  const std::string& str(void) const;
229 
231  variant to_variant(void)const;
232 
233  /*
234  * @brief Return the enclosed std::vector if this is an array, or an empty vector otherwise.
235  * @return An array&amp;
236  */
237  const array& array_items(void) const;
239  const array& get_array(void) const{ return array_items(); }
240  /*
241  * @brief Return the enclosed std::map if this is an object, or an empty map otherwise.
242  * @return An object&amp;
243  */
244  const object& object_items(void) const;
246  const object& get_object(void) const{ return object_items(); }
247 
251  const json& operator[](size_t i) const;
252 
256  const json& operator[](const std::string &key) const;
257 
258  public:
259 
261  explicit operator double(void) const { return float64(); }
263  explicit operator int(void) const { return int32(); }
265  explicit operator int64_t (void) const { return int64(); }
266  // @brief Returns value as an uint64_t.
267  explicit operator uint64_t (void) const { return uint64(); }
269  explicit operator bool(void) const { return boolean(); }
271  explicit operator std::string(void) const { return str(); }
273  explicit operator date(void) const {tsa::date d; d.set_from_iso_string(str()); return d;}
275  explicit operator date_time(void) const { tsa::date_time t; t.set_from_iso_string(str()); return t; }
276  public:
279  void dump(std::string &out) const;
281  std::string to_string(void) const;
282 
283  void print(std::ostream& stream)const;
284 
285  void print_formated(std::ostream& stream)const;
286 
291  static json parse(const std::string & in, std::string & err);
292 
293  static json parse(const std::string & in);
295  static json parse(const char * in, std::string & err) {
296  if (in) {
297  return parse(std::string(in), err);
298  }
299  else {
300  err = "null input";
301  return nullptr;
302  }
303  }
304 
309  static std::vector<json> parse_multi(const std::string & in, std::string & err);
310 
312  bool operator== (const json &rhs) const;
314  bool operator< (const json &rhs) const;
316  bool operator!= (const json &rhs) const { return !(*this == rhs); }
318  bool operator<= (const json &rhs) const { return !(rhs < *this); }
320  bool operator>(const json &rhs) const { return (rhs < *this); }
322  bool operator>= (const json &rhs) const { return !(*this < rhs); }
323 
329  typedef std::initializer_list<std::pair<std::string, Type>> shape;
330  bool has_shape(const shape & types, std::string & err) const;
331 
332  private:
333  std::shared_ptr<json_value> m_ptr;
334  public:
336  void insert(const std::string& key, const json& value);
338  bool has_key(const std::string& key)const;
340  void push_back(const json& value);
341  };
342 
343  template<> double json::get<double>(void) const;
344  template<> int json::get<int>(void) const;
345  template<> unsigned json::get<unsigned>(void) const;
346  template<> int64_t json::get<int64_t>(void) const;
347  template<> uint64_t json::get<uint64_t>(void) const;
348  template<> std::string json::get<std::string>(void) const;
349  template<> tsa::date json::get<tsa::date>(void) const;
350  template<> tsa::date_time json::get<tsa::date_time>(void) const;
351  template<> bool json::get<bool>(void) const;
352 
353  // Internal class hierarchy - JsonValue objects are not exposed to users of this API.
354  class json_value {
355  protected:
356  friend class json;
357  friend class JsonInt;
358  friend class JsonDouble;
359  virtual json::Type type() const = 0;
360  virtual bool equals(const json_value * other) const = 0;
361  virtual bool less(const json_value * other) const = 0;
362  virtual void dump(std::string &out) const = 0;
363  virtual double number_value() const;
364  virtual int int_value() const;
365  virtual bool bool_value() const;
366  virtual const std::string &string_value() const;
367  virtual const json::array &array_items() const;
368  virtual const json& operator[](size_t i) const;
369  virtual const json::object &object_items() const;
370  virtual const json& operator[](const std::string &key) const;
371  virtual ~json_value() {}
372  };
373 
374 }// tsa
375 
376 
377 #endif
static json parse(const std::string &in, std::string &err)
Parse. If parse fails, return Json() and assign an error message to err.
Definition: TSAJSON.cpp:785
bool operator==(const json &rhs) const
Definition: TSAJSON.cpp:410
json(const T &t)
Implicit constructor: anything with a to_json() function.
Definition: TSAJSON.h:135
void set_from_iso_string(const std::string &iso_date_string)
Sets the date from the given ISO date string with format: "yyyy-mm-dd". This member function is much ...
Definition: TSATime.cpp:897
bool operator<(const json &rhs) const
Definition: TSAJSON.cpp:417
Namespace for the &#39;Trading System API&#39; library.
Definition: original1.TSA3Core.cpp:20
static std::vector< json > parse_multi(const std::string &in, std::string &err)
Parse multiple objects, concatenated or separated by whitespace.
Definition: TSAJSON.cpp:813
Type
JSON value types.
Definition: TSAJSON.h:87
json(const V &v)
Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc) ...
Definition: TSAJSON.h:146
bool is_object() const
Definition: TSAJSON.h:167
bool is_string() const
Definition: TSAJSON.h:163
bool operator>(const json &rhs) const
Definition: TSAJSON.h:320
variant objects can represent values of different types.
Definition: TSAVariant.h:140
const json & operator[](size_t i) const
Return a reference to arr[i] if this is an array, Json() otherwise.
Definition: TSAJSON.cpp:371
bool is_bool() const
Definition: TSAJSON.h:161
void set_from_iso_string(const std::string &date_time_string)
Sets the date-time from a string in ISO format (yyyy-mm-ddThh:mm:ss:f). This member is very fast...
Definition: TSATime.cpp:2476
bool operator>=(const json &rhs) const
Definition: TSAJSON.h:322
A date of the Gregorian calendar.
Definition: TSATime.h:119
bool operator!=(const json &rhs) const
Definition: TSAJSON.h:316
json(const M &m)
Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
Definition: TSAJSON.h:141
json() noexcept
Constructor.
Definition: TSAJSON.cpp:289
bool operator<=(const json &rhs) const
Definition: TSAJSON.h:318
bool is_null() const
Definition: TSAJSON.h:157
bool bool_value(void) const
Return the enclosed value if this is a boolean, false otherwise.
Definition: TSAJSON.cpp:343
A class representing JSON objects.
Definition: TSAJSON.h:81
const std::string & string_value(void) const
Return the enclosed string if this is a string, "" otherwise.
Definition: TSAJSON.cpp:345
void dump(std::string &out) const
Serialize self.
Definition: TSAJSON.cpp:146
Class representing a gregorian-date and time-of-day combination. The time component has microsecond r...
Definition: TSATime.h:428
int64_t identifier_t
type for ID&#39;s
Definition: TSATypeDef.h:117
bool is_array() const
Definition: TSAJSON.h:165
Type type() const
Accessors.
Definition: TSAJSON.cpp:334
std::initializer_list< std::pair< std::string, Type > > shape
Definition: TSAJSON.h:329
bool is_number() const
Definition: TSAJSON.h:159
int int_value(void) const
Return the enclosed value if this is a int, false otherwise.
Definition: TSAJSON.cpp:341
variant to_variant(void) const
Definition: TSAJSON.cpp:351