Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // WIP -- not done yet :)
- #include <optional>
- #include <string_view>
- #include <unordered_map>
- #include <variant>
- #include <vector>
- namespace json {
- struct Wrapper;
- using Null = std::nullptr_t;
- using Bool = bool;
- using Number = double;
- using String = std::string_view;
- using Array = std::vector<Value>;
- using Object = std::unordered_map<String, Value>;
- using Value = std::variant<Bool, Number, String, Array, Object, Null>;
- struct Wrapper {
- operator Value& () { return v; }
- operator const Value& () const { return v; }
- };
- namespace detail {
- std::optional<Object> parseObject() {
- Object object;
- if(!accept('{'))
- return {};
- if (expect('}'))
- return object;
- while (true) {
- if (auto s = parseString(); s) {
- if (!expect(':'))
- return {};
- if (auto v = parseValue(); v)
- object.emplace(s, v);
- else
- return {};
- if (expect(','))
- continue;
- if (expect('}')
- return object;
- return {};
- }
- return {};
- }
- }
- std::optional<Array> parseArray() {
- Array array;
- if (!accept('['))
- return {};
- if (expect(']'))
- return array;
- while (true) {
- if (auto v = parseValue(); v) {
- array.emplace_back(v);
- if (expect(','))
- continue;
- if (expect(']'))
- return array;
- return {};
- }
- return {};
- }
- }
- std::optional<String> parseString() {
- if (!accept('"'))
- return {};
- auto ptr = std::next(ctx.ptr());
- unsigned length{0};
- while (true) {
- ctx.advance(1);
- if (ctx.prev() != '\\' && ctx.curr() == '"')
- return {ptr, length};
- ++length;
- }
- return {};
- }
- std::optional<Number> parseNumber() {
- auto ptr = ctx.ptr();
- accept('-');
- if (!check(::isdigit))
- return {};
- while (check(::isdigit))
- ;
- if (accept('.')) {
- if (!check(::isdigit))
- return {};
- while (check(::isdigit))
- ;
- }
- if (accept('e') || accept('E')) {
- accept('+') || accept('-');
- if (!check(::isdigit))
- return {};
- while (check(::isdigit))
- ;
- }
- String asString{ptr, ctx.ptr() - ptr};
- return std::stod(asString);
- }
- std::optional<Value> parseValue() {
- if (accept("true"))
- return bool{true};
- if (accept("false"))
- return bool{false};
- if (accept("null"))
- return nullptr;
- if (auto n = parseNumber(); n)
- return n;
- if (auto s = parseString(); s)
- return s;
- if (auto o = parseObject(); o)
- return o;
- if (auto a = parseArray(); a)
- return a;
- return {};
- }
- } // end namespace detail
- std::optional<Object> parse() {
- return detail::parseObject();
- }
- } // end namespace json
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement