Advertisement
Guest User

Untitled

a guest
Nov 19th, 2019
115
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.53 KB | None | 0 0
  1. namespace Json {
  2.  
  3. class Node : std::variant<std::vector<Node>,
  4. std::map<std::string, Node>,
  5. double,
  6. bool,
  7. std::string> {
  8. public:
  9. using variant::variant;
  10.  
  11. const auto& AsArray() const {
  12. return std::get<std::vector<Node>>(*this);
  13. }
  14. const auto& AsMap() const {
  15. return std::get<std::map<std::string, Node>>(*this);
  16. }
  17. /*
  18. int AsInt() const {
  19. return std::get<int>(*this);
  20. }
  21. */
  22. double AsDouble() const {
  23. return std::get<double>(*this);
  24. }
  25. bool AsBool() const {
  26. return std::get<bool>(*this);
  27. }
  28. const auto& AsString() const {
  29. return std::get<std::string>(*this);
  30. }
  31. friend std::ostream &operator << ( std::ostream &os, const Json::Node &node ) ;
  32. };
  33.  
  34. std::ostream &operator << ( std::ostream &os, const Json::Node &node ) {
  35. if ( std::holds_alternative<std::string>(node) ) {
  36. return os << "\"" << node.AsString() << "\"";
  37. }
  38. if ( std::holds_alternative<bool>(node) ) {
  39. return os << (node.AsBool()?"true":"false");
  40. }
  41. /*
  42. if ( std::holds_alternative<int>(node) ) {
  43. return os << node.AsInt();
  44. }
  45. */
  46. if ( std::holds_alternative<double>(node) ) {
  47. //return os << std::setprecision(8) << node.AsDouble();
  48. auto x= node.AsDouble();
  49. if ( fabs((long long)x-x) < 1e-7 )
  50. return os << static_cast<int>(x);
  51. return os << std::setprecision(8) << node.AsDouble();
  52. }
  53. if ( std::holds_alternative<std::map<std::string,Json::Node>>(node) ) {
  54. os << "{";
  55. bool flag= false;
  56. for ( const auto &it: node.AsMap() ) {
  57. os << (flag?",\n\t":"") << "\"" << it.first << "\"" << ": " << it.second;
  58. flag= true ;
  59. }
  60. return os << "}";
  61. }
  62. if ( std::holds_alternative<std::vector<Json::Node>>(node) ) {
  63. os << "[";
  64. bool flag= false;
  65. for ( const auto &x: node.AsArray() ) {
  66. os << (flag?",\n\t":"") << x;
  67. flag= true ;
  68. }
  69. return os << "]";
  70. }
  71. return os;
  72. }
  73.  
  74. class Document {
  75. public:
  76. explicit Document(Node root) : root(move(root)) {}
  77. const Node& GetRoot() const {
  78. return root;
  79. }
  80. private:
  81. Node root;
  82. };
  83.  
  84.  
  85. Node LoadNode(istream& input) ;
  86.  
  87. Node LoadArray(istream& input) {
  88. vector<Node> result;
  89.  
  90. for (char c; input >> c && c != ']'; ) {
  91. if (c != ',') {
  92. input.putback(c);
  93. }
  94. result.push_back(LoadNode(input));
  95. }
  96.  
  97. return Node(move(result));
  98. }
  99.  
  100. /*
  101. Node LoadInt(istream& input) {
  102. int result = 0;
  103. while (isdigit(input.peek())) {
  104. result *= 10;
  105. result += input.get() - '0';
  106. }
  107. return Node(result);
  108. }
  109. */
  110.  
  111. Node LoadDouble( istream &input ) {
  112. double x= 0, y= 0;
  113. int sign= 1;
  114. if ( input.peek() == '-' ) {
  115. sign= -1, input.get();
  116. }
  117. else if ( input.peek() == '+' )
  118. input.get();
  119. for ( ;isdigit(input.peek()); x*= 10, x+= input.get()-'0' ) ;
  120. if ( input.peek() == '.' ) {
  121. int len= 0;
  122. for ( input.get(); isdigit(input.peek()); y*= 10, y+= input.get()-'0', ++len ) ;
  123. y/= pow(10,len);
  124. }
  125. return Node(sign*(x+y));
  126. }
  127.  
  128. Node LoadBool( istream &input ) {
  129. std::string s;
  130. for ( ;islower(input.peek()); s.push_back(input.get()) ) ;
  131. return Node(s == "true");
  132. }
  133.  
  134. Node LoadString(istream& input) {
  135. string line;
  136. getline(input, line, '"');
  137. return Node(move(line));
  138. }
  139.  
  140. Node LoadDict(istream& input) {
  141. map<string, Node> result;
  142.  
  143. for (char c; input >> c && c != '}'; ) {
  144. if (c == ',') {
  145. input >> c;
  146. }
  147.  
  148. string key = LoadString(input).AsString();
  149. input >> c;
  150. result.emplace(move(key), LoadNode(input));
  151. }
  152.  
  153. return Node(move(result));
  154. }
  155.  
  156. Node LoadDoubleFromString( std::string s ) {
  157. auto res= std::stringstream(s);
  158. return LoadDouble(res);
  159. }
  160.  
  161. Node LoadIntFromString( std::string s ) {
  162. auto res= std::stringstream(s);
  163. return LoadDouble(res);
  164. //return LoadInt(res);
  165. }
  166.  
  167. Node LoadNode(istream& input) {
  168. char c;
  169. input >> c;
  170.  
  171. if (c == '[') {
  172. return LoadArray(input);
  173. } else if (c == '{') {
  174. return LoadDict(input);
  175. } else if (c == '"') {
  176. return LoadString(input);
  177. } else if ( c == 't' or c == 'f' ) {
  178. input.putback(c);
  179. return LoadBool(input);
  180. } else {
  181. input.putback(c);
  182. std::string s;
  183. for ( ;isdigit(input.peek()) or input.peek() == '.'; s.push_back(input.get()) ) ;
  184. auto pos= s.find('.');
  185. if ( pos == std::string::npos )
  186. return LoadIntFromString(std::move(s));
  187. return LoadDoubleFromString(std::move(s));
  188. }
  189. }
  190.  
  191. Document Load(istream& input) {
  192. return Document{LoadNode(input)};
  193. }
  194. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement