3 #include <boost/filesystem/fstream.hpp>
4 #include <boost/filesystem/path.hpp>
13 *((json_spirit::mValue *)&json) = json_spirit::mValue(value);
18 *((json_spirit::mValue *)&json) = json_spirit::mValue(value);
23 *((json_spirit::mValue *)&json) = json_spirit::mValue(boost::uint64_t(value));
28 *((json_spirit::mValue *)&json) = json_spirit::mValue(boost::int64_t(value));
33 *((json_spirit::mValue *)&json) = json_spirit::mValue(boost::uint64_t(value));
40 }
else if (value == 1.0 / 0.0) {
42 }
else if (value == -1.0 / 0.0) {
45 *((json_spirit::mValue *)&json) = json_spirit::mValue(value);
51 *((json_spirit::mValue *)&json) = json_spirit::mValue(value);
56 *((json_spirit::mValue *)&json) = json_spirit::mValue(value);
70 if (!json.
read(file_path)) {
71 throw std::runtime_error(std::string(
"ERROR: Could not read JSON file: '") +
73 "'.\n\nPlease check your formatting. For "
74 "instance, try http://www.jsoneditoronline.org.");
80 return json.get_bool();
85 return json.get_int();
90 return (
unsigned int)json.get_int();
95 return (
long int)json.get_int64();
100 return (
unsigned long int)json.get_uint64();
112 return json.get_str();
125 value = json.get_int();
129 value = json.get_int64();
133 value = json.get_uint64();
138 std::string str = json.get_str();
141 }
else if (str ==
"inf") {
143 }
else if (str ==
"-inf") {
146 throw std::runtime_error(
147 "Expected json real, received string other than 'nan', 'inf', or "
152 value = json.get_real();
157 value = json.get_str();
163 value = fs::path(json.get_str());
169 return json_spirit::read_stream(stream, (json_spirit::mValue &)*
this);
173 fs::ifstream stream(file_path);
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());
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);
197 unsigned int prec)
const {
198 std::ofstream file(file_name.c_str());
199 print(file, indent, prec);
206 unsigned int prec)
const {
207 fs::ofstream file(file_path);
208 print(file, indent, prec);
219 if (type() != B.type()) {
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)) {
246 bool res = (*
this == B);
284 json_spirit::mObject &obj = get_obj();
285 json_spirit::mObject::iterator it = obj.find(
name);
288 if (it == obj.end()) {
289 obj[
name] = json_spirit::mValue(json_spirit::mObject());
298 const json_spirit::mObject &obj = get_obj();
299 json_spirit::mObject::const_iterator it = obj.find(
name);
302 if (it == obj.end()) {
303 throw std::runtime_error(
"JSON const operator[] access, but " +
name +
329 if (!path.is_relative()) {
330 throw std::invalid_argument(
331 "Error in jsonParser::operator[](const fs::path &path): path must be "
335 for (
auto it = path.begin(); it != path.end(); ++it) {
339 index = std::stoi(it->string());
340 }
catch (std::exception &e) {
342 for (
auto tmp_it = path.begin(); tmp_it != path.end(); ++tmp_it) {
343 curr_path /= tmp_it->string();
349 std::stringstream msg;
350 msg <<
"Error in jsonParser::at: stoi error when attempting to access "
352 <<
"path: '" << path <<
"' "
353 <<
"curr_path: '" << curr_path <<
"'";
354 throw std::invalid_argument(msg.str());
356 if (curr->
size() > index) {
357 curr = &((*curr)[index]);
359 std::stringstream msg;
360 msg <<
"Error in jsonParser::at: attempted to access element outside "
362 <<
"path: '" << path <<
"' "
363 <<
"index: " << index <<
" "
364 <<
"curr->size(): " << curr->
size();
365 throw std::invalid_argument(msg.str());
368 auto res = curr->
find(it->string());
369 if (res != curr->
end()) {
370 curr = &((*curr)[it->string()]);
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());
392 return (
const jsonParser &)get_array()[element];
399 throw std::invalid_argument(
400 "Error in jsonParser::at: attempting to access non-array with index");
402 if (!(element <
size())) {
403 throw std::out_of_range(
"Error in jsonParser::at: out of range");
412 throw std::invalid_argument(
413 "Error in jsonParser::at: attempting to access non-array with index");
415 if (!(element <
size())) {
416 throw std::out_of_range(
"Error in jsonParser::at: out of range");
418 return (
const jsonParser &)get_array()[element];
426 while (A_it != A.
cend()) {
427 if (*A_it != *B_it) {
429 return find_diff(*A_it, *B_it, diff / A_it.name());
431 std::stringstream ss;
432 ss << std::distance(A.
cbegin(), A_it);
433 return find_diff(*A_it, *B_it, diff / ss.str());
445 fs::path
find_diff(
const jsonParser &A,
const jsonParser &B,
double tol,
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()) {
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()) {
460 std::stringstream ss;
461 ss << std::distance(A.cbegin(), A_it);
462 return find_diff(*A_it, *B_it, tol, diff / ss.str());
489 return get_obj().size();
491 return get_array().size();
557 if (!path.is_relative()) {
558 throw std::invalid_argument(
559 "Error in jsonParser::operator[](const fs::path &path): path must be "
567 for (
auto it = path.begin(); it != path.end(); ++it) {
569 int index = std::stoi(it->string());
570 if (curr->
size() > index) {
572 for (
int i = 0; i < index; ++i) {
580 res = curr->
find(it->string());
581 if (res != curr->
end()) {
582 curr = &((*curr)[it->string()]);
608 return get_obj().erase(
name);
616 template <
bool IsConst>
619 template <
bool IsConst>
621 : parser(iter.parser),
623 obj_iter(iter.obj_iter),
624 array_iter(iter.array_iter),
625 val_iter(iter.val_iter) {}
627 template <
bool IsConst>
634 template <
bool IsConst>
638 : parser(j), type(json_spirit::obj_type), obj_iter(iter) {}
640 template <
bool IsConst>
644 : parser(j), type(json_spirit::array_type), array_iter(iter) {}
646 template <
bool IsConst>
649 : parser(j), type(json_spirit::null_type), val_iter(iter) {}
651 template <
bool IsConst>
654 if (type == json_spirit::obj_type)
656 else if (type == json_spirit::array_type)
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);
673 template <
bool IsConst>
676 if (parser != iter.
parser) {
680 bool this_is_end = this->is_end();
681 bool that_is_end = iter.
is_end();
683 if (this_is_end && that_is_end) {
685 }
else if (this_is_end != that_is_end) {
688 if (type == json_spirit::obj_type) {
690 }
else if (type == json_spirit::array_type) {
692 }
else if (type == json_spirit::null_type) {
700 template <
bool IsConst>
702 if (type == json_spirit::obj_type && obj_iter == parser->get_obj().end()) {
704 }
else if (type == json_spirit::array_type &&
705 array_iter == parser->get_array().end()) {
707 }
else if (type == json_spirit::null_type && val_iter == 1) {
713 template <
bool IsConst>
716 return !(*
this == iter);
719 template <
bool IsConst>
721 if (type == json_spirit::obj_type) {
724 }
else if (type == json_spirit::array_type) {
733 template <
bool IsConst>
737 if (type == json_spirit::obj_type) {
740 }
else if (type == json_spirit::array_type) {
749 template <
bool IsConst>
751 if (type == json_spirit::obj_type) {
754 }
else if (type == json_spirit::array_type) {
763 template <
bool IsConst>
767 if (type == json_spirit::obj_type) {
770 }
else if (type == json_spirit::array_type) {
779 template <
bool IsConst>
781 if (type == json_spirit::obj_type)
783 else if (type == json_spirit::array_type)
791 template <
bool IsConst>
793 if (type == json_spirit::obj_type)
794 return obj_iter->first;
796 throw std::runtime_error(
"Calling 'name' on non-object jsonParserIterator");
799 template <
bool IsConst>
810 template class jsonParserIterator<true>;
811 template class jsonParserIterator<false>;
bool is_string() const
Check if string.
jsonParser()
Create a new empty jsonParser.
iterator begin()
Returns const_iterator to beginning of JSON object or JSON array.
bool contains(const std::string &name) const
Return true if JSON object contains 'name'.
iterator end()
Returns iterator to end of JSON object or JSON array.
bool is_array() const
Check if array type.
jsonParserIterator< false > iterator
json_spirit::mObject::size_type size_type
bool read(std::istream &stream)
Reads json from the stream.
const_iterator cend() const
Returns const_iterator to end of JSON object or JSON array.
jsonParser & at(const fs::path &path)
iterator find(const std::string &name)
Return iterator to JSON object value with 'name'.
jsonParser & operator[](const std::string &name)
void write(const std::string &file_name, unsigned int indent=2, unsigned int prec=12) const
Write json to file.
bool is_float() const
Check if number type (not including int)
jsonParserIterator< true > const_iterator
bool is_int() const
Check if int type.
bool is_null() const
Check if null type.
bool is_number() const
Check if number type (including int)
bool is_bool() const
Check if bool type.
size_type erase(const std::string &name)
Erase key:value pair from an object.
static jsonParser parse(const std::string &str)
Construct a jsonParser from a string containing JSON data.
const_iterator cbegin() const
Returns const_iterator to beginning of JSON object or JSON array.
jsonParser::iterator find_at(const fs::path &path)
Return iterator to sub-object or element, or 'end' if not found.
bool almost_equal(const jsonParser &B, double tol) const
bool is_obj() const
Check if object type.
void print(std::ostream &stream, unsigned int indent=2, unsigned int prec=12) const
Print json to stream.
std::conditional< IsConst, json_spirit::mObject::const_iterator, json_spirit::mObject::iterator >::type object_iterator
pointer operator->() const
array_iterator array_iter
jsonParserIterator & operator--()
jsonParserIterator & operator++()
std::conditional< IsConst, json_spirit::mArray::const_iterator, json_spirit::mArray::iterator >::type array_iterator
json_spirit::Value_type type
bool operator!=(const jsonParserIterator &iter) const
bool operator==(const jsonParserIterator &iter) const
reference operator*() const
jsonParserIterator & operator=(jsonParserIterator iter)
double from_json< double >(const jsonParser &json)
fs::path find_diff(const jsonParser &A, const jsonParser &B)
Return the location at which jsonParser 'A' != 'B' as a fs::path.
bool from_json< bool >(const jsonParser &json)
unsigned int from_json< unsigned int >(const jsonParser &json)
jsonParser from_json< jsonParser >(const jsonParser &json)
int from_json< int >(const jsonParser &json)
unsigned long int from_json< unsigned long int >(const jsonParser &json)
long int from_json< long int >(const jsonParser &json)
T get(Args &&... args) const
Get data from json, using one of several alternatives.
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)
void swap(ConfigDoF &A, ConfigDoF &B)
void swap(jsonParserIterator< IsConst > &a, jsonParserIterator< IsConst > &b)
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 > &)