Medial Code Documentation
Loading...
Searching...
No Matches
json.h
Go to the documentation of this file.
1
7#ifndef DMLC_JSON_H_
8#define DMLC_JSON_H_
9
10// This code requires C++11 to compile
11#include <vector>
12#ifndef _LIBCPP_SGX_NO_IOSTREAMS
13#include <iostream>
14#include <sstream>
15#endif
16#include <cctype>
17#include <string>
18#include <algorithm>
19#include <map>
20#include <list>
21#include <utility>
22
23#include "./base.h"
24#include "./logging.h"
25#include "./type_traits.h"
26
27#if DMLC_USE_CXX11
28#include <typeindex>
29#include <typeinfo>
30#include <unordered_map>
31#if DMLC_STRICT_CXX11
32#if DMLC_ENABLE_RTTI
33#include "./any.h"
34#endif // DMLC_ENABLE_RTTI
35#endif // DMLC_STRICT_CXX11
36#endif // DMLC_USE_CXX11
37
38namespace dmlc {
45 public:
50#ifndef _LIBCPP_SGX_NO_IOSTREAMS
51 explicit JSONReader(std::istream *is)
52#else
53 explicit JSONReader(std::string *is)
54#endif
55 : is_(is),
56 line_count_r_(0),
57 line_count_n_(0) {}
63 inline void ReadString(std::string *out_str);
70 template<typename ValueType>
71 inline void ReadNumber(ValueType *out_value);
85 inline void BeginObject();
98 inline void BeginArray();
106 inline bool NextObjectItem(std::string *out_key);
113 inline bool NextArrayItem();
120 template<typename ValueType>
121 inline void Read(ValueType *out_value);
122
124 inline std::string line_info() const {
125#ifndef _LIBCPP_SGX_NO_IOSTREAMS
126 char temp[64];
127 std::ostringstream os;
128 os << " Line " << std::max(line_count_r_, line_count_n_);
129 is_->getline(temp, 64);
130 os << ", around ^`" << temp << "`";
131 return os.str();
132#else
133 std::string info = " Line ";
134 info += std::to_string(std::max(line_count_r_, line_count_n_));
135
136 // string getline
137 size_t end_pos = is_->find('\n');
138 end_pos = std::min(static_cast<size_t>(64),
139 end_pos == std::string::npos ? is_->size() : end_pos);
140 std::string line = is_->substr(0, end_pos);
141 is_->erase(0, line.size() + 1); // +1 for \n
142
143 info += ", around ^`" + line + "`";
144 return info;
145#endif
146 }
147
148 private:
149#ifndef _LIBCPP_SGX_NO_IOSTREAMS
151 std::istream *is_;
152#else
154 std::string *is_;
155#endif
157 size_t line_count_r_;
159 size_t line_count_n_;
164 std::vector<size_t> scope_counter_;
169 inline int NextNonSpace();
174 inline int PeekNextNonSpace();
179 inline int NextChar();
184 inline int PeekNextChar();
185};
186
191 public:
196#ifndef _LIBCPP_SGX_NO_IOSTREAMS
197 explicit JSONWriter(std::ostream *os)
198#else
199 explicit JSONWriter(std::string *os)
200#endif
201 : os_(os) {}
206 inline void WriteNoEscape(const std::string &s);
211 inline void WriteString(const std::string &s);
217 template<typename ValueType>
218 inline void WriteNumber(const ValueType &v);
230 inline void BeginArray(bool multi_line = true);
232 inline void EndArray();
244 inline void BeginObject(bool multi_line = true);
246 inline void EndObject();
253 template<typename ValueType>
254 inline void WriteObjectKeyValue(const std::string &key,
255 const ValueType &value);
260 inline void WriteArraySeperator();
266 template<typename ValueType>
267 inline void WriteArrayItem(const ValueType &value);
273 template<typename ValueType>
274 inline void Write(const ValueType &value);
275
276 private:
277#ifndef _LIBCPP_SGX_NO_IOSTREAMS
279 std::ostream *os_;
280#else
281 std::string *os_;
282#endif
287 std::vector<size_t> scope_counter_;
289 std::vector<bool> scope_multi_line_;
293 inline void WriteSeperator();
294};
295
313 public:
320 template<typename T>
321 inline void DeclareField(const std::string &key, T *addr) {
322 DeclareFieldInternal(key, addr, false);
323 }
330 template<typename T>
331 inline void DeclareOptionalField(const std::string &key, T *addr) {
332 DeclareFieldInternal(key, addr, true);
333 }
338 inline void ReadAllFields(JSONReader *reader);
339
340 private:
348 template<typename T>
349 inline void DeclareFieldInternal(const std::string &key, T *addr, bool optional);
355 template<typename T>
356 inline static void ReaderFunction(JSONReader *reader, void *addr);
358 typedef void (*ReadFunction)(JSONReader *reader, void *addr);
360 struct Entry {
362 ReadFunction func;
364 void *addr;
366 bool optional;
367 };
369 std::map<std::string, Entry> map_;
370};
371
372#define DMLC_JSON_ENABLE_ANY_VAR_DEF(KeyName) \
373 static DMLC_ATTRIBUTE_UNUSED ::dmlc::json::AnyJSONManager& \
374 __make_AnyJSONType ## _ ## KeyName ## __
375
384#define DMLC_JSON_ENABLE_ANY(Type, KeyName) \
385 DMLC_STR_CONCAT(DMLC_JSON_ENABLE_ANY_VAR_DEF(KeyName), __COUNTER__) = \
386 ::dmlc::json::AnyJSONManager::Global()->EnableType<Type>(#KeyName) \
387
389namespace json {
390
395template<typename T>
396struct Handler;
397
398template<typename ValueType>
399struct NumericHandler {
400 inline static void Write(JSONWriter *writer, const ValueType &value) {
401 writer->WriteNumber<ValueType>(value);
402 }
403 inline static void Read(JSONReader *reader, ValueType *value) {
404 reader->ReadNumber<ValueType>(value);
405 }
406};
407
408template<typename ContainerType>
409struct ArrayHandler {
410 inline static void Write(JSONWriter *writer, const ContainerType &array) {
411 typedef typename ContainerType::value_type ElemType;
412 writer->BeginArray(array.size() > 10 || !dmlc::is_pod<ElemType>::value);
413 for (typename ContainerType::const_iterator it = array.begin();
414 it != array.end(); ++it) {
415 writer->WriteArrayItem(*it);
416 }
417 writer->EndArray();
418 }
419 inline static void Read(JSONReader *reader, ContainerType *array) {
420 typedef typename ContainerType::value_type ElemType;
421 array->clear();
422 reader->BeginArray();
423 while (reader->NextArrayItem()) {
424 ElemType value;
425 Handler<ElemType>::Read(reader, &value);
426 array->insert(array->end(), value);
427 }
428 }
429};
430
431template<typename ContainerType>
432struct MapHandler{
433 inline static void Write(JSONWriter *writer, const ContainerType &map) {
434 writer->BeginObject(map.size() > 1);
435 for (typename ContainerType::const_iterator it = map.begin(); it != map.end(); ++it) {
436 writer->WriteObjectKeyValue(it->first, it->second);
437 }
438 writer->EndObject();
439 }
440 inline static void Read(JSONReader *reader, ContainerType *map) {
441 typedef typename ContainerType::mapped_type ElemType;
442 map->clear();
443 reader->BeginObject();
444 std::string key;
445 while (reader->NextObjectItem(&key)) {
446 ElemType value;
447 reader->Read(&value);
448 (*map)[key] = value;
449 }
450 }
451};
452
453template<typename T>
454struct CommonJSONSerializer {
455 inline static void Write(JSONWriter *writer, const T &value) {
456 value.Save(writer);
457 }
458 inline static void Read(JSONReader *reader, T *value) {
459 value->Load(reader);
460 }
461};
462
463template<>
464struct Handler<std::string> {
465 inline static void Write(JSONWriter *writer, const std::string &value) {
466 writer->WriteString(value);
467 }
468 inline static void Read(JSONReader *reader, std::string *str) {
469 reader->ReadString(str);
470 }
471};
472
473template<typename T>
474struct Handler<std::vector<T> > : public ArrayHandler<std::vector<T> > {
475};
476
477template<typename K, typename V>
478struct Handler<std::pair<K, V> > {
479 inline static void Write(JSONWriter *writer, const std::pair<K, V> &kv) {
480 writer->BeginArray();
481 writer->WriteArrayItem(kv.first);
482 writer->WriteArrayItem(kv.second);
483 writer->EndArray();
484 }
485 inline static void Read(JSONReader *reader, std::pair<K, V> *kv) {
486 reader->BeginArray();
487 CHECK(reader->NextArrayItem())
488 << "Expect array of length 2";
489 Handler<K>::Read(reader, &(kv->first));
490 CHECK(reader->NextArrayItem())
491 << "Expect array of length 2";
492 Handler<V>::Read(reader, &(kv->second));
493 CHECK(!reader->NextArrayItem())
494 << "Expect array of length 2";
495 }
496};
497
498template<typename T>
499struct Handler<std::list<T> > : public ArrayHandler<std::list<T> > {
500};
501
502template<typename V>
503struct Handler<std::map<std::string, V> > : public MapHandler<std::map<std::string, V> > {
504};
505
506#if DMLC_USE_CXX11
507template<typename V>
508struct Handler<std::unordered_map<std::string, V> >
509 : public MapHandler<std::unordered_map<std::string, V> > {
510};
511#endif // DMLC_USE_CXX11
512
513template<typename T>
514struct Handler {
515 inline static void Write(JSONWriter *writer, const T &data) {
517 NumericHandler<T>,
518 CommonJSONSerializer<T> >::Type THandler;
519 THandler::Write(writer, data);
520 }
521 inline static void Read(JSONReader *reader, T *data) {
523 NumericHandler<T>,
524 CommonJSONSerializer<T> >::Type THandler;
525 THandler::Read(reader, data);
526 }
527};
528
529#if DMLC_STRICT_CXX11
530#if DMLC_ENABLE_RTTI
531// Manager to store json serialization strategy.
532class AnyJSONManager {
533 public:
534 template<typename T>
535 inline AnyJSONManager& EnableType(const std::string& type_name) { // NOLINT(*)
536 std::type_index tp = std::type_index(typeid(T));
537 if (type_name_.count(tp) != 0) {
538 CHECK(type_name_.at(tp) == type_name)
539 << "Type has already been registered as another typename " << type_name_.at(tp);
540 return *this;
541 }
542 CHECK(type_map_.count(type_name) == 0)
543 << "Type name " << type_name << " already registered in registry";
544 Entry e;
545 e.read = ReadAny<T>;
546 e.write = WriteAny<T>;
547 type_name_[tp] = type_name;
548 type_map_[type_name] = e;
549 return *this;
550 }
551 // return global singleton
552 inline static AnyJSONManager* Global() {
553 static AnyJSONManager inst;
554 return &inst;
555 }
556
557 private:
558 AnyJSONManager() {}
559
560 template<typename T>
561 inline static void WriteAny(JSONWriter *writer, const any &data) {
562 writer->Write(dmlc::unsafe_get<T>(data));
563 }
564 template<typename T>
565 inline static void ReadAny(JSONReader *reader, any* data) {
566 T temp;
567 reader->Read(&temp);
568 *data = std::move(temp);
569 }
570 // data entry to store vtable for any type
571 struct Entry {
572 void (*read)(JSONReader* reader, any *data);
573 void (*write)(JSONWriter* reader, const any& data);
574 };
575
576 template<typename T>
577 friend struct Handler;
578
579 std::unordered_map<std::type_index, std::string> type_name_;
580 std::unordered_map<std::string, Entry> type_map_;
581};
582
583template<>
584struct Handler<any> {
585 inline static void Write(JSONWriter *writer, const any &data) {
586 std::unordered_map<std::type_index, std::string>&
587 nmap = AnyJSONManager::Global()->type_name_;
588 std::type_index id = std::type_index(data.type());
589 auto it = nmap.find(id);
590 CHECK(it != nmap.end() && it->first == id)
591 << "Type " << id.name() << " has not been registered via DMLC_JSON_ENABLE_ANY";
592 std::string type_name = it->second;
593 AnyJSONManager::Entry e = AnyJSONManager::Global()->type_map_.at(type_name);
594 writer->BeginArray(false);
595 writer->WriteArrayItem(type_name);
596 writer->WriteArraySeperator();
597 e.write(writer, data);
598 writer->EndArray();
599 }
600 inline static void Read(JSONReader *reader, any *data) {
601 std::string type_name;
602 reader->BeginArray();
603 CHECK(reader->NextArrayItem()) << "invalid any json format";
604 Handler<std::string>::Read(reader, &type_name);
605 std::unordered_map<std::string, AnyJSONManager::Entry>&
606 tmap = AnyJSONManager::Global()->type_map_;
607 auto it = tmap.find(type_name);
608 CHECK(it != tmap.end() && it->first == type_name)
609 << "Typename " << type_name << " has not been registered via DMLC_JSON_ENABLE_ANY";
610 AnyJSONManager::Entry e = it->second;
611 CHECK(reader->NextArrayItem()) << "invalid any json format";
612 e.read(reader, data);
613 CHECK(!reader->NextArrayItem()) << "invalid any json format";
614 }
615};
616#endif // DMLC_ENABLE_RTTI
617#endif // DMLC_STRICT_CXX11
618
619} // namespace json
620
621// implementations of JSONReader/Writer
622inline int JSONReader::NextChar() {
623#ifndef _LIBCPP_SGX_NO_IOSTREAMS
624 return is_->get();
625#else
626 int ch = is_->at(0);
627 is_->erase(0, 1);
628 return ch;
629#endif
630}
631
632inline int JSONReader::PeekNextChar() {
633#ifndef _LIBCPP_SGX_NO_IOSTREAMS
634 return is_->peek();
635#else
636 return is_->at(0);
637#endif
638}
639
640inline int JSONReader::NextNonSpace() {
641 int ch;
642 do {
643 ch = NextChar();
644 if (ch == '\n') ++line_count_n_;
645 if (ch == '\r') ++line_count_r_;
646 } while (isspace(ch));
647 return ch;
648}
649
650inline int JSONReader::PeekNextNonSpace() {
651 int ch;
652 while (true) {
653 ch = PeekNextChar();
654 if (ch == '\n') ++line_count_n_;
655 if (ch == '\r') ++line_count_r_;
656 if (!isspace(ch)) break;
657 NextChar();
658 }
659 return ch;
660}
661
662namespace {
663 template<typename T>
664#ifndef _LIBCPP_SGX_NO_IOSTREAMS
665 void Extend(std::ostream *os, T item) {
666 *os << item;
667 }
668#else
669 void Extend(std::string *ostr, T item) {
670 *ostr += item;
671 }
672#endif
673} // namespace
674
675inline void JSONReader::ReadString(std::string *out_str) {
676 int ch = NextNonSpace();
677 CHECK_EQ(ch, '\"')
678 << "Error at" << line_info()
679 << ", Expect \'\"\' but get \'" << static_cast<char>(ch) << '\'';
680#ifndef _LIBCPP_SGX_NO_IOSTREAMS
681 std::ostringstream output;
682#else
683 std::string output = "";
684#endif
685 while (true) {
686 ch = NextChar();
687 if (ch == '\\') {
688 char sch = static_cast<char>(NextChar());
689 switch (sch) {
690 case 'r': Extend(&output, "\r"); break;
691 case 'n': Extend(&output, "\n"); break;
692 case '\\': Extend(&output, "\\"); break;
693 case 't': Extend(&output, "\t"); break;
694 case '\"': Extend(&output, "\""); break;
695 default: LOG(FATAL) << "unknown string escape \\" << sch;
696 }
697 } else {
698 if (ch == '\"') break;
699 Extend(&output, static_cast<char>(ch));
700 }
701 if (ch == EOF || ch == '\r' || ch == '\n') {
702 LOG(FATAL)
703 << "Error at" << line_info()
704 << ", Expect \'\"\' but reach end of line ";
705 }
706 }
707#ifndef _LIBCPP_SGX_NO_IOSTREAMS
708 *out_str = output.str();
709#else
710 *out_str = output;
711#endif
712}
713
714template<typename ValueType>
715inline void JSONReader::ReadNumber(ValueType *out_value) {
716#ifndef _LIBCPP_SGX_NO_IOSTREAMS
717 *is_ >> *out_value;
718 CHECK(!is_->fail())
719 << "Error at" << line_info()
720 << ", Expect number";
721#else
722 char* endptr;
723 const char* icstr = is_->c_str();
724 unsigned number = strtol(icstr, &endptr, 10);
725 is_->erase(0, endptr - icstr);
726 *out_value = static_cast<ValueType>(number);
727#endif
728}
729
730inline void JSONReader::BeginObject() {
731 int ch = NextNonSpace();
732 CHECK_EQ(ch, '{')
733 << "Error at" << line_info()
734 << ", Expect \'{\' but get \'" << static_cast<char>(ch) << '\'';
735 scope_counter_.push_back(0);
736}
737
738inline void JSONReader::BeginArray() {
739 int ch = NextNonSpace();
740 CHECK_EQ(ch, '[')
741 << "Error at" << line_info()
742 << ", Expect \'[\' but get \'" << static_cast<char>(ch) << '\'';
743 scope_counter_.push_back(0);
744}
745
746inline bool JSONReader::NextObjectItem(std::string *out_key) {
747 bool next = true;
748 if (scope_counter_.back() != 0) {
749 int ch = NextNonSpace();
750 if (ch == EOF) {
751 next = false;
752 } else if (ch == '}') {
753 next = false;
754 } else {
755 CHECK_EQ(ch, ',')
756 << "Error at" << line_info()
757 << ", JSON object expect \'}\' or \',\' \'" << static_cast<char>(ch) << '\'';
758 }
759 } else {
760 int ch = PeekNextNonSpace();
761 if (ch == '}') {
762 NextChar();
763 next = false;
764 }
765 }
766 if (!next) {
767 scope_counter_.pop_back();
768 return false;
769 } else {
770 scope_counter_.back() += 1;
771 ReadString(out_key);
772 int ch = NextNonSpace();
773 CHECK_EQ(ch, ':')
774 << "Error at" << line_info()
775 << ", Expect \':\' but get \'" << static_cast<char>(ch) << '\'';
776 return true;
777 }
778}
779
780inline bool JSONReader::NextArrayItem() {
781 bool next = true;
782 if (scope_counter_.back() != 0) {
783 int ch = NextNonSpace();
784 if (ch == EOF) {
785 next = false;
786 } else if (ch == ']') {
787 next = false;
788 } else {
789 CHECK_EQ(ch, ',')
790 << "Error at" << line_info()
791 << ", JSON array expect \']\' or \',\'. Get \'" << static_cast<char>(ch) << "\' instead";
792 }
793 } else {
794 int ch = PeekNextNonSpace();
795 if (ch == ']') {
796 NextChar();
797 next = false;
798 }
799 }
800 if (!next) {
801 scope_counter_.pop_back();
802 return false;
803 } else {
804 scope_counter_.back() += 1;
805 return true;
806 }
807}
808
809template<typename ValueType>
810inline void JSONReader::Read(ValueType *out_value) {
811 json::Handler<ValueType>::Read(this, out_value);
812}
813
814inline void JSONWriter::WriteNoEscape(const std::string &s) {
815 Extend(os_, '\"');
816 Extend(os_, s);
817 Extend(os_, '\"');
818}
819
820inline void JSONWriter::WriteString(const std::string &s) {
821 Extend(os_, '\"');
822 for (size_t i = 0; i < s.length(); ++i) {
823 char ch = s[i];
824 switch (ch) {
825 case '\r': Extend(os_, "\\r"); break;
826 case '\n': Extend(os_, "\\n"); break;
827 case '\\': Extend(os_, "\\\\"); break;
828 case '\t': Extend(os_, "\\t"); break;
829 case '\"': Extend(os_, "\\\""); break;
830 default: Extend(os_, ch);
831 }
832 }
833 Extend(os_, '\"');
834}
835
836template<typename ValueType>
837inline void JSONWriter::WriteNumber(const ValueType &v) {
838#ifndef _LIBCPP_SGX_NO_IOSTREAMS
839 Extend(os_, v);
840#else
841 Extend(os_, std::to_string(v));
842#endif
843}
844
845inline void JSONWriter::BeginArray(bool multi_line) {
846 Extend(os_, '[');
847 scope_multi_line_.push_back(multi_line);
848 scope_counter_.push_back(0);
849}
850
851inline void JSONWriter::EndArray() {
852 CHECK_NE(scope_multi_line_.size(), 0U);
853 CHECK_NE(scope_counter_.size(), 0U);
854 bool newline = scope_multi_line_.back();
855 size_t nelem = scope_counter_.back();
856 scope_multi_line_.pop_back();
857 scope_counter_.pop_back();
858 if (newline && nelem != 0) WriteSeperator();
859 Extend(os_, ']');
860}
861
862inline void JSONWriter::BeginObject(bool multi_line) {
863 Extend(os_, '{');
864 scope_multi_line_.push_back(multi_line);
865 scope_counter_.push_back(0);
866}
867
868inline void JSONWriter::EndObject() {
869 CHECK_NE(scope_multi_line_.size(), 0U);
870 CHECK_NE(scope_counter_.size(), 0U);
871 bool newline = scope_multi_line_.back();
872 size_t nelem = scope_counter_.back();
873 scope_multi_line_.pop_back();
874 scope_counter_.pop_back();
875 if (newline && nelem != 0) WriteSeperator();
876 Extend(os_, '}');
877}
878
879template<typename ValueType>
880inline void JSONWriter::WriteObjectKeyValue(const std::string &key,
881 const ValueType &value) {
882 if (scope_counter_.back() > 0) {
883 Extend(os_, ", ");
884 }
885 WriteSeperator();
886 Extend(os_, '\"');
887 Extend(os_, key);
888 Extend(os_, "\": ");
889 scope_counter_.back() += 1;
890 json::Handler<ValueType>::Write(this, value);
891}
892
894 if (scope_counter_.back() != 0) {
895 Extend(os_, ", ");
896 }
897 scope_counter_.back() += 1;
898 WriteSeperator();
899}
900
901template<typename ValueType>
902inline void JSONWriter::WriteArrayItem(const ValueType &value) {
903 this->WriteArraySeperator();
904 json::Handler<ValueType>::Write(this, value);
905}
906
907template<typename ValueType>
908inline void JSONWriter::Write(const ValueType &value) {
909 size_t nscope = scope_multi_line_.size();
910 json::Handler<ValueType>::Write(this, value);
911 CHECK_EQ(nscope, scope_multi_line_.size())
912 << "Uneven scope, did you call EndArray/EndObject after each BeginObject/Array?";
913}
914
915inline void JSONWriter::WriteSeperator() {
916 if (scope_multi_line_.size() == 0 || scope_multi_line_.back()) {
917 Extend(os_, '\n');
918 Extend(os_, std::string(scope_multi_line_.size() * 2, ' '));
919 }
920}
921
922inline void JSONObjectReadHelper::ReadAllFields(JSONReader *reader) {
923 reader->BeginObject();
924 std::map<std::string, int> visited;
925 std::string key;
926 while (reader->NextObjectItem(&key)) {
927 if (map_.count(key) != 0) {
928 Entry e = map_[key];
929 (*e.func)(reader, e.addr);
930 visited[key] = 0;
931 } else {
932#ifndef _LIBCPP_SGX_NO_IOSTREAMS
933 std::ostringstream err;
934#else
935 std::string err("");
936#endif
937 Extend(&err, "JSONReader: Unknown field ");
938 Extend(&err, key);
939 Extend(&err, ", candidates are: \n");
940 for (std::map<std::string, Entry>::iterator
941 it = map_.begin(); it != map_.end(); ++it) {
942 Extend(&err, '\"');
943 Extend(&err, it->first);
944 Extend(&err, "\"\n");
945 }
946#ifndef _LIBCPP_SGX_NO_IOSTREAMS
947 LOG(FATAL) << err.str();
948#else
949 LOG(FATAL) << err;
950#endif
951 }
952 }
953 if (visited.size() != map_.size()) {
954 for (std::map<std::string, Entry>::iterator
955 it = map_.begin(); it != map_.end(); ++it) {
956 if (it->second.optional) continue;
957 CHECK_NE(visited.count(it->first), 0U)
958 << "JSONReader: Missing field \"" << it->first << "\"\n At "
959 << reader->line_info();
960 }
961 }
962}
963
964template<typename T>
965inline void JSONObjectReadHelper::ReaderFunction(JSONReader *reader, void *addr) {
966 json::Handler<T>::Read(reader, static_cast<T*>(addr));
967}
968
969template<typename T>
970inline void JSONObjectReadHelper::
971DeclareFieldInternal(const std::string &key, T *addr, bool optional) {
972 CHECK_EQ(map_.count(key), 0U)
973 << "Adding duplicate field " << key;
974 Entry e;
975 e.func = ReaderFunction<T>;
976 e.addr = static_cast<void*>(addr);
977 e.optional = optional;
978 map_[key] = e;
979}
980
982} // namespace dmlc
983#endif // DMLC_JSON_H_
Container to hold any data type.
Helper class to read JSON into a class or struct object.
Definition json.h:312
void ReadAllFields(JSONReader *reader)
Read in all the declared fields.
void DeclareField(const std::string &key, T *addr)
Declare field of type T.
Definition json.h:321
void DeclareOptionalField(const std::string &key, T *addr)
Declare optional field of type T.
Definition json.h:331
Lightweight JSON Reader to read any STL compositions and structs. The user need to know the schema of...
Definition json.h:44
std::string line_info() const
Definition json.h:124
bool NextArrayItem()
Try to read the next element in the array. If this call is successful, user can proceed to call reade...
bool NextObjectItem(std::string *out_key)
Try to move to next object item. If this call is successful, user can proceed to call reader->Read to...
void ReadString(std::string *out_str)
Parse next JSON string.
void BeginArray()
Begin parsing an array.
JSONReader(std::istream *is)
Constructor.
Definition json.h:51
void Read(ValueType *out_value)
Read next ValueType.
void ReadNumber(ValueType *out_value)
Read Number.
void BeginObject()
Begin parsing an object.
Lightweight json to write any STL compositions.
Definition json.h:190
JSONWriter(std::ostream *os)
Constructor.
Definition json.h:197
void BeginArray(bool multi_line=true)
Start beginning of array.
void WriteNoEscape(const std::string &s)
Write a string that do not contain escape characters.
void WriteArraySeperator()
Write seperator of array, before writing next element. User can proceed to call writer->Write to writ...
void WriteNumber(const ValueType &v)
Write a string that can contain escape characters.
void WriteArrayItem(const ValueType &value)
Write value into array.
void EndObject()
Finish writing object.
void Write(const ValueType &value)
Write value to json.
void BeginObject(bool multi_line=true)
Start beginning of array.
void EndArray()
Finish writing an array.
void WriteObjectKeyValue(const std::string &key, const ValueType &value)
Write key value pair in the object.
void WriteString(const std::string &s)
Write a string that can contain escape characters.
Is not constructible or convertible from any expression of type (possibly const) dmlc::optional<U>,...
Definition optional.h:76
defines console logging options for xgboost. Use to enforce unified print behavior.
namespace for dmlc
Definition array_view.h:12
bool isspace(char c)
Inline implementation of isspace(). Tests whether the given character is a whitespace letter.
Definition strtonum.h:26
Definition StdDeque.h:58
Macros common to all headers.
template to select type based on condition For example, IfThenElseType<true, int, float>::Type will g...
Definition type_traits.h:123
whether a type is pod type
Definition type_traits.h:21
type traits information header