Giter Site home page Giter Site logo

sajson's Introduction

Documentation

sajson

sajson is an extremely high-performance, in-place, DOM-style JSON parser written in C++.

Originally, sajson meant Single Allocation JSON, but it now supports dynamic allocation too.

Features

sajson parses an input document into a contiguous AST structure. Unlike some other high-performance JSON parsers, the AST is efficiently queryable. Object lookups by key are O(lg N) and array indexing is O(1).

sajson does not require that the input buffer is null-terminated. You can use it to parse straight out of a disk mmap or network buffer, for example.

sajson is in-situ: it modifies the input string. While parsing, string values are converted to UTF-8.

(Note: sajson pays a slight performance penalty for not requiring null termination of the input string. Because sajson is in-situ, many uses cases require copying the input data anyway. Therefore, I could be convinced to add an option for requiring null termination.)

Other Features

  • Single header file -- simply drop sajson.h into your project.
  • No exceptions, RTTI, or longjmp.
  • O(1) stack usage. No document will overflow the stack.
  • Only two number types: 32-bits and doubles.
  • Small code size -- suitable for Emscripten.
  • Has been fuzzed with American Fuzzy Lop.

AST Structure

The parsed AST's size is computed as such:

  • 2 words per string
  • 1 word per 32-bit integer value
  • 64 bits per floating point value
  • 1+N words per array, where N is the number of elements
  • 1+3N words per object, where N is the number of members

The values null, true, and false are encoded in tag bits and have no cost otherwise.

Allocation Modes

Single

The original sajson allocation mode allocates one word per byte of the input document. This is the fastest mode: because the AST and parse stack are guaranteed to fit, no allocation checks are required at runtime.

That is, on 32-bit platforms, sajson allocates 4 bytes per input character. On 64-bit platforms, sajson allocates 8 bytes per input character. Only use this parse mode if you can handle allocating the worst-case buffer size for your input documents.

Dynamic

The dynamic allocation mode grows the parse stack and AST buffer as needed. It's about 10-40% slower than single allocation because it needs to check for out-of-memory every time data is appended, and occasionally the buffers need to be reallocated and copied.

Bounded

The bounded allocation mode takes a fixed-size memory buffer and uses it for both the parse stack and the resulting AST. If the parse stack and AST fit in the given buffer, the parse succeeds. This allocation mode allows using sajson without the library making any allocations.

Performance

sajson's performance is excellent - it frequently benchmarks faster than RapidJSON, for example.

Implementation details are available at http://chadaustin.me/tag/sajson/.

Documentation

API documentation is available at http://chadaustin.github.io/sajson/doxygen/

