shushus

Спринт 12. Строим JSON. Задание 2.

Apr 16th, 2023
685
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.82 KB | None | 0 0
  1. -----------------------------------------------------------------------
  2. json.h
  3. -----------------------------------------------------------------------
  4. #pragma once
  5.  
  6. #include <iostream>
  7. #include <map>
  8. #include <string>
  9. #include <variant>
  10. #include <vector>
  11.  
  12. namespace json {
  13.  
  14. class Node;
  15. using Dict = std::map<std::string, Node>;
  16. using Array = std::vector<Node>;
  17.  
  18. class ParsingError : public std::runtime_error {
  19. public:
  20.     using runtime_error::runtime_error;
  21. };
  22.  
  23. class Node final : private std::variant<std::nullptr_t, Array, Dict, bool, int, double, std::string> {
  24. public:
  25.     using variant::variant;
  26.     using Value = variant;
  27.  
  28.     bool IsInt() const {
  29.         return std::holds_alternative<int>(*this);
  30.     }
  31.    
  32.     int AsInt() const {
  33.         using namespace std::literals;
  34.         if (!IsInt()) {
  35.             throw std::logic_error("Not an int"s);
  36.         }
  37.         return std::get<int>(*this);
  38.     }
  39.  
  40.     bool IsPureDouble() const {
  41.         return std::holds_alternative<double>(*this);
  42.     }
  43.    
  44.     bool IsDouble() const {
  45.         return IsInt() || IsPureDouble();
  46.     }
  47.    
  48.     double AsDouble() const {
  49.         using namespace std::literals;
  50.        
  51.         if (!IsDouble()) {
  52.             throw std::logic_error("Not a double"s);
  53.         }
  54.         return IsPureDouble() ? std::get<double>(*this) : AsInt();
  55.     }
  56.  
  57.     bool IsBool() const {
  58.         return std::holds_alternative<bool>(*this);
  59.     }
  60.    
  61.     bool AsBool() const {
  62.         using namespace std::literals;
  63.        
  64.         if (!IsBool()) {
  65.             throw std::logic_error("Not a bool"s);
  66.         }
  67.  
  68.         return std::get<bool>(*this);
  69.     }
  70.  
  71.     bool IsNull() const {
  72.         return std::holds_alternative<std::nullptr_t>(*this);
  73.     }
  74.  
  75.     bool IsArray() const {
  76.         return std::holds_alternative<Array>(*this);
  77.     }
  78.        
  79.     const Array& AsArray() const {
  80.         using namespace std::literals;
  81.        
  82.         if (!IsArray()) {
  83.             throw std::logic_error("Not an array"s);
  84.         }
  85.  
  86.         return std::get<Array>(*this);
  87.     }
  88.  
  89.     bool IsString() const {
  90.         return std::holds_alternative<std::string>(*this);
  91.     }
  92.        
  93.     const std::string& AsString() const {
  94.         using namespace std::literals;
  95.        
  96.         if (!IsString()) {
  97.             throw std::logic_error("Not a string"s);
  98.         }
  99.  
  100.         return std::get<std::string>(*this);
  101.     }
  102.  
  103.     bool IsDict() const {
  104.         return std::holds_alternative<Dict>(*this);
  105.     }
  106.        
  107.     const Dict& AsDict() const {
  108.         using namespace std::literals;
  109.        
  110.         if (!IsDict()) {
  111.             throw std::logic_error("Not a dict"s);
  112.         }
  113.  
  114.         return std::get<Dict>(*this);
  115.     }
  116.  
  117.     bool operator==(const Node& rhs) const {
  118.         return GetValue() == rhs.GetValue();
  119.     }
  120.  
  121.     const Value& GetValue() const {
  122.         return *this;
  123.     }
  124. };
  125.  
  126. inline bool operator!=(const Node& lhs, const Node& rhs) {
  127.     return !(lhs == rhs);
  128. }
  129.  
  130. class Document {
  131. public:
  132.     explicit Document(Node root)
  133.         : root_(std::move(root)) {
  134.     }
  135.  
  136.     const Node& GetRoot() const {
  137.         return root_;
  138.     }
  139.  
  140. private:
  141.     Node root_;
  142. };
  143.  
  144. inline bool operator==(const Document& lhs, const Document& rhs) {
  145.     return lhs.GetRoot() == rhs.GetRoot();
  146. }
  147.  
  148. inline bool operator!=(const Document& lhs, const Document& rhs) {
  149.     return !(lhs == rhs);
  150. }
  151.  
  152. Document Load(std::istream& input);
  153.  
  154. void Print(const Document& doc, std::ostream& output);
  155.  
  156. }//end namespace json
  157. -----------------------------------------------------------------------
  158. json.cpp
  159. -----------------------------------------------------------------------
  160. #include "json.h"
  161.  
  162. #include <iterator>
  163.  
  164. namespace json {
  165.  
  166. namespace {
  167. using namespace std::literals;
  168.  
  169. Node LoadNode(std::istream& input);
  170. Node LoadString(std::istream& input);
  171.  
  172. std::string LoadLiteral(std::istream& input) {
  173.     std::string s;
  174.    
  175.     while (std::isalpha(input.peek())) {
  176.         s.push_back(static_cast<char>(input.get()));
  177.     }
  178.     return s;
  179. }
  180.  
  181. Node LoadArray(std::istream& input) {
  182.     std::vector<Node> result;
  183.  
  184.     for (char c; input >> c && c != ']';) {
  185.        
  186.         if (c != ',') {
  187.             input.putback(c);
  188.         }
  189.         result.push_back(LoadNode(input));
  190.     }
  191.    
  192.     if (!input) {
  193.         throw ParsingError("Array parsing error"s);
  194.     }
  195.    
  196.     return Node(std::move(result));
  197. }
  198.  
  199. Node LoadDict(std::istream& input) {
  200.     Dict dict;
  201.  
  202.     for (char c; input >> c && c != '}';) {
  203.        
  204.         if (c == '"') {
  205.             std::string key = LoadString(input).AsString();
  206.            
  207.             if (input >> c && c == ':') {
  208.                
  209.                 if (dict.find(key) != dict.end()) {
  210.                     throw ParsingError("Duplicate key '"s + key + "' have been found");
  211.                 }
  212.                
  213.                 dict.emplace(std::move(key), LoadNode(input));
  214.                
  215.             } else {
  216.                
  217.                 throw ParsingError(": is expected but '"s + c + "' has been found"s);
  218.             }
  219.            
  220.         } else if (c != ',') {
  221.             throw ParsingError(R"(',' is expected but ')"s + c + "' has been found"s);
  222.         }
  223.     }
  224.    
  225.     if (!input) {
  226.         throw ParsingError("Dictionary parsing error"s);
  227.     }
  228.    
  229.     return Node(std::move(dict));
  230. }
  231.  
  232. Node LoadString(std::istream& input) {
  233.     auto it = std::istreambuf_iterator<char>(input);
  234.     auto end = std::istreambuf_iterator<char>();
  235.     std::string s;
  236.    
  237.     while (true) {
  238.        
  239.         if (it == end) {
  240.             throw ParsingError("String parsing error");
  241.         }
  242.        
  243.         const char ch = *it;
  244.         if (ch == '"') {
  245.             ++it;
  246.             break;
  247.            
  248.         } else if (ch == '\\') {
  249.             ++it;
  250.            
  251.             if (it == end) {
  252.                 throw ParsingError("String parsing error");
  253.             }
  254.            
  255.             const char escaped_char = *(it);
  256.             switch (escaped_char) {
  257.                 case 'n':
  258.                     s.push_back('\n');
  259.                     break;
  260.                 case 't':
  261.                     s.push_back('\t');
  262.                     break;
  263.                 case 'r':
  264.                     s.push_back('\r');
  265.                     break;
  266.                 case '"':
  267.                     s.push_back('"');
  268.                     break;
  269.                 case '\\':
  270.                     s.push_back('\\');
  271.                     break;
  272.                 default:
  273.                     throw ParsingError("Unrecognized escape sequence \\"s + escaped_char);
  274.                    
  275.             }
  276.            
  277.         } else if (ch == '\n' || ch == '\r') {
  278.             throw ParsingError("Unexpected end of line"s);
  279.            
  280.         } else {
  281.             s.push_back(ch);
  282.            
  283.         }
  284.        
  285.         ++it;
  286.     }
  287.  
  288.     return Node(std::move(s));
  289. }
  290.  
  291. Node LoadBool(std::istream& input) {
  292.     const auto s = LoadLiteral(input);
  293.    
  294.     if (s == "true"sv) {
  295.         return Node{true};
  296.        
  297.     } else if (s == "false"sv) {
  298.         return Node{false};
  299.        
  300.     } else {
  301.         throw ParsingError("Failed to parse '"s + s + "' as bool"s);
  302.     }
  303. }
  304.  
  305. Node LoadNull(std::istream& input) {
  306.     if (auto literal = LoadLiteral(input); literal == "null"sv) {
  307.         return Node{nullptr};
  308.        
  309.     } else {
  310.         throw ParsingError("Failed to parse '"s + literal + "' as null"s);
  311.     }
  312. }
  313.  
  314. Node LoadNumber(std::istream& input) {
  315.     std::string parsed_num;
  316.  
  317.     auto read_char = [&parsed_num, &input] {
  318.         parsed_num += static_cast<char>(input.get());
  319.        
  320.         if (!input) {
  321.             throw ParsingError("Failed to read number from stream"s);
  322.         }
  323.     };
  324.  
  325.     auto read_digits = [&input, read_char] {
  326.         if (!std::isdigit(input.peek())) {
  327.             throw ParsingError("A digit is expected"s);
  328.         }
  329.        
  330.         while (std::isdigit(input.peek())) {
  331.             read_char();
  332.         }
  333.        
  334.     };
  335.  
  336.     if (input.peek() == '-') {
  337.         read_char();
  338.        
  339.     }
  340.  
  341.     if (input.peek() == '0') {
  342.         read_char();
  343.        
  344.     } else {
  345.         read_digits();
  346.        
  347.     }
  348.  
  349.     bool is_int = true;
  350.     if (input.peek() == '.') {
  351.         read_char();
  352.         read_digits();
  353.         is_int = false;
  354.        
  355.     }
  356.  
  357.     if (int ch = input.peek(); ch == 'e' || ch == 'E') {
  358.         read_char();
  359.        
  360.         if (ch = input.peek(); ch == '+' || ch == '-') {
  361.             read_char();
  362.         }
  363.        
  364.         read_digits();
  365.         is_int = false;
  366.     }
  367.  
  368.     try {
  369.        
  370.         if (is_int) {
  371.            
  372.             try {
  373.                 return std::stoi(parsed_num);
  374.             } catch (...) {
  375.  
  376.             }
  377.         }
  378.        
  379.         return std::stod(parsed_num);
  380.        
  381.     } catch (...) {
  382.         throw ParsingError("Failed to convert "s + parsed_num + " to number"s);
  383.     }
  384.    
  385. }
  386.  
  387. Node LoadNode(std::istream& input) {
  388.     char c;
  389.    
  390.     if (!(input >> c)) {
  391.         throw ParsingError("Unexpected EOF"s);
  392.     }
  393.    
  394.     switch (c) {
  395.         case '[':
  396.             return LoadArray(input);
  397.         case '{':
  398.             return LoadDict(input);
  399.         case '"':
  400.             return LoadString(input);
  401.         case 't':
  402.             [[fallthrough]];
  403.         case 'f':
  404.             input.putback(c);
  405.             return LoadBool(input);
  406.         case 'n':
  407.             input.putback(c);
  408.             return LoadNull(input);
  409.         default:
  410.             input.putback(c);
  411.             return LoadNumber(input);
  412.     }
  413. }
  414.  
  415. struct PrintContext {
  416.     std::ostream& out;
  417.     int indent_step = 4;
  418.     int indent = 0;
  419.  
  420.     void PrintIndent() const {
  421.         for (int i = 0; i < indent; ++i) {
  422.             out.put(' ');
  423.         }
  424.     }
  425.  
  426.     PrintContext Indented() const {
  427.         return {out,
  428.                 indent_step,
  429.                 indent_step + indent};
  430.     }
  431. };
  432.  
  433. void PrintNode(const Node& value, const PrintContext& ctx);
  434.  
  435. template <typename Value>
  436. void PrintValue(const Value& value, const PrintContext& ctx) {
  437.     ctx.out << value;
  438. }
  439.  
  440. void PrintString(const std::string& value, std::ostream& out) {
  441.     out.put('"');
  442.    
  443.     for (const char c : value) {
  444.         switch (c) {
  445.             case '\r':
  446.                 out << "\\r"sv;
  447.                 break;
  448.             case '\n':
  449.                 out << "\\n"sv;
  450.                 break;
  451.             case '"':
  452.                 [[fallthrough]];
  453.             case '\\':
  454.                 out.put('\\');
  455.                 [[fallthrough]];
  456.             default:
  457.                 out.put(c);
  458.                 break;
  459.         }
  460.     }
  461.    
  462.     out.put('"');
  463. }
  464.  
  465. template <>
  466. void PrintValue<std::string>(const std::string& value, const PrintContext& ctx) {
  467.     PrintString(value, ctx.out);
  468. }
  469.  
  470. template <>
  471. void PrintValue<std::nullptr_t>(const std::nullptr_t&, const PrintContext& ctx) {
  472.     ctx.out << "null"sv;
  473. }
  474.  
  475. template <>
  476. void PrintValue<bool>(const bool& value, const PrintContext& ctx) {
  477.     ctx.out << (value ? "true"sv : "false"sv);
  478. }
  479.  
  480. template <>
  481. void PrintValue<Array>(const Array& nodes, const PrintContext& ctx) {
  482.     std::ostream& out = ctx.out;
  483.     out << "[\n"sv;
  484.     bool first = true;
  485.    
  486.     auto inner_ctx = ctx.Indented();
  487.     for (const Node& node : nodes) {
  488.         if (first) {
  489.             first = false;
  490.            
  491.         } else {
  492.             out << ",\n"sv;
  493.            
  494.         }
  495.        
  496.         inner_ctx.PrintIndent();
  497.         PrintNode(node, inner_ctx);
  498.     }
  499.    
  500.     out.put('\n');
  501.     ctx.PrintIndent();
  502.     out.put(']');
  503. }
  504.  
  505. template <>
  506. void PrintValue<Dict>(const Dict& nodes, const PrintContext& ctx) {
  507.     std::ostream& out = ctx.out;
  508.     out << "{\n"sv;
  509.     bool first = true;
  510.    
  511.     auto inner_ctx = ctx.Indented();
  512.     for (const auto& [key, node] : nodes) {
  513.        
  514.         if (first) {
  515.             first = false;
  516.         } else {
  517.             out << ",\n"sv;
  518.         }
  519.        
  520.         inner_ctx.PrintIndent();
  521.         PrintString(key, ctx.out);
  522.         out << ": "sv;
  523.         PrintNode(node, inner_ctx);
  524.     }
  525.    
  526.     out.put('\n');
  527.     ctx.PrintIndent();
  528.     out.put('}');
  529. }
  530.  
  531. void PrintNode(const Node& node, const PrintContext& ctx) {
  532.     std::visit(
  533.         [&ctx](const auto& value) {PrintValue(value, ctx);},node.GetValue());
  534. }
  535.  
  536. }//end namespace
  537.  
  538. Document Load(std::istream& input) {
  539.     return Document{LoadNode(input)};
  540. }
  541.  
  542. void Print(const Document& doc, std::ostream& output) {
  543.     PrintNode(doc.GetRoot(), PrintContext{output});
  544. }
  545.  
  546. }//end namespace json
  547. -----------------------------------------------------------------------
  548. json_builder.h
  549. -----------------------------------------------------------------------
  550. #pragma once
  551.  
  552. #include "json.h"
  553. #include <stack>
  554. #include <string>
  555. #include <memory>
  556.  
  557. namespace json {
  558.  
  559. class KeyContext;
  560. class DictionaryContext;
  561. class ArrayContext;
  562.  
  563. class Builder {
  564. public:
  565.     Node make_node(Node::Value value_);
  566.     void add_node(Node node);
  567.  
  568.     KeyContext Key(std::string key_);
  569.     DictionaryContext StartDict();
  570.     ArrayContext StartArray();
  571.  
  572.     Builder& Value(Node::Value value);
  573.  
  574.     Builder& EndDict();
  575.  
  576.     Builder& EndArray();
  577.  
  578.     Node Build();
  579.  
  580. private:
  581.     Node root_;
  582.     std::vector<std::unique_ptr<Node>> nodes_stack_;
  583.  
  584. };
  585.  
  586. class BaseContext {
  587. public:
  588.     BaseContext(Builder& builder);
  589.  
  590.     KeyContext Key(std::string key);
  591.     DictionaryContext StartDict();
  592.     ArrayContext StartArray();
  593.  
  594.     Builder& Value(Node::Value value);
  595.  
  596.     Builder& EndDict();
  597.  
  598.     Builder& EndArray();
  599.  
  600. protected:
  601.     Builder& builder_;
  602.  
  603. };
  604.  
  605. class KeyContext : public BaseContext {
  606. public:
  607.     KeyContext(Builder& builder);
  608.  
  609.     KeyContext Key(std::string key) = delete;
  610.  
  611.     BaseContext EndDict() = delete;
  612.     BaseContext EndArray() = delete;
  613.  
  614.     DictionaryContext Value(Node::Value value);
  615. };
  616.  
  617. class DictionaryContext : public BaseContext {
  618. public:
  619.     DictionaryContext(Builder& builder);
  620.  
  621.     DictionaryContext StartDict() = delete;
  622.  
  623.     ArrayContext StartArray() = delete;
  624.     Builder& EndArray() = delete;
  625.  
  626.     Builder& Value(Node::Value value) = delete;
  627. };
  628.  
  629. class ArrayContext : public BaseContext {
  630. public:
  631.     ArrayContext(Builder& builder);
  632.  
  633.     KeyContext Key(std::string key) = delete;
  634.  
  635.     Builder& EndDict() = delete;
  636.  
  637.     ArrayContext Value(Node::Value value);
  638. };
  639.  
  640. }//end namespace json
  641. -----------------------------------------------------------------------
  642. json_builder.cpp
  643. -----------------------------------------------------------------------
  644. #include "json_builder.h"
  645.  
  646. namespace json {
  647.  
  648. //---------------------BaseContext---------------------
  649.  
  650. BaseContext::BaseContext(Builder& builder) : builder_(builder) {}
  651.  
  652. KeyContext BaseContext::Key(std::string key) {return builder_.Key(key);}
  653. Builder& BaseContext::Value(Node::Value value) {return builder_.Value(value);}
  654.  
  655. DictionaryContext BaseContext::StartDict() {return DictionaryContext(builder_.StartDict());}
  656. Builder& BaseContext::EndDict() {return builder_.EndDict();}
  657.  
  658. ArrayContext BaseContext::StartArray() {return ArrayContext(builder_.StartArray());}
  659. Builder& BaseContext::EndArray() {return builder_.EndArray();}
  660.    
  661. //---------------------KeyContext-----------------------
  662.  
  663. KeyContext::KeyContext(Builder& builder) : BaseContext(builder) {}
  664.  
  665. DictionaryContext  KeyContext::Value(Node::Value value) {return BaseContext::Value(std::move(value));}
  666.    
  667. //---------------------DictionaryContext----------------
  668.  
  669. DictionaryContext::DictionaryContext(Builder& builder) : BaseContext(builder) {}
  670.  
  671. //---------------------ArrayContext---------------------
  672.  
  673. ArrayContext::ArrayContext(Builder& builder) : BaseContext(builder) {}
  674.  
  675. ArrayContext ArrayContext::Value (Node::Value value) {return BaseContext::Value(move(value)); }
  676.  
  677. //---------------------Builder--------------------------
  678.  
  679. Node Builder::make_node(Node::Value value_) {
  680.     Node node;
  681.  
  682.     if (std::holds_alternative<bool>(value_)) {
  683.         bool bol = std::get<bool>(value_);
  684.         node = Node(bol);
  685.  
  686.     } else if (std::holds_alternative<int>(value_)) {
  687.         int intt = std::get<int>(value_);
  688.         node = Node(intt);
  689.  
  690.     } else if (std::holds_alternative<double>(value_)) {
  691.         double doble = std::get<double>(value_);
  692.         node = Node(doble);
  693.  
  694.     } else if (std::holds_alternative<std::string>(value_)) {
  695.         std::string str = std::get<std::string>(value_);
  696.         node = Node(std::move(str));
  697.  
  698.     } else if (std::holds_alternative<Array>(value_)) {
  699.         Array arr = std::get<Array>(value_);
  700.         node = Node(std::move(arr));
  701.  
  702.     } else if (std::holds_alternative<Dict>(value_)) {
  703.         Dict dictionary = std::get<Dict>(value_);
  704.         node = Node(std::move(dictionary));
  705.  
  706.     } else {
  707.         node = Node();
  708.     }
  709.  
  710.     return node;
  711. }
  712.  
  713. void Builder::add_node(Node node) {
  714.     if (nodes_stack_.empty()) {
  715.  
  716.         if (!root_.IsNull()) {
  717.             throw std::logic_error("root has been added");
  718.         }
  719.  
  720.         root_ = node;
  721.         return;
  722.  
  723.     } else {
  724.  
  725.         if (!nodes_stack_.back()->IsArray()
  726.             && !nodes_stack_.back()->IsString()) {
  727.  
  728.             throw std::logic_error("unable to create node");
  729.         }
  730.  
  731.         if (nodes_stack_.back()->IsArray()) {
  732.             Array arr = nodes_stack_.back()->AsArray();
  733.             arr.emplace_back(node);
  734.  
  735.             nodes_stack_.pop_back();
  736.             auto arr_ptr = std::make_unique<Node>(arr);
  737.             nodes_stack_.emplace_back(std::move(arr_ptr));
  738.  
  739.             return;
  740.         }
  741.  
  742.         if (nodes_stack_.back()->IsString()) {
  743.             std::string str = nodes_stack_.back()->AsString();
  744.             nodes_stack_.pop_back();
  745.  
  746.             if (nodes_stack_.back()->IsDict()) {
  747.                 Dict dictionary = nodes_stack_.back()->AsDict();
  748.                 dictionary.emplace(std::move(str), node);
  749.  
  750.                 nodes_stack_.pop_back();
  751.                 auto dictionary_ptr = std::make_unique<Node>(dictionary);
  752.                 nodes_stack_.emplace_back(std::move(dictionary_ptr));
  753.             }
  754.  
  755.             return;
  756.         }
  757.     }
  758. }
  759.  
  760. KeyContext Builder::Key(std::string key_) {
  761.     if (nodes_stack_.empty()) {
  762.         throw std::logic_error("unable to create key");
  763.     }
  764.  
  765.     auto key_ptr = std::make_unique<Node>(key_);
  766.  
  767.     if (nodes_stack_.back()->IsDict()) {
  768.         nodes_stack_.emplace_back(std::move(key_ptr));
  769.     }
  770.  
  771.     return KeyContext(*this);
  772. }
  773.  
  774. Builder& Builder::Value(Node::Value value_) {
  775.     add_node(make_node(value_));
  776.  
  777.     return *this;
  778. }
  779.  
  780. DictionaryContext Builder::StartDict() {
  781.     nodes_stack_.emplace_back(std::move(std::make_unique<Node>(Dict())));
  782.  
  783.     return DictionaryContext(*this);
  784. }
  785.  
  786. Builder& Builder::EndDict() {
  787.     if (nodes_stack_.empty()) {
  788.         throw std::logic_error("unable to close as without opening");
  789.     }
  790.  
  791.     Node node = *nodes_stack_.back();
  792.  
  793.     if (!node.IsDict()) {
  794.         throw std::logic_error("object isn't dictionary");
  795.     }
  796.  
  797.     nodes_stack_.pop_back();
  798.     add_node(node);
  799.  
  800.     return *this;
  801. }
  802.  
  803. ArrayContext Builder::StartArray() {
  804.     nodes_stack_.emplace_back(std::move(std::make_unique<Node>(Array())));
  805.  
  806.     return ArrayContext(*this);
  807. }
  808.  
  809. Builder& Builder::EndArray() {
  810.     if (nodes_stack_.empty()) {
  811.         throw std::logic_error("unable to close without opening");
  812.     }
  813.  
  814.     Node node = *nodes_stack_.back();
  815.  
  816.     if (!node.IsArray()) {
  817.         throw std::logic_error("object isn't array");
  818.     }
  819.  
  820.     nodes_stack_.pop_back();
  821.     add_node(node);
  822.  
  823.     return *this;
  824. }
  825.  
  826. Node Builder::Build() {
  827.     if (root_.IsNull()) {
  828.         throw std::logic_error("empty json");
  829.     }
  830.  
  831.     if (!nodes_stack_.empty()) {
  832.         throw std::logic_error("invalid json");
  833.     }
  834.  
  835.     return root_;
  836. }
  837.  
  838. }//end namespace json
  839. -----------------------------------------------------------------------
  840. main.cpp
  841. -----------------------------------------------------------------------
  842. #include "json_builder.h"
  843.  
  844. #include <iostream>
  845.  
  846. using namespace std;
  847.  
  848. int main() {
  849.    
  850.     json::Print(
  851.         json::Document{
  852.             json::Builder{}
  853.             .StartDict()
  854.                 .Key("key1"s).Value(123)
  855.                 .Key("key2"s).Value("value2"s)
  856.                 .Key("key3"s).StartArray()
  857.                     .Value(456)
  858.                     .StartDict().EndDict()
  859.                     .StartDict()
  860.                         .Key(""s)
  861.                         .Value(nullptr)
  862.                     .EndDict()
  863.                     .Value(""s)
  864.                 .EndArray()
  865.             .EndDict()
  866.             .Build()
  867.         },
  868.         cout
  869.     );
  870.     cout << endl;
  871.  
  872.     json::Print(
  873.         json::Document{
  874.             json::Builder{}
  875.             .Value("just a string"s)
  876.             .Build()
  877.         },
  878.         cout
  879.     );
  880.     cout << endl;
  881.    
  882. }
Advertisement
Add Comment
Please, Sign In to add comment