CASM  1.1.0
A Clusters Approach to Statistical Mechanics
jsonParser.cc
Go to the documentation of this file.
2 
3 #include <boost/filesystem/fstream.hpp>
4 #include <boost/filesystem/path.hpp>
5 
6 #include "casm/misc/CASM_math.hh"
7 
8 namespace CASM {
9 
11 
12 jsonParser &to_json(bool value, jsonParser &json) {
13  *((json_spirit::mValue *)&json) = json_spirit::mValue(value);
14  return json;
15 }
16 
17 jsonParser &to_json(int value, jsonParser &json) {
18  *((json_spirit::mValue *)&json) = json_spirit::mValue(value);
19  return json;
20 }
21 
22 jsonParser &to_json(unsigned int value, jsonParser &json) {
23  *((json_spirit::mValue *)&json) = json_spirit::mValue(boost::uint64_t(value));
24  return json;
25 }
26 
27 jsonParser &to_json(const long int value, jsonParser &json) {
28  *((json_spirit::mValue *)&json) = json_spirit::mValue(boost::int64_t(value));
29  return json;
30 }
31 
32 jsonParser &to_json(const unsigned long int value, jsonParser &json) {
33  *((json_spirit::mValue *)&json) = json_spirit::mValue(boost::uint64_t(value));
34  return json;
35 }
36 
37 jsonParser &to_json(double value, jsonParser &json) {
38  if (value != value) {
39  return to_json("nan", json);
40  } else if (value == 1.0 / 0.0) {
41  return to_json("inf", json);
42  } else if (value == -1.0 / 0.0) {
43  return to_json("-inf", json);
44  } else {
45  *((json_spirit::mValue *)&json) = json_spirit::mValue(value);
46  return json;
47  }
48 }
49 
50 jsonParser &to_json(const std::string &value, jsonParser &json) {
51  *((json_spirit::mValue *)&json) = json_spirit::mValue(value);
52  return json;
53 }
54 
55 jsonParser &to_json(const char *value, jsonParser &json) {
56  *((json_spirit::mValue *)&json) = json_spirit::mValue(value);
57  return json;
58 }
59 
60 jsonParser &to_json(const jsonParser &value, jsonParser &json) {
61  return json = value;
62 }
63 
69 void to_json(fs::path file_path, jsonParser &json) {
70  if (!json.read(file_path)) {
71  throw std::runtime_error(std::string("ERROR: Could not read JSON file: '") +
72  file_path.string() +
73  "'.\n\nPlease check your formatting. For "
74  "instance, try http://www.jsoneditoronline.org.");
75  }
76 }
77 
78 template <>
79 bool from_json<bool>(const jsonParser &json) {
80  return json.get_bool();
81 }
82 
83 template <>
84 int from_json<int>(const jsonParser &json) {
85  return json.get_int();
86 }
87 
88 template <>
89 unsigned int from_json<unsigned int>(const jsonParser &json) {
90  return (unsigned int)json.get_int();
91 }
92 
93 template <>
94 long int from_json<long int>(const jsonParser &json) {
95  return (long int)json.get_int64();
96 }
97 
98 template <>
99 unsigned long int from_json<unsigned long int>(const jsonParser &json) {
100  return (unsigned long int)json.get_uint64();
101 }
102 
103 template <>
104 double from_json<double>(const jsonParser &json) {
105  double d;
106  from_json(d, json);
107  return d;
108 }
109 
110 template <>
111 std::string from_json<std::string>(const jsonParser &json) {
112  return json.get_str();
113 }
114 
115 template <>
117  return json;
118 }
119 
120 void from_json(bool &value, const jsonParser &json) { value = json.get_bool(); }
121 
122 void from_json(int &value, const jsonParser &json) { value = json.get_int(); }
123 
124 void from_json(unsigned int &value, const jsonParser &json) {
125  value = json.get_int();
126 }
127 
128 void from_json(long int &value, const jsonParser &json) {
129  value = json.get_int64();
130 }
131 
132 void from_json(unsigned long int &value, const jsonParser &json) {
133  value = json.get_uint64();
134 }
135 
136 void from_json(double &value, const jsonParser &json) {
137  if (json.is_string()) {
138  std::string str = json.get_str();
139  if (str == "nan") {
140  value = sqrt(-1.0);
141  } else if (str == "inf") {
142  value = 1.0 / 0.0;
143  } else if (str == "-inf") {
144  value = -1.0 / 0.0;
145  } else {
146  throw std::runtime_error(
147  "Expected json real, received string other than 'nan', 'inf', or "
148  "'-inf': '" +
149  str + "'");
150  }
151  } else {
152  value = json.get_real();
153  }
154 }
155 
156 void from_json(std::string &value, const jsonParser &json) {
157  value = json.get_str();
158 }
159 
160 void from_json(jsonParser &value, const jsonParser &json) { value = json; }
161 
162 void from_json(fs::path &value, const jsonParser &json) {
163  value = fs::path(json.get_str());
164 }
165 
166 // ---- Read/Print JSON ----------------------------------
167 
168 bool jsonParser::read(std::istream &stream) {
169  return json_spirit::read_stream(stream, (json_spirit::mValue &)*this);
170 }
171 
172 bool jsonParser::read(const fs::path &file_path) {
173  fs::ifstream stream(file_path);
174  return read(stream);
175 }
176 
177 std::istream &operator>>(std::istream &stream, jsonParser &json) {
178  if (!json.read(stream)) {
179  std::stringstream msg;
180  msg << "Error: Unable to successfully parse JSON file. File parsed as:\n"
181  << json << "\nPlease correct input file and try again. Exiting...\n";
182  throw std::invalid_argument(msg.str());
183  }
184  return stream;
185 }
186 
188 void jsonParser::print(std::ostream &stream, unsigned int indent,
189  unsigned int prec) const {
190  json_spirit::write_stream((json_spirit::mValue &)*this, stream, indent, prec,
191  json_spirit::pretty_print | json_spirit::raw_utf8 |
192  json_spirit::single_line_arrays);
193 };
194 
196 void jsonParser::write(const std::string &file_name, unsigned int indent,
197  unsigned int prec) const {
198  std::ofstream file(file_name.c_str());
199  print(file, indent, prec);
200  file.close();
201  return;
202 }
203 
205 void jsonParser::write(const fs::path &file_path, unsigned int indent,
206  unsigned int prec) const {
207  fs::ofstream file(file_path);
208  print(file, indent, prec);
209  file.close();
210  return;
211 }
212 
213 std::ostream &operator<<(std::ostream &stream, const jsonParser &json) {
214  json.print(stream);
215  return stream;
216 }
217 
218 bool jsonParser::almost_equal(const jsonParser &B, double tol) const {
219  if (type() != B.type()) {
220  return false;
221  }
222 
223  if (is_array()) {
224  auto f = [=](const jsonParser &_A, const jsonParser &_B) {
225  return _A.almost_equal(_B, tol);
226  };
227  bool res = (size() == B.size() && std::equal(begin(), end(), B.begin(), f));
228  return res;
229  } else if (is_obj()) {
230  if (size() != B.size()) {
231  return false;
232  }
233  auto A_it = begin();
234  auto A_end = end();
235  auto B_it = B.begin();
236  for (; A_it != A_end; ++A_it, ++B_it) {
237  if (A_it.name() != B_it.name() || !A_it->almost_equal(*B_it, tol)) {
238  return false;
239  }
240  }
241  return true;
242  } else if (is_float()) {
243  bool res = CASM::almost_equal(this->get<double>(), B.get<double>(), tol);
244  return res;
245  } else {
246  bool res = (*this == B);
247  return res;
248  }
249 }
250 
251 // ------ Type Checking Methods ------------------------------------
252 
254 bool jsonParser::is_null() const { return type() == json_spirit::null_type; }
255 
257 bool jsonParser::is_bool() const { return type() == json_spirit::bool_type; }
258 
260 bool jsonParser::is_int() const { return type() == json_spirit::int_type; }
261 
263 bool jsonParser::is_float() const { return type() == json_spirit::real_type; }
264 
266 bool jsonParser::is_number() const { return is_int() || is_float(); }
267 
269 bool jsonParser::is_string() const { return type() == json_spirit::str_type; }
270 
272 bool jsonParser::is_obj() const { return type() == json_spirit::obj_type; }
273 
275 bool jsonParser::is_array() const { return type() == json_spirit::array_type; }
276 
277 // ---- Navigate the JSON data: ----------------------------
278 
283 jsonParser &jsonParser::operator[](const std::string &name) {
284  json_spirit::mObject &obj = get_obj();
285  json_spirit::mObject::iterator it = obj.find(name);
286 
287  // if 'name' not found, add it and with value 'null'
288  if (it == obj.end()) {
289  obj[name] = json_spirit::mValue(json_spirit::mObject());
290  }
291  return (jsonParser &)obj[name];
292 }
293 
297 const jsonParser &jsonParser::operator[](const std::string &name) const {
298  const json_spirit::mObject &obj = get_obj();
299  json_spirit::mObject::const_iterator it = obj.find(name);
300 
301  // if 'name' not found, add it and with value 'null'
302  if (it == obj.end()) {
303  throw std::runtime_error("JSON const operator[] access, but " + name +
304  " does not exist");
305  }
306  return (const jsonParser &)it->second;
307 }
308 
316 jsonParser &jsonParser::at(const fs::path &path) {
317  return const_cast<jsonParser &>(
318  static_cast<const jsonParser *>(this)->at(path));
319 }
320 
328 const jsonParser &jsonParser::at(const fs::path &path) const {
329  if (!path.is_relative()) {
330  throw std::invalid_argument(
331  "Error in jsonParser::operator[](const fs::path &path): path must be "
332  "relative");
333  }
334  const jsonParser *curr = this;
335  for (auto it = path.begin(); it != path.end(); ++it) {
336  if (curr->is_array()) {
337  int index;
338  try {
339  index = std::stoi(it->string());
340  } catch (std::exception &e) {
341  fs::path curr_path;
342  for (auto tmp_it = path.begin(); tmp_it != path.end(); ++tmp_it) {
343  curr_path /= tmp_it->string();
344  if (tmp_it == it) {
345  break;
346  }
347  }
348 
349  std::stringstream msg;
350  msg << "Error in jsonParser::at: stoi error when attempting to access "
351  "array element. "
352  << "path: '" << path << "' "
353  << "curr_path: '" << curr_path << "'";
354  throw std::invalid_argument(msg.str());
355  }
356  if (curr->size() > index) {
357  curr = &((*curr)[index]);
358  } else {
359  std::stringstream msg;
360  msg << "Error in jsonParser::at: attempted to access element outside "
361  "of array range. "
362  << "path: '" << path << "' "
363  << "index: " << index << " "
364  << "curr->size(): " << curr->size();
365  throw std::invalid_argument(msg.str());
366  }
367  } else {
368  auto res = curr->find(it->string());
369  if (res != curr->end()) {
370  curr = &((*curr)[it->string()]);
371  } else {
372  std::stringstream msg;
373  msg << "Error in jsonParser::at: key '" << it->string()
374  << "' not found at '" << path << "'.";
375  throw std::invalid_argument(msg.str());
376  }
377  }
378  }
379 
380  return *curr;
381 }
382 
386  return (jsonParser &)get_array()[element];
387 }
388 
391 const jsonParser &jsonParser::operator[](const size_type &element) const {
392  return (const jsonParser &)get_array()[element];
393 }
394 
398  if (!is_array()) {
399  throw std::invalid_argument(
400  "Error in jsonParser::at: attempting to access non-array with index");
401  }
402  if (!(element < size())) {
403  throw std::out_of_range("Error in jsonParser::at: out of range");
404  }
405  return (jsonParser &)get_array()[element];
406 }
407 
410 const jsonParser &jsonParser::at(const size_type &element) const {
411  if (!is_array()) {
412  throw std::invalid_argument(
413  "Error in jsonParser::at: attempting to access non-array with index");
414  }
415  if (!(element < size())) {
416  throw std::out_of_range("Error in jsonParser::at: out of range");
417  }
418  return (const jsonParser &)get_array()[element];
419 }
420 
421 namespace {
423 fs::path find_diff(const jsonParser &A, const jsonParser &B, fs::path diff) {
424  auto A_it = A.cbegin();
425  auto B_it = B.cbegin();
426  while (A_it != A.cend()) {
427  if (*A_it != *B_it) {
428  if (A.is_obj() && B.is_obj()) {
429  return find_diff(*A_it, *B_it, diff / A_it.name());
430  } else if (A.is_array() && B.is_array()) {
431  std::stringstream ss;
432  ss << std::distance(A.cbegin(), A_it);
433  return find_diff(*A_it, *B_it, diff / ss.str());
434  }
435  return diff;
436  }
437  ++A_it;
438  ++B_it;
439  }
440  return diff;
441 }
442 
445 fs::path find_diff(const jsonParser &A, const jsonParser &B, double tol,
446  fs::path diff) {
447  auto A_it = A.cbegin();
448  auto B_it = B.cbegin();
449  while (A_it != A.cend()) {
450  if (!A_it->almost_equal(*B_it, tol)) {
451  if (A.is_obj() && B.is_obj()) {
452  if (A.size() != B.size()) {
453  return diff;
454  }
455  return find_diff(*A_it, *B_it, tol, diff / A_it.name());
456  } else if (A.is_array() && B.is_array()) {
457  if (A.size() != B.size()) {
458  return diff;
459  }
460  std::stringstream ss;
461  ss << std::distance(A.cbegin(), A_it);
462  return find_diff(*A_it, *B_it, tol, diff / ss.str());
463  }
464  return diff;
465  }
466  ++A_it;
467  ++B_it;
468  }
469  return diff;
470 }
471 
472 } // namespace
473 
475 fs::path find_diff(const jsonParser &A, const jsonParser &B) {
476  return find_diff(A, B, fs::path());
477 }
478 
481 fs::path find_diff(const jsonParser &A, const jsonParser &B, double tol) {
482  return find_diff(A, B, tol, fs::path());
483 }
484 
488  if (is_obj())
489  return get_obj().size();
490  else if (is_array())
491  return get_array().size();
492  else
493  return 1;
494 }
495 
498  if (is_obj())
499  return iterator(this, get_obj().begin());
500  else if (is_array())
501  return iterator(this, get_array().begin());
502  else
503  return iterator(this, 0);
504 }
505 
508 
511  if (is_obj())
512  return const_iterator(this, get_obj().cbegin());
513  else if (is_array())
514  return const_iterator(this, get_array().cbegin());
515  else
516  return const_iterator(this, 0);
517 }
518 
521  if (is_obj())
522  return iterator(this, get_obj().end());
523  else if (is_array())
524  return iterator(this, get_array().end());
525  else
526  return iterator(this, 1);
527 }
528 
531 
534  if (is_obj())
535  return const_iterator(this, get_obj().cend());
536  else if (is_array())
537  return const_iterator(this, get_array().cend());
538  else
539  return const_iterator(this, 1);
540 }
541 
544  return iterator(this, get_obj().find(name));
545 }
546 
549  return const_iterator(this, get_obj().find(name));
550 }
551 
557  if (!path.is_relative()) {
558  throw std::invalid_argument(
559  "Error in jsonParser::operator[](const fs::path &path): path must be "
560  "relative");
561  }
562  if (path.empty()) {
563  return jsonParser::iterator(this, 0);
564  }
565  jsonParser *curr = this;
566  jsonParser::iterator res = this->end();
567  for (auto it = path.begin(); it != path.end(); ++it) {
568  if (curr->is_array()) {
569  int index = std::stoi(it->string());
570  if (curr->size() > index) {
571  res = curr->begin();
572  for (int i = 0; i < index; ++i) {
573  ++res;
574  }
575  curr = &(*res);
576  } else {
577  return this->end();
578  }
579  } else {
580  res = curr->find(it->string());
581  if (res != curr->end()) {
582  curr = &((*curr)[it->string()]);
583  } else {
584  return this->end();
585  }
586  }
587  }
588 
589  return res;
590 }
591 
596 jsonParser::const_iterator jsonParser::find_at(const fs::path &path) const {
597  return const_cast<jsonParser *>(this)->find_at(path);
598 }
599 
601 bool jsonParser::contains(const std::string &name) const {
602  return find(name) != cend();
603 }
604 
608  return get_obj().erase(name);
609 }
610 
611 // ---- static Methods -------------------------------------
612 
614 jsonParser jsonParser::parse(const fs::path &path) { return jsonParser(path); }
615 
616 template <bool IsConst>
618 
619 template <bool IsConst>
621  : parser(iter.parser),
622  type(iter.type),
623  obj_iter(iter.obj_iter),
624  array_iter(iter.array_iter),
625  val_iter(iter.val_iter) {}
626 
627 template <bool IsConst>
629  jsonParserIterator iter) {
630  swap(*this, iter);
631  return *this;
632 }
633 
634 template <bool IsConst>
638  : parser(j), type(json_spirit::obj_type), obj_iter(iter) {}
639 
640 template <bool IsConst>
643  const typename jsonParserIterator<IsConst>::array_iterator &iter)
644  : parser(j), type(json_spirit::array_type), array_iter(iter) {}
645 
646 template <bool IsConst>
648  typename jsonParserIterator<IsConst>::pointer j, const int &iter)
649  : parser(j), type(json_spirit::null_type), val_iter(iter) {}
650 
651 template <bool IsConst>
654  if (type == json_spirit::obj_type)
655  return (reference)obj_iter->second;
656  else if (type == json_spirit::array_type)
657  return (reference)*array_iter;
658  else
659  return *parser;
660 }
661 
662 template <bool IsConst>
665  if (type == json_spirit::obj_type)
666  return (pointer)&obj_iter->second;
667  else if (type == json_spirit::array_type)
668  return (pointer) & (*array_iter);
669  else
670  return parser;
671 }
672 
673 template <bool IsConst>
675  const jsonParserIterator &iter) const {
676  if (parser != iter.parser) {
677  return false;
678  }
679 
680  bool this_is_end = this->is_end();
681  bool that_is_end = iter.is_end();
682 
683  if (this_is_end && that_is_end) {
684  return true;
685  } else if (this_is_end != that_is_end) {
686  return false;
687  } else {
688  if (type == json_spirit::obj_type) {
689  return obj_iter == iter.obj_iter;
690  } else if (type == json_spirit::array_type) {
691  return array_iter == iter.array_iter;
692  } else if (type == json_spirit::null_type) {
693  return val_iter == iter.val_iter;
694  }
695  }
696 
697  return false;
698 }
699 
700 template <bool IsConst>
702  if (type == json_spirit::obj_type && obj_iter == parser->get_obj().end()) {
703  return true;
704  } else if (type == json_spirit::array_type &&
705  array_iter == parser->get_array().end()) {
706  return true;
707  } else if (type == json_spirit::null_type && val_iter == 1) {
708  return true;
709  }
710  return false;
711 }
712 
713 template <bool IsConst>
715  const jsonParserIterator &iter) const {
716  return !(*this == iter);
717 }
718 
719 template <bool IsConst>
721  if (type == json_spirit::obj_type) {
722  ++obj_iter;
723  return *this;
724  } else if (type == json_spirit::array_type) {
725  ++array_iter;
726  return *this;
727  } else {
728  ++val_iter;
729  return *this;
730  }
731 }
732 
733 template <bool IsConst>
735  jsonParserIterator cp(*this);
736 
737  if (type == json_spirit::obj_type) {
738  ++obj_iter;
739  return cp;
740  } else if (type == json_spirit::array_type) {
741  ++array_iter;
742  return cp;
743  } else {
744  ++val_iter;
745  return cp;
746  }
747 }
748 
749 template <bool IsConst>
751  if (type == json_spirit::obj_type) {
752  --obj_iter;
753  return *this;
754  } else if (type == json_spirit::array_type) {
755  --array_iter;
756  return *this;
757  } else {
758  --val_iter;
759  return *this;
760  }
761 }
762 
763 template <bool IsConst>
765  jsonParserIterator<IsConst> cp(*this);
766 
767  if (type == json_spirit::obj_type) {
768  --obj_iter;
769  return cp;
770  } else if (type == json_spirit::array_type) {
771  --array_iter;
772  return cp;
773  } else {
774  --val_iter;
775  return cp;
776  }
777 }
778 
779 template <bool IsConst>
781  if (type == json_spirit::obj_type)
782  return jsonParser::const_iterator(parser, obj_iter);
783  else if (type == json_spirit::array_type)
784  return jsonParser::const_iterator(parser, array_iter);
785  else
786  return jsonParser::const_iterator(parser, val_iter);
787 }
788 
791 template <bool IsConst>
793  if (type == json_spirit::obj_type)
794  return obj_iter->first;
795  else
796  throw std::runtime_error("Calling 'name' on non-object jsonParserIterator");
797 }
798 
799 template <bool IsConst>
801  using std::swap;
802 
803  std::swap(a.parser, b.parser);
804  swap(a.type, b.type);
805  swap(a.obj_iter, b.obj_iter);
806  swap(a.array_iter, b.array_iter);
807  swap(a.val_iter, b.val_iter);
808 }
809 
810 template class jsonParserIterator<true>;
811 template class jsonParserIterator<false>;
816 
817 } // namespace CASM
bool is_string() const
Check if string.
Definition: jsonParser.cc:269
jsonParser()
Create a new empty jsonParser.
Definition: jsonParser.hh:94
iterator begin()
Returns const_iterator to beginning of JSON object or JSON array.
Definition: jsonParser.cc:497
bool contains(const std::string &name) const
Return true if JSON object contains 'name'.
Definition: jsonParser.cc:601
iterator end()
Returns iterator to end of JSON object or JSON array.
Definition: jsonParser.cc:520
size_type size() const
Definition: jsonParser.cc:487
bool is_array() const
Check if array type.
Definition: jsonParser.cc:275
jsonParserIterator< false > iterator
Definition: jsonParser.hh:88
json_spirit::mObject::size_type size_type
Definition: jsonParser.hh:87
bool read(std::istream &stream)
Reads json from the stream.
Definition: jsonParser.cc:168
const_iterator cend() const
Returns const_iterator to end of JSON object or JSON array.
Definition: jsonParser.cc:533
jsonParser & at(const fs::path &path)
Definition: jsonParser.cc:316
iterator find(const std::string &name)
Return iterator to JSON object value with 'name'.
Definition: jsonParser.cc:543
jsonParser & operator[](const std::string &name)
Definition: jsonParser.cc:283
void write(const std::string &file_name, unsigned int indent=2, unsigned int prec=12) const
Write json to file.
Definition: jsonParser.cc:196
bool is_float() const
Check if number type (not including int)
Definition: jsonParser.cc:263
jsonParserIterator< true > const_iterator
Definition: jsonParser.hh:89
bool is_int() const
Check if int type.
Definition: jsonParser.cc:260
bool is_null() const
Check if null type.
Definition: jsonParser.cc:254
bool is_number() const
Check if number type (including int)
Definition: jsonParser.cc:266
bool is_bool() const
Check if bool type.
Definition: jsonParser.cc:257
size_type erase(const std::string &name)
Erase key:value pair from an object.
Definition: jsonParser.cc:607
static jsonParser parse(const std::string &str)
Construct a jsonParser from a string containing JSON data.
Definition: jsonParser.hh:382
const_iterator cbegin() const
Returns const_iterator to beginning of JSON object or JSON array.
Definition: jsonParser.cc:510
jsonParser::iterator find_at(const fs::path &path)
Return iterator to sub-object or element, or 'end' if not found.
Definition: jsonParser.cc:556
bool almost_equal(const jsonParser &B, double tol) const
Definition: jsonParser.cc:218
bool is_obj() const
Check if object type.
Definition: jsonParser.cc:272
void print(std::ostream &stream, unsigned int indent=2, unsigned int prec=12) const
Print json to stream.
Definition: jsonParser.cc:188
std::conditional< IsConst, json_spirit::mObject::const_iterator, json_spirit::mObject::iterator >::type object_iterator
Definition: jsonParser.hh:618
pointer operator->() const
Definition: jsonParser.cc:664
object_iterator obj_iter
Definition: jsonParser.hh:674
array_iterator array_iter
Definition: jsonParser.hh:676
jsonParserIterator & operator--()
Definition: jsonParser.cc:750
jsonParserIterator & operator++()
Definition: jsonParser.cc:720
std::conditional< IsConst, json_spirit::mArray::const_iterator, json_spirit::mArray::iterator >::type array_iterator
Definition: jsonParser.hh:622
json_spirit::Value_type type
Definition: jsonParser.hh:672
bool operator!=(const jsonParserIterator &iter) const
Definition: jsonParser.cc:714
std::string name() const
Definition: jsonParser.cc:792
bool operator==(const jsonParserIterator &iter) const
Definition: jsonParser.cc:674
reference operator*() const
Definition: jsonParser.cc:653
jsonParserIterator & operator=(jsonParserIterator iter)
Definition: jsonParser.cc:628
double from_json< double >(const jsonParser &json)
Definition: jsonParser.cc:104
fs::path find_diff(const jsonParser &A, const jsonParser &B)
Return the location at which jsonParser 'A' != 'B' as a fs::path.
Definition: jsonParser.cc:475
bool from_json< bool >(const jsonParser &json)
Definition: jsonParser.cc:79
unsigned int from_json< unsigned int >(const jsonParser &json)
Definition: jsonParser.cc:89
jsonParser from_json< jsonParser >(const jsonParser &json)
Definition: jsonParser.cc:116
int from_json< int >(const jsonParser &json)
Definition: jsonParser.cc:84
unsigned long int from_json< unsigned long int >(const jsonParser &json)
Definition: jsonParser.cc:99
long int from_json< long int >(const jsonParser &json)
Definition: jsonParser.cc:94
T get(Args &&... args) const
Get data from json, using one of several alternatives.
Definition: jsonParser.hh:716
Main CASM namespace.
Definition: APICommand.hh:8
bool almost_equal(ClusterInvariants const &A, ClusterInvariants const &B, double tol)
Check if ClusterInvariants are equal.
std::ostream & operator<<(std::ostream &_stream, const FormattedPrintable &_formatted)
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
std::istream & operator>>(std::istream &_in, std::vector< T > &vec)
Definition: stream_io.hh:10
void swap(ConfigDoF &A, ConfigDoF &B)
Definition: ConfigDoF.cc:260
void swap(jsonParserIterator< IsConst > &a, jsonParserIterator< IsConst > &b)
Definition: jsonParser.cc:800
GenericDatumFormatter< std::string, DataObject > name()
void from_json(ClexDescription &desc, const jsonParser &json)
template void swap< false >(jsonParserIterator< false > &, jsonParserIterator< false > &)
template void swap< true >(jsonParserIterator< true > &, jsonParserIterator< true > &)