Downsides / Missing Features

  • sajson does not support UTF-16 or UTF-32. However, I have never seen one of those in the wild, so I suspect they may be a case of aggressive overspecification. Some JSON specifications indicate that UTF-8 is the only valid encoding. Either way, just transcode to UTF-8 first.

  • No support for 64-bit integers. If this is something you want, just ask. (There's little technical reason not to support it. It's just that most people avoid 64-bit integers in JSON because JavaScript can't read them.)

  • Requires C++11. Some of the ownership semantics were awkward to express in C++03.

sajson's People

Contributors

chadaustin avatar dimitarcl avatar erez-o avatar flyingjester avatar gburtini avatar ibob avatar ihameed avatar kokosxd avatar saldivarcher avatar sdraw avatar wojdyr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

sajson's Issues

64-bit Int

Is there any hack to quickly add support for these? I use swift version and double representation of value is almost precise. Maybe I can cast payload somehow to Swift's Int? I've tried combinations of bit pattern and simple constructor casting but no success. Is it C++ library's engine limitation?

sajson::document and sajson::value cannot be member variable

I wanna wrap sajson,so I declare my class like this:

class HFJsonArray;
class HFJsonObject
{
public:

    explicit HFJsonObject(HFString& jsonString);
    virtual ~HFJsonObject();

public:
    HFInt32 GetInteger(HFString& key);
    HFDouble GetDouble(HFString& key);
    HFBool GetBoolean(HFString& key);
    HFString& GetString(HFString& key);
    HFJsonObject& GetJsonObject(HFString& key);
    HFJsonArray& GetJsonArray(HFString& key);

private:
    const sajson::document mDocument;
    const sajson::value& mValue;
};

In the cpp file:

HFJsonObject::HFJsonObject(HFString& jsonString)
{
    HFChar* str = (HFChar*)jsonString.GetBuffer();
    sajson::literal lt = sajson::literal((const char*)str);
    sajson::document doc = sajson::parse<sajson::literal>(lt);
    mValue = doc.get_root();
}

and compile error occur:

mValue = doc.get_root(); // semantic error: No viable overloaded '='

but this would work:

sajson::value myValue = doc.get_root();

as a result, I cannot implements the other function like GetInteger, GetDouble etc.. because I cannot get the sajson::value variable

Removing std::string from errors

I have a suggestion for a step towards removing the std::string dependency. Moving from error strings to error codes. You can see my implementation here: iboB@5568a59

If you like it, I'll add a pull request

Extended functionality

Thanks for an excellent library!

I forked it to make some minor extensions, mainly overloaded operators for array indexing, object element access and value comparison.

I could make a pull request from it but I don't know if you are interested in extending the library in this way!

Anyway, the fork lives here: https://github.com/erikronstrom/sajson

Parsing failure

I recently try to add sajson to nativejson-benchmark in this branch.

It was able to parse two test json data, but failed for twitter.json. The error message generated is

Verifying sajson (C++) ... Error (1:1): illegal unprintable codepoint in string

with this code:

class SajsonParseResult : public ParseResultBase {
public:
    SajsonParseResult(document&& d_) : d(std::move(d_)) {}
    document d;
};

// ...
    virtual ParseResultBase* Parse(const char* json, size_t length) const {
        (void)length;
        SajsonParseResult* pr = new SajsonParseResult(parse(literal(json)));
        if (!pr->d.is_valid()) {
            std::cout << "Error (" << pr->d.get_error_line() << ":" << pr->d.get_error_column() << "): " << pr->d.get_error_message() << std::endl;
        }
        return pr;
    }

I am pretty sure the json is valid, as it is obtained from twitter's API, and also passed more than a dozens of parsers.

BTW, I am the author of RapidJSON :)

preserving key order in objects

This may be a non-goal for sajson, but I wanted to preserve the order of keys, so I can write everything back to a file minimizing differences with the original file.
As a quick hack I added a couple of #ifdefs to disable key sorting and to remove affected functions:
project-gemmi/gemmi@8668bee

Not sure if it's worth upstreaming, but just to let you know.

Problem with decoding Double values using Swift

I've been playing around with the Swift interface to sajson and been working on adopting Swift4's Decodable protocol to use sajson instead of Foundation's JSONSerialization. I came across a problem with decoding floating point numbers though. I'm not yet sure if the error is in the Swift bridge or in sajson itself. Maybe the original author of the Swift code has an idea?

See below for a test case where decoding two ValueReader.double values results in one being slightly off and the other one being completely off.

   func test_floats() {
       let doc = try! parse(allocationStrategy: .single, input: "{\"start\": 12.948, \"end\": 42.1234}")
       doc.withRootValueReader { docValue in
           guard case .object(let objectReader) = docValue else { XCTFail(); return }
           XCTAssert(objectReader.count == 2)
           guard let startValue = objectReader["start"], case let .double(start) = startValue else { XCTFail(); return }
           guard let endValue = objectReader["end"], case let .double(end) = endValue else { XCTFail(); return }
           
           XCTAssertEqual(start, 12.948)
           // XCTAssertEqual failed: ("12.9480152587891") is not equal to ("12.948") - 

           XCTAssertEqual(end, 42.1234)
           // XCTAssertEqual failed: ("981442340.4544") is not equal to ("42.1234") - 
       }
   }

No allocation mode for sajson?

Hi, I'm wondering if it is possible to officially support using sajson without any allocation at all. Currently, even if one uses

auto doc = sajson::parse(sajson::single_allocation(buffer, length), sajson::mutable_string_view(length, str));

there will still be one allocation due to the use of refcount in mutable_string_view. In some applications allocations should be avoided as much as possible, but in this case sajson will still call operator new with a size of a size_t.

I have a locally patched version of sajson that removes the use of refcount and changes mutable_string_view to only take unowned strings:

--- a/sajson.h
+++ b/sajson.h
@@ -235,37 +235,13 @@ namespace sajson {
         mutable_string_view()
             : length_(0)
             , data(0)
-            , owns(false)
         {}

         mutable_string_view(size_t length, char* data)
             : length_(length)
             , data(data)
-            , owns(false)
         {}

-        mutable_string_view(const literal& s)
-            : length_(s.length())
-            , owns(true)
-        {
-            data = new char[length_];
-            memcpy(data, s.data(), length_);
-        }
-
-        mutable_string_view(const string& s)
-            : length_(s.length())
-            , owns(true)
-        {
-            data = new char[length_];
-            memcpy(data, s.data(), length_);
-        }
-
-        ~mutable_string_view() {
-            if (uses.count() == 1 && owns) {
-                delete[] data;
-            }
-        }
-
         size_t length() const {
             return length_;
         }
@@ -275,10 +251,8 @@ namespace sajson {
         }

     private:
-        refcount uses;
         size_t length_;
         char* data;
-        bool owns;
     };

     union integer_storage {

I'm thinking perhaps sajson could incorporate something similar officially? Perhaps using an ifdef, or some more templating? If this sounds cool, I can proceed to make a PR.

add incremental memory growth

Right now sajson allocates an upper bound memory usage. That's rarely needed. Add an option to allow memory growth.

validate UTF-8 in strings

It would be nice for sajson to guarantee that string values were encoded as UTF-8. Today we don't guarantee that in the case of a malformed UTF-8 code in a string.

arrays of objects test fails??

I added this to test.cpp and it fails maybe I'm doing something wrong?

TEST(object_array) {
const sajson::document& document = parse(literal("[{ "a": 123456 }, { "a": 7890 }]"));
assert(success(document));
const value& root = document.get_root();
CHECK_EQUAL(TYPE_ARRAY, root.get_type());
CHECK_EQUAL(2u, root.get_length());

const value& e1 = root.get_array_element(0);
CHECK_EQUAL(TYPE_OBJECT, e1.get_type());
size_t index_a = e1.find_object_key(literal("a"));
const value& node = root.get_object_value(index_a);
CHECK_EQUAL(TYPE_INTEGER, node.get_type());
CHECK_EQUAL(123456U, node.get_number_value());
const value& e2 = root.get_array_element(0);
CHECK_EQUAL(TYPE_OBJECT, e2.get_type());
index_a = e2.find_object_key(literal("a"));
const value& node1 = root.get_object_value(index_a);
CHECK_EQUAL(7890U, node1.get_number_value());

}

Documentation with API references

Hi,

I've created a documentation with API references - https://sajson.docsforge.com/

The docs are updated automatically so it will be in sync if the source files, readme, or examples are changed.

If you want me to add or remove any pages (like namespace internal), please let me know :)

Disclaimer, I'm the creator of docsforge.

optimize number parsing

The only benchmark where sajson loses to rapidjson is number parsing. Need to split the integer loop from the floating point loop (which has the important effect of breaking p's dependency chain on the numeric value).

undefined behaviour in integer_storage and double_storage

After reading your blog post about sajson optimizations (it was a really interesting read) I started browsing the code. I noticed type-punning through a union:

    union integer_storage {
        enum {
            word_length = 1
        };

        static void store(size_t* location, int value) {
            integer_storage is;
            is.i = value;
            *location = is.u;
        }

        int i;
        size_t u;
    };

From what I know from reading discussions on SO this is an undefined behavior in C++ (although a common practice). Just to let you know.

(it's not a big deal; I think I'll start using this library soon anyway)

How to use Swift version?

Hey there!
I think switching enum with guard case . for every object in json isn't the best way, am I right? Could you show me real world (production) examples of using this lib?

Question about invalid UTF-8

Hi! I am a spanish newbie with string encoding,

I try:

int main()
{
	std::string json = "{\"name\":\"áéíóúñ¡¿\"}";
	size_t longitud = json.length();

	char m_json[32];
	strcpy(m_json, json.c_str());

	const sajson::document& document = sajson::parse(sajson::dynamic_allocation(), 
        sajson::mutable_string_view(longitud, m_json));
	if (!document.is_valid())
	{
	    return -1;
	}
        return 0;
}

I get: ERROR_INVALID_UTF8 (22)

How can solve this problem? I have test utilities like http://utfcpp.sourceforge.net/ for ensuring that a string contains valid UTF-8. And then it works! But... i don´t want to lose the original characters,,, (!)

Thanks!

DJuego

Stream json parsing

Is there a way to parse the JSON string from a network stream (JSON as bytes stream or data chunks)?

Signed integer overflow in parse_number()

Here's the input that will trigger the issue:
int_overflow.txt
Feed it into master(cbd7a20) parse() function built with UndefinedBehaviorSanitizer will crash the parser:

> ./parse int_overflow.txt
sajson.h:2105:30: runtime error: signed integer overflow: 10 * 999999006 cannot be represented in type 'int'
    #0 0x520ccb in sajson::parser<sajson::dynamic_allocation::allocator>::parse_number(char*) /home/grieve/scratch/sajson/./sajson.h:2105:30
    #1 0x518953 in sajson::parser<sajson::dynamic_allocation::allocator>::parse() /home/grieve/scratch/sajson/./sajson.h:1806:39
    #2 0x5156a6 in sajson::parser<sajson::dynamic_allocation::allocator>::get_document() /home/grieve/scratch/sajson/./sajson.h:1529:17
    #3 0x513ae5 in sajson::document sajson::parse<sajson::dynamic_allocation, sajson::mutable_string_view>(sajson::dynamic_allocation const&, sajson::mutable_string_view const&) /home/grieve/scratch/sajson/./sajson.h:2467:11
    #4 0x5130d9 in main /home/grieve/scratch/sajson/parse.cpp:24:23
    #5 0x7fcc1b4b44c9 in __libc_start_main (/usr/lib/libc.so.6+0x204c9)
    #6 0x419d59 in _start (/home/grieve/scratch/sajson/parse+0x419d59)

Here is the full source list of parse.cpp I used in the aforementioned testing:

#include "sajson.h"
#include <cstring>
#include <utility>
#include <fstream>
#include <istream>

using namespace sajson;

std::pair<char*, std::size_t> readBytes(const char* filename) {
  std::ifstream ifs(filename, std::ios::binary|std::ios::ate);
  auto pos = ifs.tellg();
  std::size_t len = pos;

  char* buf = new char[len];
  ifs.seekg(0, std::ios::beg);
  ifs.read(buf, len);
  ifs.close();
  return std::make_pair(buf, len);
}

int main(int argc, char** argv) {
  if (argc > 1) {
    auto res = readBytes(argv[1]);
    auto const& doc = parse(dynamic_allocation(), mutable_string_view(res.second, res.first));
    delete[] res.first;
  }
}

Allocator problems

I don't think the current allocator approach is the way to go.

As far as I understand the point of the dynamic_allocator is to keep the structure buffer's size as small as possible (which is more suitable for a library called majson - Multiple Allocations JSON 😄 ). Of course I wouldn't have a problem with that if it wasn't at the cost of having multiple if-checks for allocation errors at every place it could allocate memory, needlessly slowing the execution.

I (and I think the majority of the user base) would much rather lose the possibility to keep the memory minimal, than pay the price for those checks.

I urge you to consider dropping the dynamic_allocation strategy and focusing on minimizing the allocations.

I had developed allocators internally before which only had: void* allocate(size_t size)/void deallocate(void* buf, size_t size), and they were used for the both the structure and the input buffers, thus allowing the library to always work with zero allocations with custom allocators.

I'll migrate my changes to the new version of sajson some time next week and if you're interested I'll post a link here. Here's the gist of features:

  • Removing mutable_string_view in favor of manually managed pointers
  • Simple allocate/deallocate allocators. One or two calls to allocate per parse (one if the input is mutable as is, two if a new input buffer needs to be allocated)
  • No if checks in parser for bad allocations. Parser assumes sufficient buffers
  • No ownership "safety" (well the safety isn't ensured by ownership patterns. It's just how the code is written). Ownership of the buffers is manually transferred from the parser to the document if a valid document can be created (document must remain non-copyable as it is now).

Optimize string values and keys

I think the idea to copy and modify the input json string is great (and on a humorous note, perhaps the library's name should be dajson, as you make two allocations - one for the payload and one for the input text).

Anyway... copying the input works great for parse_string_slow, but I think you're not taking it far enough. Currently getting keys and sensible string values requires allocations (by creating std::string-s), which may not always be needed. For example if the user only wants to compare those to existing values, these allocations are pointless.

I have made a change here which alters the input buffer by adding zeroes at the end of strings (replacing the closing quotation marks). Thus a safe const char* may be returned, and the decision whether an allocation is to be made when using strings is left to the user.

Not a pull request yet, since it's a non-backwards-compatible change. You may have an ideas about that. Keep the old functions and add new? Major/minor version increment?

Unhandled error return value in sajson.h: parser::parse()

Within the parser::parse() function of sajson.h the return value of a call to parse_string() is ignored leading to a corrupt representation of the parsed objects.

From sajson::parser::parse()

if (current_structure_type == TYPE_OBJECT && c != '}') {
  if (c != '"') {
    return error("object key must be quoted");
  }
  result = parse_string(temp);
  if (peek_structure() != ':') {
    return error("expected :");
  }
  ++p;
  temp += 2;
}

When parsing an object key string the return value result of parse_string() is later overwritten. As long as the character following the string parsing error is a ':' and the value for the key is valid, the parser will overwrite that error return value before it is checked and parsing will continue as if the key string is valid.

The bug can be demonstrated in a debugger using the following input to sajson::parser::parse()

{"\:0}

The initial object's key string is invalid and will generate an error within sajson::parser::parse_string_slow()

switch (*p) {
...
default:
  return error("unknown escape");

This error value will be passed back to sajson::parser::parse() and written to the result variable. However, upon entering the following code the result variable will be overwritten with the return value of sajson::parser::parse_number().

switch (peek_structure()) {
  type next_type;
  ...
  case '0':
  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
  case '-':
    result = parse_number();
    break;
  ...
if (!result) {
  return result.success;
}

When the value of result is finally checked the error value will no longer be present and parsing will continue with a bad element. In this simple case the parser does not crash.

A more complicated object hierarchy can cause the parser to crash when the object containing the bad key is passed to sajson::parser::install_object(). The following input to sajson::parser::parse() can be used to demonstrate a crash when a corrupted object is sorted.

{"":0,"":0,"":[0.,""],"\:[0.,""],"\:[]}

The following patch can be implemented to correctly check the return value of sajson::parser::parse_string()

diff --git a/include/sajson.h b/include/sajson.h
index 350c58e..7ad08ad 100644
--- a/include/sajson.h
+++ b/include/sajson.h
@@ -618,6 +618,9 @@ namespace sajson {
                         return error("object key must be quoted");
                     }
                     result = parse_string(temp);
+                    if (!result) {
+                        return result.success;
+                    }
                     if (peek_structure() != ':') {
                         return error("expected :");
                     }

Parsing big integers

Hi,

sajson interpret big numbers like 1496756396000 as double, because

                if (SAJSON_UNLIKELY(!try_double && i > INT_MAX / 10 - 9)) {                                                                        
                    // TODO: could split this into two loops                                                                                       
                    try_double = true;                                                                                                             
                    d = i;                                                                                                                                         
                } 

Could you please fix that?

'parse_flags' redefinition ; different storage class

Hello Im trying to compile with visual studio 2015 and this error appears:
'parse_flags' redefinition ; different storage class

This is located in sajson.h line 152 constexpr uint8_t globals_struct::parse_flags[256] = {

Any idea?

warnings with -Wshadow

The -Wshadow flag in GCC and Clang generates a number of warnings in sajson.h (copied below). This flag is not very popular, but on the other hand it'd not harm to avoid the warnings.

$ g++-7 -c -std=c++11 -Wshadow -Iinclude example/main.cpp
In file included from example/main.cpp:2:0:
include/sajson.h: In constructor ‘sajson::string::string(const char*, size_t)’:
include/sajson.h:221:13: warning: declaration of ‘text’ shadows a member of ‘sajson::string’ [-Wshadow]
             : text(text)
             ^
include/sajson.h:240:27: note: shadowed declaration is here
         const char* const text;
                           ^~~~
include/sajson.h: In constructor ‘sajson::literal::literal(const char*)’:
include/sajson.h:251:13: warning: declaration of ‘text’ shadows a member of ‘sajson::literal’ [-Wshadow]
             : string(text, strlen(text))
             ^
include/sajson.h:240:27: note: shadowed declaration is here
         const char* const text;
                           ^~~~
include/sajson.h: In constructor ‘sajson::mutable_string_view::mutable_string_view(size_t, char*)’:
include/sajson.h:271:13: warning: declaration of ‘data’ shadows a member of ‘sajson::mutable_string_view’ [-Wshadow]
             : length_(length)
             ^
include/sajson.h:345:15: note: shadowed declaration is here
         char* data;
               ^~~~
include/sajson.h: In constructor ‘sajson::value::value(sajson::type, const size_t*, const char*)’:
include/sajson.h:615:13: warning: declaration of ‘text’ shadows a member of ‘sajson::value’ [-Wshadow]
             : value_type(value_type)
             ^
include/sajson.h:634:27: note: shadowed declaration is here
         const char* const text;
                           ^~~~
include/sajson.h:615:13: warning: declaration of ‘payload’ shadows a member of ‘sajson::value’ [-Wshadow]
             : value_type(value_type)
             ^
include/sajson.h:633:29: note: shadowed declaration is here
         const size_t* const payload;
                             ^~~~~~~
include/sajson.h:615:13: warning: declaration of ‘value_type’ shadows a member of ‘sajson::value’ [-Wshadow]
             : value_type(value_type)
             ^
include/sajson.h:632:20: note: shadowed declaration is here
         const type value_type;
                    ^~~~~~~~~~
include/sajson.h: In constructor ‘sajson::internal::ownership::ownership(size_t*)’:
include/sajson.h:674:17: warning: declaration of ‘p’ shadows a member of ‘sajson::internal::ownership’ [-Wshadow]
                 : p(p)
                 ^
include/sajson.h:691:21: note: shadowed declaration is here
             size_t* p;
                     ^
include/sajson.h: In constructor ‘sajson::internal::ownership::ownership(sajson::internal::ownership&&)’:
include/sajson.h:678:13: warning: declaration of ‘p’ shadows a member of ‘sajson::internal::ownership’ [-Wshadow]
             : p(p.p) {
             ^
include/sajson.h:691:21: note: shadowed declaration is here
             size_t* p;
                     ^
In file included from example/main.cpp:2:0:
include/sajson.h: In constructor ‘sajson::document::document(const sajson::mutable_string_view&, sajson::internal::ownership&&, sajson::type, const size_t*)’:
include/sajson.h:828:13: warning: declaration of ‘root’ shadows a member of ‘sajson::document’ [-Wshadow]
             : input(input)
             ^
include/sajson.h:865:29: note: shadowed declaration is here
         const size_t* const root;
                             ^~~~
include/sajson.h:828:13: warning: declaration of ‘root_type’ shadows a member of ‘sajson::document’ [-Wshadow]
             : input(input)
             ^
include/sajson.h:864:20: note: shadowed declaration is here
         const type root_type;
                    ^~~~~~~~~
include/sajson.h:828:13: warning: declaration of ‘structure’ shadows a member of ‘sajson::document’ [-Wshadow]
             : input(input)
             ^
include/sajson.h:863:29: note: shadowed declaration is here
         internal::ownership structure;
                             ^~~~~~~~~
include/sajson.h:828:13: warning: declaration of ‘input’ shadows a member of ‘sajson::document’ [-Wshadow]
             : input(input)
             ^
include/sajson.h:862:29: note: shadowed declaration is here
         mutable_string_view input;
                             ^~~~~
include/sajson.h: In constructor ‘sajson::document::document(const sajson::mutable_string_view&, size_t, size_t, sajson::error, int)’:
include/sajson.h:841:13: warning: declaration of ‘error_arg’ shadows a member of ‘sajson::document’ [-Wshadow]
             : input(input)
             ^
include/sajson.h:869:19: note: shadowed declaration is here
         const int error_arg;
                   ^~~~~~~~~
include/sajson.h:841:13: warning: declaration of ‘error_code’ shadows a member of ‘sajson::document’ [-Wshadow]
             : input(input)
             ^
include/sajson.h:868:21: note: shadowed declaration is here
         const error error_code;
                     ^~~~~~~~~~
include/sajson.h:841:13: warning: declaration of ‘error_column’ shadows a member of ‘sajson::document’ [-Wshadow]
             : input(input)
             ^
include/sajson.h:867:22: note: shadowed declaration is here
         const size_t error_column;
                      ^~~~~~~~~~~~
include/sajson.h:841:13: warning: declaration of ‘error_line’ shadows a member of ‘sajson::document’ [-Wshadow]
             : input(input)
             ^
include/sajson.h:866:22: note: shadowed declaration is here
         const size_t error_line;
                      ^~~~~~~~~~
include/sajson.h:841:13: warning: declaration of ‘input’ shadows a member of ‘sajson::document’ [-Wshadow]
             : input(input)
             ^
include/sajson.h:862:29: note: shadowed declaration is here
         mutable_string_view input;
                             ^~~~~
include/sajson.h: In constructor ‘sajson::single_allocation::allocator::allocator(size_t*, size_t, bool)’:
include/sajson.h:952:17: warning: declaration of ‘should_deallocate’ shadows a member of ‘sajson::single_allocation::allocator’ [-Wshadow]
                 : structure(buffer)
                 ^
include/sajson.h:1022:18: note: shadowed declaration is here
             bool should_deallocate;
                  ^~~~~~~~~~~~~~~~~
include/sajson.h: In constructor ‘sajson::single_allocation::single_allocation(size_t*, size_t)’:
include/sajson.h:1040:13: warning: declaration of ‘existing_buffer’ shadows a member of ‘sajson::single_allocation’ [-Wshadow]
             : has_existing_buffer(true)
             ^
include/sajson.h:1077:17: note: shadowed declaration is here
         size_t* existing_buffer;
                 ^~~~~~~~~~~~~~~
include/sajson.h: In constructor ‘sajson::single_allocation::single_allocation(size_t (&)[N])’:
include/sajson.h:1049:13: warning: declaration of ‘existing_buffer’ shadows a member of ‘sajson::single_allocation’ [-Wshadow]
             : single_allocation(existing_buffer, N)
             ^
include/sajson.h:1077:17: note: shadowed declaration is here
         size_t* existing_buffer;
                 ^~~~~~~~~~~~~~~
include/sajson.h: In constructor ‘sajson::dynamic_allocation::allocator::allocator(size_t*, size_t, size_t)’:
include/sajson.h:1198:17: warning: declaration of ‘initial_stack_capacity’ shadows a member of ‘sajson::dynamic_allocation::allocator’ [-Wshadow]
                 : ast_buffer_bottom(buffer)
                 ^
include/sajson.h:1296:20: note: shadowed declaration is here
             size_t initial_stack_capacity;
                    ^~~~~~~~~~~~~~~~~~~~~~
include/sajson.h: In constructor ‘sajson::dynamic_allocation::dynamic_allocation(size_t, size_t)’:
include/sajson.h:1304:13: warning: declaration of ‘initial_stack_capacity’ shadows a member of ‘sajson::dynamic_allocation’ [-Wshadow]
             : initial_ast_capacity(initial_ast_capacity)
             ^
include/sajson.h:1336:16: note: shadowed declaration is here
         size_t initial_stack_capacity;
                ^~~~~~~~~~~~~~~~~~~~~~
include/sajson.h:1304:13: warning: declaration of ‘initial_ast_capacity’ shadows a member of ‘sajson::dynamic_allocation’ [-Wshadow]
             : initial_ast_capacity(initial_ast_capacity)
             ^
include/sajson.h:1335:16: note: shadowed declaration is here
         size_t initial_ast_capacity;
                ^~~~~~~~~~~~~~~~~~~~
include/sajson.h: In constructor ‘sajson::bounded_allocation::stack_head::stack_head(sajson::bounded_allocation::allocator*)’:
include/sajson.h:1399:17: warning: declaration of ‘source_allocator’ shadows a member of ‘sajson::bounded_allocation::stack_head’ [-Wshadow]
                 : source_allocator(source_allocator)
                 ^
include/sajson.h:1402:24: note: shadowed declaration is here
             allocator* source_allocator;
                        ^~~~~~~~~~~~~~~~
include/sajson.h: In constructor ‘sajson::bounded_allocation::bounded_allocation(size_t*, size_t)’:
include/sajson.h:1488:13: warning: declaration of ‘existing_buffer’ shadows a member of ‘sajson::bounded_allocation’ [-Wshadow]
             : existing_buffer(existing_buffer)
             ^
include/sajson.h:1509:17: note: shadowed declaration is here
         size_t* existing_buffer;
                 ^~~~~~~~~~~~~~~
include/sajson.h: In constructor ‘sajson::bounded_allocation::bounded_allocation(size_t (&)[N])’:
include/sajson.h:1496:13: warning: declaration of ‘existing_buffer’ shadows a member of ‘sajson::bounded_allocation’ [-Wshadow]
             : bounded_allocation(existing_buffer, N)
             ^
include/sajson.h:1509:17: note: shadowed declaration is here
         size_t* existing_buffer;
                 ^~~~~~~~~~~~~~~
include/sajson.h: In constructor ‘sajson::parser<Allocator>::parser(const sajson::mutable_string_view&, Allocator&&)’:
include/sajson.h:1520:13: warning: declaration of ‘allocator’ shadows a member of ‘sajson::parser<Allocator>’ [-Wshadow]
             : input(msv)
             ^
include/sajson.h:2433:19: note: shadowed declaration is here
         Allocator allocator;
                   ^~~~~~~~~
include/sajson.h: In member function ‘bool sajson::parser<Allocator>::parse()’:
include/sajson.h:1746:22: warning: declaration of ‘success’ shadows a previous local [-Wshadow]
                 bool success;
                      ^~~~~~~
include/sajson.h:1620:18: note: shadowed declaration is here
             bool success;
                  ^~~~~~~
include/sajson.h:1815:30: warning: declaration of ‘success’ shadows a previous local [-Wshadow]
                         bool success;
                              ^~~~~~~
include/sajson.h:1620:18: note: shadowed declaration is here
             bool success;
                  ^~~~~~~
include/sajson.h: In instantiation of ‘sajson::parser<Allocator>::parser(const sajson::mutable_string_view&, Allocator&&) [with Allocator = sajson::dynamic_allocation::allocator]’:
include/sajson.h:2464:16:   required from ‘sajson::document sajson::parse(const AllocationStrategy&, const StringType&) [with AllocationStrategy = sajson::dynamic_allocation; StringType = sajson::mutable_string_view]’
example/main.cpp:113:119:   required from here
include/sajson.h:1519:9: warning: declaration of ‘allocator’ shadows a member of ‘sajson::parser<sajson::dynamic_allocation::allocator>’ [-Wshadow]
         parser(const mutable_string_view& msv, Allocator&& allocator)
         ^~~~~~
include/sajson.h:2433:19: note: shadowed declaration is here
         Allocator allocator;
                   ^~~~~~~~~
include/sajson.h: In instantiation of ‘bool sajson::parser<Allocator>::parse() [with Allocator = sajson::dynamic_allocation::allocator]’:
include/sajson.h:1529:22:   required from ‘sajson::document sajson::parser<Allocator>::get_document() [with Allocator = sajson::dynamic_allocation::allocator]’
include/sajson.h:2467:24:   required from ‘sajson::document sajson::parse(const AllocationStrategy&, const StringType&) [with AllocationStrategy = sajson::dynamic_allocation; StringType = sajson::mutable_string_view]’
example/main.cpp:113:119:   required from here
include/sajson.h:1746:22: warning: declaration of ‘success’ shadows a previous local [-Wshadow]
                 bool success;
                      ^~~~~~~
include/sajson.h:1620:18: note: shadowed declaration is here
             bool success;
                  ^~~~~~~
include/sajson.h:1815:30: warning: declaration of ‘success’ shadows a previous local [-Wshadow]
                         bool success;
                              ^~~~~~~
include/sajson.h:1620:18: note: shadowed declaration is here
             bool success;
                  ^~~~~~~

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.