Giter Site home page Giter Site logo

nlohmann / json Goto Github PK

View Code? Open in Web Editor NEW
40.3K 765.0 6.5K 185.33 MB

JSON for Modern C++

Home Page: https://json.nlohmann.me

License: MIT License

C++ 96.94% Makefile 0.32% CMake 1.92% HTML 0.02% Meson 0.01% Cuda 0.01% Python 0.63% Jinja 0.07% Starlark 0.06% Swift 0.01%
json json-pointer json-patch cbor msgpack header-only stl-containers json-serialization json-parser rfc-6901

json's People

Contributors

abolz avatar aburgh avatar anthonyvh avatar ax3l avatar bradfora avatar chriskitching avatar dariomt avatar dota17 avatar dumarjo avatar falbrechtskirchinger avatar fangq avatar fhuberts avatar francois-air avatar gracicot avatar henryrlee avatar himikof avatar jseward avatar julian-becker avatar karzhenkov avatar nickaein avatar nlohmann avatar onqtam avatar pfeatherstone avatar pjkundert avatar robertmrk avatar t-b avatar teemperor avatar theodelrieu avatar tinytinni avatar type1j 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  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

json's Issues

Don't return "const values"

In member functions like dump and type_name, return std::string instead const std::string. Returning const values cause unnecessary copies to occur.

Avoid using spaces when encoding without pretty print

When encoding the JSON string with the dump method, it will insert some spaces (after ":" or ",") even without pretty print active. It will add some undesired extra bytes when the data is just going over the wire. In my case it is important as I am encoding JSON Web Tokens (JWT), and every byte its important as the token is being transmitted in every request.

Creating an empty array

I'm using the following code right now:

json customers;

for (...)
{
  customers.push_back(...)
}

cout << customers;

However, if the for loop doesnt happen, I would like to return an empty array (eg [])

Is they an other way to get this behaviour without doing json customers= json::parse("[]"); ?

unique_ptr for ownership

Since you're using C++11, wouldn't it be better to manage object ownership using unique_ptr?

I will issue a pull request when I start using your library.

Use of deprecated implicit copy constructor

Appears when -Wdeprecated is enabled on clang.

src/json.hpp:2076:26: warning: definition of implicit copy constructor for 'iterator' is deprecated because it has a user-declared copy assignment
      operator [-Wdeprecated]
        inline iterator& operator=(const iterator& other) noexcept
                         ^
test/unit.cpp:2471:37: note: implicit copy constructor for 'iterator' first required here
                json::iterator it = j.begin();

In file included from test/unit.cpp:13:
src/json.hpp:2579:32: warning: definition of implicit copy constructor for 'const_iterator' is deprecated because it has a user-declared copy
      assignment operator [-Wdeprecated]
        inline const_iterator& operator=(const const_iterator& other) noexcept
                               ^
test/unit.cpp:2496:38: note: implicit copy constructor for 'const_iterator' first required here
                json::const_iterator it = j_const.begin();
                                     ^

There are also some warnings involving floating point comparisons when Wfloat-equal is enabled:

src/json.hpp:1567:53: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
                    return lhs.m_value.number_float == static_cast<number_float_t>(rhs.m_value.number_integer);
                           ~~~~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
test/unit.cpp:127:21: note: in instantiation of member function 'nlohmann::operator==' requested here
            CHECK(j == j_reference);
                    ^
test/catch.hpp:8925:44: note: expanded from macro 'CHECK'
#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" )
                                           ^
test/catch.hpp:1484:39: note: expanded from macro 'INTERNAL_CATCH_TEST'
    } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look
                                      ^
In file included from test/unit.cpp:13:
src/json.hpp:1571:53: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
                    return lhs.m_value.number_float == rhs.m_value.number_float;
                           ~~~~~~~~~~~~~~~~~~~~~~~~ ^  ~~~~~~~~~~~~~~~~~~~~~~~~
src/json.hpp:4235:35: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
                    if (float_val == int_val)
                        ~~~~~~~~~ ^  ~~~~~~~

Problem getting vector (array) of strings

Considering the JSON below,

{
     "names": ["Tim", "Tom"],
     "num": [1, 2]
}

I want to get a vector of string. I realized that I could only use auto a = json["name"] and then process it using for-range loop. However, if I want to explicitly define the return type then I will get an error. For instance, both vector<string> names = j["names"] and vector<string> names = j["names"].get<vector<string>>() will give me an error:

./json.hpp:829:24: error: no matching constructor for initialization of 'std::__1::vector<std::__1::basic_string<char>,
      std::__1::allocator<std::__1::basic_string<char> > >'
                return T(m_value.array->begin(), m_value.array->end());

I can see that json library couldn't cast to vector<string>; however, it will work if I want to get num even explicitly like this: vector<float> f = j["num"].get<vector<float>>().

Now, I'm wondering if I am doing it wrong or it's not implemented?

Thanks,
Amir.

Do not use std::to_string

This is simply wrong:

    case (value_t::number_float):
    {
        return std::to_string(m_value.number_float);
    }

The to_string use std::locale what can change the point to comma (happened with us, because in QT the QApplication create change this) what is not good for json. You have to use always point instead of comma (json rpc standard)

Compilation results in tons of warnings

╭╴ (master=)╶╮
╰ jeff@siegfried:json $ uname -a
Linux siegfried 3.16.0-33-generic #44-Ubuntu SMP Thu Mar 12 12:19:35 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
╭╴ (master=)╶╮
╰ jeff@siegfried:json $ make
g++ -std=c++11 -Wall -Wextra -pedantic -Weffc++ -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-overflow=5 -Wswitch -Wundef -Wno-unused -Wnon-virtual-dtor -Wreorder -Wdeprecated -Wfloat-equal -I src -I test test/unit.cpp -o json_unit
In file included from test/unit.cpp:11:0:
test/catch.hpp:264:57: warning: ‘const T& Catch::operator+(const T&, Catch::StreamEndStop)’ should return by value [-Weffc++]
T const& operator + ( T const& value, StreamEndStop ) {
^
test/catch.hpp: In copy constructor ‘Catch::NotImplementedException::NotImplementedException(const Catch::NotImplementedException&)’:
test/catch.hpp:280:9: warning: ‘Catch::NotImplementedException::m_what’ should be initialized in the member initialization list [-Weffc++]
NotImplementedException( NotImplementedException const& ) {}
^
test/catch.hpp:280:9: warning: ‘Catch::NotImplementedException::m_lineInfo’ should be initialized in the member initialization list [-Weffc++]
In file included from test/unit.cpp:11:0:
test/catch.hpp: At global scope:
test/catch.hpp:478:7: warning: ‘class Catch::MethodTestCase’ only defines a private destructor and has no friends [-Wctor-dtor-privacy]
class MethodTestCase : public SharedImpl {
^
test/catch.hpp: In constructor ‘Catch::AssertionInfo::AssertionInfo()’:
test/catch.hpp:645:9: warning: ‘Catch::AssertionInfo::macroName’ should be initialized in the member initialization list [-Weffc++]
AssertionInfo() {}
^
test/catch.hpp:645:9: warning: ‘Catch::AssertionInfo::lineInfo’ should be initialized in the member initialization list [-Weffc++]
test/catch.hpp:645:9: warning: ‘Catch::AssertionInfo::capturedExpression’ should be initialized in the member initialization list [-Weffc++]
test/catch.hpp:645:9: warning: ‘Catch::AssertionInfo::resultDisposition’ should be initialized in the member initialization list [-Weffc++]
test/catch.hpp: In constructor ‘Catch::AssertionResultData::AssertionResultData()’:
test/catch.hpp:659:9: warning: ‘Catch::AssertionResultData::reconstructedExpression’ should be initialized in the member initialization list [-Weffc++]
AssertionResultData() : resultType( ResultWas::Unknown ) {}
^
test/catch.hpp:659:9: warning: ‘Catch::AssertionResultData::message’ should be initialized in the member initialization list [-Weffc++]

...

segmentation fault when iterating over empty arrays/objects

From an email:

Anyway, a quite serious bug is when one tries to iterate over a empty container (array or object), which results in a segmentation fault due to a 0x0 this pointer. I fixed this by changing the iterator constructors to check if the container is empty, and in that case set the “object_” pointer to a nullptr.

The proposed code fix:

json::const_iterator::const_iterator(const json* j) : object_(j)
{
    if (object_ != nullptr)
    {
        if (object_->type_ == value_type::array)
        {
            if (object_->empty())
// Explicit empty check added
            {
                object_ = nullptr;
            }
            else
            {
                vi_ = new array_t::const_iterator(object_->value_.array->begin());
            }
        }
        else if (object_->type_ == value_type::object)
// *else if* is mandatory since the previous
        {
// block can set pointer to nullptr!
            if (object_->empty())
// Explicit empty check added
            {
                object_ = nullptr;
            }
            else
            {
                oi_ = new object_t::const_iterator(object_->value_.object->begin());
            }
        }
    }
}

Add count member function

A typical operation is to find if a json object has a given key, this is typically done like:

json j;
bool has_key = j.find("key") != j.end();

The standard containers (std::map, std::set,...) offer a count member function that counts the number of occurrences of a key, such that one can:

std::map<std::string, int> m;
bool has_key = m.count("key");  // -> count == 0? false : true

It would be nice to have something similar since this is a very common operation.

Drop C++98 support

Supporting both C++98 and C++11 at the same time makes maintenance harder.

dump() / parse() not idempotent

If you construct a string of the JSON payload using dump() and then use parse() to deserialize it, the contents of the former object don't match the latter when there are escape characters. Example pseudo-code

void test_case()
{
    nlohmann::json fields;
    fields["one"] = std::string("one");
    fields["two"] = std::string("two three");
    fields["three"] = std::string("three \"four\"");
    std::string payload = fields.dump();

    nlohmann::json parsed_fields = fields_t::parse(payload);
    test_check_eq(parsed_fields.size(), fields.size());
    test_check_eq(parsed_fields["one"], fields["one"]);
    test_check_eq(parsed_fields["two"], fields["two"]);
    test_check_eq(parsed_fields["three"], fields["three"]);
}

Here parsed_fields["three"] == std::string("three \\\"four\\\""). If this is expected, then what should be done to parsed_fields in this case to recover the original contents?

Windows/Visual Studio (through 2013) is unsupported

I was about to use this for a C++ project in Visual Studio 2013, but the header fails compilation entirely, thanks to a myriad of errors:

1>------ Build started: Project: jsondummy, Configuration: Debug Win32 ------
1>  main.cpp
1>d:\github\jsondummy\src\json.hpp(137): error C2061: syntax error : identifier 'iterator'
1>          d:\github\jsondummy\src\json.hpp(4893) : see reference to class template instantiation 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>' being compiled
1>d:\github\jsondummy\src\json.hpp(137): error C2238: unexpected token(s) preceding ';'
1>d:\github\jsondummy\src\json.hpp(143): error C2061: syntax error : identifier 'const_iterator'
1>d:\github\jsondummy\src\json.hpp(143): error C2238: unexpected token(s) preceding ';'
1>d:\github\jsondummy\src\json.hpp(149): error C2061: syntax error : identifier 'reverse_iterator'
1>d:\github\jsondummy\src\json.hpp(149): error C2238: unexpected token(s) preceding ';'
1>d:\github\jsondummy\src\json.hpp(155): error C2061: syntax error : identifier 'const_reverse_iterator'
1>d:\github\jsondummy\src\json.hpp(155): error C2238: unexpected token(s) preceding ';'
1>d:\github\jsondummy\src\json.hpp(382): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(385): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(402): warning C4346: 'std::is_constructible<ObjectType<StringType,nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,>::key_type,V::key_type>::value' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(402): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(402): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(402): error C2143: syntax error : missing ',' before 'std::is_constructible<nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,V::mapped_type>::value'
1>d:\github\jsondummy\src\json.hpp(402): error C2977: 'std::enable_if' : too many template arguments
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtr1common(67) : see declaration of 'std::enable_if'
1>d:\github\jsondummy\src\json.hpp(403): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\github\jsondummy\src\json.hpp(426): error C2065: 'not' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(426): warning C4346: 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::iterator' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(426): error C2923: 'std::is_same' : 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::iterator' is not a valid template type argument for parameter '_Ty2'
1>d:\github\jsondummy\src\json.hpp(426): error C2143: syntax error : missing ',' before 'std::integral_constant<bool,false>::value'
1>d:\github\jsondummy\src\json.hpp(427): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(427): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(427): error C2146: syntax error : missing ',' before identifier 'not'
1>d:\github\jsondummy\src\json.hpp(427): error C2065: 'not' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(427): warning C4346: 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::const_iterator' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(427): error C2923: 'std::is_same' : 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::const_iterator' is not a valid template type argument for parameter '_Ty2'
1>d:\github\jsondummy\src\json.hpp(427): error C2143: syntax error : missing ',' before 'std::integral_constant<bool,false>::value'
1>d:\github\jsondummy\src\json.hpp(428): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(428): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(428): error C2146: syntax error : missing ',' before identifier 'not'
1>d:\github\jsondummy\src\json.hpp(428): error C2065: 'not' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(428): warning C4346: 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::reverse_iterator' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(428): error C2923: 'std::is_same' : 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::reverse_iterator' is not a valid template type argument for parameter '_Ty2'
1>d:\github\jsondummy\src\json.hpp(428): error C2143: syntax error : missing ',' before 'std::integral_constant<bool,false>::value'
1>d:\github\jsondummy\src\json.hpp(429): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(429): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(429): error C2146: syntax error : missing ',' before identifier 'not'
1>d:\github\jsondummy\src\json.hpp(429): error C2065: 'not' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(429): warning C4346: 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::const_reverse_iterator' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(429): error C2923: 'std::is_same' : 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::const_reverse_iterator' is not a valid template type argument for parameter '_Ty2'
1>d:\github\jsondummy\src\json.hpp(429): error C2143: syntax error : missing ',' before 'std::integral_constant<bool,false>::value'
1>d:\github\jsondummy\src\json.hpp(430): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(430): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(430): error C2146: syntax error : missing ',' before identifier 'not'
1>d:\github\jsondummy\src\json.hpp(430): error C2065: 'not' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(430): error C2143: syntax error : missing ',' before 'std::is_same<V,ArrayType<nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,>::iterator>::value'
1>d:\github\jsondummy\src\json.hpp(431): warning C4346: 'std::is_same<V,ArrayType<nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,>::iterator>::value' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(431): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(431): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(431): error C2146: syntax error : missing ',' before identifier 'not'
1>d:\github\jsondummy\src\json.hpp(431): error C2065: 'not' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(431): error C2143: syntax error : missing ',' before 'std::is_same<V,ArrayType<nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,>::const_iterator>::value'
1>d:\github\jsondummy\src\json.hpp(432): warning C4346: 'std::is_same<V,ArrayType<nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,>::const_iterator>::value' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(432): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(432): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(432): error C2143: syntax error : missing ',' before 'std::is_constructible<nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,V::value_type>::value'
1>d:\github\jsondummy\src\json.hpp(432): error C2977: 'std::enable_if' : too many template arguments
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtr1common(67) : see declaration of 'std::enable_if'
1>d:\github\jsondummy\src\json.hpp(433): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\github\jsondummy\src\json.hpp(434): error C2535: 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::basic_json(const V &)' : member function already defined or declared
1>          d:\github\jsondummy\src\json.hpp(404) : see declaration of 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::basic_json'
1>d:\github\jsondummy\src\json.hpp(485): warning C4346: 'std::is_constructible<NumberIntegerType,T>::value' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(485): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(485): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(485): error C2143: syntax error : missing ',' before 'std::numeric_limits<T>::is_integer'
1>d:\github\jsondummy\src\json.hpp(485): error C2977: 'std::enable_if' : too many template arguments
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtr1common(67) : see declaration of 'std::enable_if'
1>d:\github\jsondummy\src\json.hpp(486): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\github\jsondummy\src\json.hpp(487): warning C4346: 'std::numeric_limits<T>::is_integer' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(487): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(502): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(594): warning C4346: 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::iterator' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(594): error C2923: 'std::is_same' : 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::iterator' is not a valid template type argument for parameter '_Ty2'
1>d:\github\jsondummy\src\json.hpp(595): error C2146: syntax error : missing ',' before identifier 'or'
1>d:\github\jsondummy\src\json.hpp(595): error C2065: 'or' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(595): warning C4346: 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::const_iterator' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(595): error C2923: 'std::is_same' : 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::const_iterator' is not a valid template type argument for parameter '_Ty2'
1>d:\github\jsondummy\src\json.hpp(596): error C2143: syntax error : missing ',' before 'std::integral_constant<bool,false>::value'
1>d:\github\jsondummy\src\json.hpp(596): error C2977: 'std::enable_if' : too many template arguments
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtr1common(67) : see declaration of 'std::enable_if'
1>d:\github\jsondummy\src\json.hpp(597): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\github\jsondummy\src\json.hpp(748): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(761): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(762): warning C4346: 'std::is_nothrow_move_constructible<nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>::value_t>::value' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(762): error C2061: syntax error : identifier 'value'
1>d:\github\jsondummy\src\json.hpp(767): error C2091: function returns function
1>d:\github\jsondummy\src\json.hpp(779): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(838): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(851): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(857): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(863): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(869): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(875): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(881): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(887): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(893): error C3646: 'noexcept' : unknown override specifier
1>d:\github\jsondummy\src\json.hpp(906): warning C4346: 'std::is_convertible<ObjectType<StringType,nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,>::key_type,T::key_type>::value' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(906): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(906): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(907): error C2143: syntax error : missing ',' before 'std::is_convertible<nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,T::mapped_type>::value'
1>d:\github\jsondummy\src\json.hpp(907): error C2977: 'std::enable_if' : too many template arguments
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtr1common(67) : see declaration of 'std::enable_if'
1>d:\github\jsondummy\src\json.hpp(907): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\github\jsondummy\src\json.hpp(943): warning C4346: 'std::is_convertible<nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,T::value_type>::value' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(943): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(943): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(943): error C2146: syntax error : missing ',' before identifier 'not'
1>d:\github\jsondummy\src\json.hpp(943): error C2065: 'not' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(943): error C2143: syntax error : missing ',' before 'std::is_same<nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,T::value_type>::value'
1>d:\github\jsondummy\src\json.hpp(944): warning C4346: 'std::is_same<nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,AllocatorType>,T::value_type>::value' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(944): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(944): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(944): error C2146: syntax error : missing ',' before identifier 'not'
1>d:\github\jsondummy\src\json.hpp(944): error C2065: 'not' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(944): error C2143: syntax error : missing ',' before 'std::is_arithmetic<T>::value'
1>d:\github\jsondummy\src\json.hpp(945): warning C4346: 'std::is_arithmetic<T>::value' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(945): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(945): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(945): error C2146: syntax error : missing ',' before identifier 'not'
1>d:\github\jsondummy\src\json.hpp(945): error C2065: 'not' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(945): error C2143: syntax error : missing ',' before 'std::is_convertible<std::string,T>::value'
1>d:\github\jsondummy\src\json.hpp(946): warning C4346: 'std::is_convertible<std::string,T>::value' : dependent name is not a type
1>          prefix with 'typename' to indicate a type
1>d:\github\jsondummy\src\json.hpp(946): error C2146: syntax error : missing ',' before identifier 'and'
1>d:\github\jsondummy\src\json.hpp(946): error C2065: 'and' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(946): error C2146: syntax error : missing ',' before identifier 'not'
1>d:\github\jsondummy\src\json.hpp(946): error C2065: 'not' : undeclared identifier
1>d:\github\jsondummy\src\json.hpp(947): error C2143: syntax error : missing ',' before 'nlohmann::has_mapped_type<T>::value'
1>d:\github\jsondummy\src\json.hpp(947): error C2977: 'std::enable_if' : too many template arguments
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtr1common(67) : see declaration of 'std::enable_if'
1>d:\github\jsondummy\src\json.hpp(947): fatal error C1003: error count exceeds 100; stopping compilation
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

This is on VS2013, and as far as I know it supports 90% of the standard (but not some of what you're using here, like noexcept).

Are you planning to support Visual Studio/Windows some time later on?

Improper parsing of JSON string "\\"

Currently the parser assumes if a '' is before a double quote, the double quote isn't the end of the string.

Note that there are more complicated cases like this (and their expansion) which need to be handled properly which probably will take more code to support properly: ("\"", "\") of arbitrary length. A reverse search which checks if the number of '' preceding the quote is even or odd would do it: https://github.com/nlohmann/json/blob/master/src/json.cc#L2050

Performance in backslash-heavy strings may suffer a lot though. Might be better to do a pure forward scan of the string counting backslashes as you go (Lots of memory access, but it should all be prefetched + L1 cached by current x86, x64 CPUs).

Key iterator

When iterating over a json object, e.g. using a range-based for loop, one only gets the values, and it is impossible right now to get the key of each value. It would be nice to be able to iterate over the keys, since this allows you to get the value afterwards if you want too.

Another alternative is a key.value pair iterator like map.

Cannot encode long numbers

I cannot encode a unsigned long or unsigned long long value without casting it to int, with its corresponding overflow. It is required, i.e., for storing a timestamp in milliseconds from epoch.

free functions for explicit objects and arrays in initializer lists

Currently,

{{"a","b"},{"c","d"}}

will be treated as object, and there is no way to express it as array of two arrays with two strings each.

As tgockel points out:

I can't say it's a great solution, but in JSON Voorhees, I went with free functions called array and object to disambiguate the initializer_list syntax. It also solves the issue of {} ambiguously meaning an empty object or empty array (and accidentally making an array when given string_views or something).

Such free functions could solve the above problem:

{array({"a","b"}), array({"c","d"})}

Add to_string overload for indentation

Create an overload of the to_string member function that handles indentation (spaces) and line breaks.

const std::string to_string(int indent) const noexcept

dumping a small number_float just outputs 0.000000

I expected that small doubles would be represented in dumped JSON as a javascript number in scientific notation, but instead it just appears as 0.000000

Example:

#include <iostream>

#include "json.hpp"
using json = nlohmann::json;

main() {
  double d = 1.23456e-89;
  json j = d;

  std::cout << "d=" << d << " j=" << j << std::endl;
}

Expected output: d=1.23456e-89 j=1.23456e-89

Actual output: d=1.23456e-89 j=0.000000

Looking at the json code, it appears this is due to using std::to_string() for all numbers, which is equivalent to sprintf("%f", ...) whereas sprintf("%g", ...) would be more appropriate. To fix this, the dump function would need to use something other than to_string to format floating point numbers. I'll try to put together a PR for this although C++ is far from my best language.

Compilation error due to assuming that private=public

The snippet to reproduce the error:

  struct A {
    nlohmann::json j;
    auto has_entry(std::string n) {
      return j.find(n) != j.end() ? true : false;
    }
  };

what the error looks like:

src/json.hpp:1073:20: error: 'm_it' is a private member of 'nlohmann::basic_json<std::map, std::vector, std::__1::basic_string<char>, bool, long long,
      double, std::allocator>::const_iterator'
            result.m_it.object_iterator = m_value.object->find(key);
                   ^

This is not catched by the unit tests because they are compiled by defining private=public.

A "better" way to do that could be to have a separate file only for those tests that "need" private=public.

This might be clang 3.6 specific, since I'm the only one who seems to be having problems.

I worked around this issue by including the library as follows:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
#pragma clang diagnostic ignored "-Wdeprecated"
#define private public
#include <json.hpp>
#define private private
#pragma clang diagnostic pop

Use non-member begin/end

Right now the library uses member-functions .begin() and .end() when serializing sequences: see e.g. here.

As a consequence some types cannot be serialized.

Erase key

Right now there is no way of erasing a key.

Numbers as keys

I know this isn't strictly json-compliant, but I would love to have numbers as keys.

Say I try:

std::map data<double, double> = {{1.0, 2.0}, {3.0, 4.0}};

I would like to be able to:

json j_data(data);

In order to get:

{1.0:2.0, 3.0:4.0}

I think the strength of json is that it can take a little bit of abuse.
Thanks.

find is error

json o;
o["foo"] = 23;
o["bar"] = false;
o["baz"] = 3.141;

// find an entry
if (o.find("foo") != o.end()) {
// there is an entry with key "foo"
}

in my example

key:"Heart_COL"
type:"HEX"
val:"DF01140234340000"

auto it = jsonData.find("type");
std::cout << *it << '\n';
the printf data is "Heart_COL"

Supported compilers

Hi.

There is no documentation on what compilers are supported, or which C++ features are required. I've tried to include the header in a project with MSVC 2013, and I get plenty of compile errors (with MinGW it compiles fine). I know MSVC might not have good enough C++11 support, so that's somewhat expected. I'm wondering, though, if anybody has attempted some newer pre-release of MSVC and if it is worth it at all trying to get it compile, sending patches, etc.

Thank you.

PD: In case it's useful, the first error I have is with the declaration of using iterator = basic_json::iterator:

c:\users\alex\documents\helloworld\json/src/json.hpp(142) : error C2061: syntax error : identifier 'iterator'
        c:\users\alex\documents\helloworld\json/src/json.hpp(4335) : see reference to class template instantiation 'nlohmann::basic_json<ObjectType,ArrayType,StringType,BooleanType,NumberIntegerType,NumberFloatType,Allocator>' being compiled
c:\users\alex\documents\helloworld\json/src/json.hpp(142) : error C2238: unexpected token(s) preceding ';'

Later on I get plenty of unrecognized noexcept. The later could be worked around with a macro, I think, but I have no idea on the former, or other template magic involved.

Double quotation mark is not parsed correctly

In JSON, double quotation mark in a JSON string is escaped as \", such as

["\"foo\""]

should be escaped as "foo". But this library did not handle it and parsed it as \"foo\".

I reproduced the bug with the following test case:

    SECTION("escape_dobulequote")
    {
        auto s = "[\"\\\"foo\\\"\"]";
        json j = json::parse(s);
        CHECK(j == json({"\"foo\""}));
    }

Results:

test/unit.cpp:6351: FAILED:
  CHECK( j == json({"\"foo\""}) )
with expansion:
  ["\\\"foo\\\""] == "\"foo\""

Removing item from array

Hi. Thanks for great lib!
Is there support for removing item/items from array?

E.g.:

        json j;
        j["name"] = { "testname", "yetanothername" };
        j["name"].erase("testname");
$ ./a.out 
terminate called after throwing an instance of 'std::runtime_error'
what():  cannot use at with array

Complete brief documentation

The following functions are not yet documented:

  • type
  • push_back
  • operator+=
  • swap
  • find
  • count
  • dump
  • parse
  • operator==, operator!=, operator<, operator<=, operator>, operator>=
  • std::swap
  • std::hash
  • operator<<, operator>>
  • operator"" _json

Wishlist

A common use case in web development is the need for flatten and unflatten functions, that is the ability to flatten a json object into a map of javascript assignment strings and vice versa.

{
"member1" : true,
"member2" : "Hello World",
"member3" : [1, {"member4" : 4, "member5" : 6.5}, 3]
}

into

prefix "whatever"

key = whatever.member1
value = true
key = whatever.member2
value = "Hello World"
key = whatever.member3[0]
value = 1
key = whatever.member1[1].member4
value = 4
key = whatever.member1[1].member5
value = 6.5
key = whatever.member3[2]
value = 3

function sighatures would be something like

map<string, json_primitive_that_insn't_object_or_array> flatten(json_object_or_array, symbol_name);
json_object_or_array unflatten(map<string, json_primitive_that_insn't_object_or_array>, symbol_name);

The type of the map would be string to a json primitive that isn't an object or an array.

The use case is that the keys in the map could be used as form field names. PHP and jQuery both are already doing this natively. Wouldn't it be nice if C++ had equal or better footing for web development.

Confused about iterating through json objects

If I have:

{
  "england": {
    "name": "euro",
    "value": 57.99
  },
  "mexico": {
    "name": "peso",
    "value": 31.99
  },
  "us": {
    "name": "USD",
    "value": 42.99
  }
}

And I want to iterate through each, how would I do so?

My attempt so far has been similar to the following:

std::ifstream input_file( const string file_path );
nlohmann::json currencies_json;
currencies_json << input_file;
input_file.close();

unordered_map <string, currency_class> currencies;
for ( const auto currency_json: currencies_json ) {
    currency_class new_currency;

    new_currency[ "country" ] = ???
    new_currency[ "name" ] = ???
    new_currency[ "value"] = ???

    currencies[ country ] = new_currency;
}

I've tried it a a few ways including - for example - creating a string for new_currency[ "country" ] first and then storing it in it like new_currency[ "country" ] = my_string, but I get errors such as:

no member named 'key' in 'nlohmann::basic_json<std::map, std::vector, std::__1::basic_string<char>, bool, long long, double, std::allocator>'

or

[....]:1073:20: error: 'm_it' is a private member of 'nlohmann::basic_json<std::map, std::vector, std::__1::basic_string<char>,
      bool, long long, double, std::allocator>::const_iterator'
           result.m_it.object_iterator = m_value.object->find(key);
                   ^
[...]:89:32: note: in instantiation of member function 'nlohmann::basic_json<std::map, std::vector, std::__1::basic_string<char>, bool, long long, double,
      std::allocator>::find' requested here
                const auto iterator = currencies.find("country");
                                             ^
[...]/build/dependencies/json-prefix/src/json/src/json.hpp:3007:96: note: declared private here
        internal_iterator<typename array_t::const_iterator, typename object_t::const_iterator> m_it;

Could you provide some guidance? I'd really appreciate it!

string parser does not recognize uncompliant strings

The Readme currently states:

Furthermore, we allow for more escape symbols in strings as the JSON specification. While this may not be a problem in reality, we are aware of it, but as long as we have a hand-written parser, we won't invest too much to be fully compliant.

And in fact, anything between two unescaped quotes will be treated as strings. However, the JSON standard is very explicit how a string may look like:

As long as the class does not implement this string specification, the class is not fully JSON compliant.

Serialize/Deserialize like PHP?

Hi,

Is there a way we could Serialize the output like PHP's Serialize version?

Currently it outputs in one line as a string. Would be helpful if it could support additional method such as this one.

Let me know!

Thanks.

P.S Kudos for the awesome work you've done. Very nice, clean and easier to use!

Why are elements alphabetized on key while iterating?

Let's say I have the json from the example readme:

  nlohmann::json all = {
  {"pi", 3.141},
  {"happy", true},
  {"name", "Niels"},
  {"nothing", nullptr},
  {"answer", {
    {"everything", 42}
  }},
  {"list", {1, 0, 2}},
  {"object", {
    {"currency", "USD"},
    {"value", 42.99}
  }}
};

I will iterate over it the following way:

  for (nlohmann::json::iterator it = all.begin(); it != all.end(); ++it) {
    std::cout << it.key() << std::endl;
  }

I would expect this:

pi
happy
name
nothing
answer
list
object

Instead, I get:

answer
happy
list
name
nothing
object
pi

Why is this the default? Can it be turned off?

Handle infinity and NaN cases

http://en.cppreference.com/w/cpp/io/c/fprintf

snprintf will format infinity and nan doubles as Inf/Infinity or nan/nan(char_sequence) respectively. This can break the validity of a json.dump() document:

json/src/json.hpp

Line 2279 in 1580eee

const auto sz = static_cast<unsigned int>(std::snprintf(nullptr, 0, "%.15g", m_value.number_float));

You can check for infinity/nan w/ std::isinfinite/std::isnan - not sure what you'd like to actually do in those scenarios (some specific/configurable string representation?)

http://en.cppreference.com/w/cpp/numeric/math/isfinite

Keys when iterating over objects

I'm trying to iterate over a json input file containing an unknown number of molecules (see below). For each of these the key is the name which I currently have found no way to extract. Is this possible?

Code:

#include <faunus/json.hpp>
#include <iostream>
#include <fstream>

/*
 * minimal.json:
 * {
 *   "moleculelist" : { 
 *     "salt" : { "atoms":"Na Cl", "atomic":true, "Ninit":1 },
 *     "water" : { "atoms":"H H O", "atomic":false, "Ninit":55 }
 *   }
 * }
 */

using json = nlohmann::json;

int main() {
  std::ifstream f("minimal.json");
  if (f) {
    json j;
    j << f;
    if ( ! j["moleculelist"].empty() )
      for ( auto &mol : j["moleculelist"] )
        if ( mol.is_object() ) {
          // how to get entry keys? (i.e. "salt", "water", etc.)
          for ( auto &i : mol )
            std::cout << i << "\n";
        }
  }
}

errors in g++-4.8.1

g++-4.8.1 generates the following two errors while g++-4.9.2 does not generate any error (OS: ubuntu-12.04).

g++-4.8 -std=c++11    -I src -I test test/unit.cpp  -o json_unit
In file included from test/unit.cpp:25:0:
src/json.hpp: In instantiation of ‘T nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType>::erase(T) [with T = nlohmann::basic_json<>::const_iterator; typename std::enable_if<(std::is_same<V, nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType>::iterator>::value || std::is_same<V, nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType>::const_iterator>::value), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberFloatType = double; AllocatorType = std::allocator]’:
test/unit.cpp:2655:80:   required from here
src/json.hpp:1286:44: error: no matching function for call to ‘std::vector<nlohmann::basic_json<> >::erase(__gnu_cxx::__normal_iterator<const nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<> > >&)’
                 result.m_it.array_iterator = m_value.array->erase(pos.m_it.array_iterator);
                                            ^
src/json.hpp:1286:44: note: candidates are:
In file included from /usr/include/c++/4.8/vector:69:0,
                 from /usr/include/c++/4.8/bits/random.h:34,
                 from /usr/include/c++/4.8/random:50,
                 from /usr/include/c++/4.8/bits/stl_algo.h:65,
                 from /usr/include/c++/4.8/algorithm:62,
                 from test/catch.hpp:62,
                 from test/unit.cpp:11:
/usr/include/c++/4.8/bits/vector.tcc:134:5: note: std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::erase(std::vector<_Tp, _Alloc>::iterator) [with _Tp = nlohmann::basic_json<>; _Alloc = std::allocator<nlohmann::basic_json<> >; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<> > >; typename std::_Vector_base<_Tp, _Alloc>::pointer = nlohmann::basic_json<>*]
     vector<_Tp, _Alloc>::
     ^
/usr/include/c++/4.8/bits/vector.tcc:134:5: note:   no known conversion for argument 1 from ‘__gnu_cxx::__normal_iterator<const nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<> > >’ to ‘std::vector<nlohmann::basic_json<> >::iterator {aka __gnu_cxx::__normal_iterator<nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<> > >}’
/usr/include/c++/4.8/bits/vector.tcc:146:5: note: std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::erase(std::vector<_Tp, _Alloc>::iterator, std::vector<_Tp, _Alloc>::iterator) [with _Tp = nlohmann::basic_json<>; _Alloc = std::allocator<nlohmann::basic_json<> >; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<> > >; typename std::_Vector_base<_Tp, _Alloc>::pointer = nlohmann::basic_json<>*]
     vector<_Tp, _Alloc>::
     ^
/usr/include/c++/4.8/bits/vector.tcc:146:5: note:   candidate expects 2 arguments, 1 provided
In file included from test/unit.cpp:25:0:
src/json.hpp: In instantiation of ‘T nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType>::erase(T, T) [with T = nlohmann::basic_json<>::const_iterator; typename std::enable_if<(std::is_same<V, nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType>::iterator>::value || std::is_same<V, nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType>::const_iterator>::value), int>::type <anonymous> = 0; ObjectType = std::map; ArrayType = std::vector; StringType = std::basic_string<char>; BooleanType = bool; NumberIntegerType = long int; NumberFloatType = double; AllocatorType = std::allocator]’:
test/unit.cpp:2671:95:   required from here
src/json.hpp:1348:44: error: no matching function for call to ‘std::vector<nlohmann::basic_json<> >::erase(__gnu_cxx::__normal_iterator<const nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<> > >&, __gnu_cxx::__normal_iterator<const nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<> > >&)’
                 result.m_it.array_iterator = m_value.array->erase(first.m_it.array_iterator,
                                            ^
src/json.hpp:1348:44: note: candidates are:
In file included from /usr/include/c++/4.8/vector:69:0,
                 from /usr/include/c++/4.8/bits/random.h:34,
                 from /usr/include/c++/4.8/random:50,
                 from /usr/include/c++/4.8/bits/stl_algo.h:65,
                 from /usr/include/c++/4.8/algorithm:62,
                 from test/catch.hpp:62,
                 from test/unit.cpp:11:
/usr/include/c++/4.8/bits/vector.tcc:134:5: note: std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::erase(std::vector<_Tp, _Alloc>::iterator) [with _Tp = nlohmann::basic_json<>; _Alloc = std::allocator<nlohmann::basic_json<> >; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<> > >; typename std::_Vector_base<_Tp, _Alloc>::pointer = nlohmann::basic_json<>*]
     vector<_Tp, _Alloc>::
     ^
/usr/include/c++/4.8/bits/vector.tcc:134:5: note:   candidate expects 1 argument, 2 provided
/usr/include/c++/4.8/bits/vector.tcc:146:5: note: std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::erase(std::vector<_Tp, _Alloc>::iterator, std::vector<_Tp, _Alloc>::iterator) [with _Tp = nlohmann::basic_json<>; _Alloc = std::allocator<nlohmann::basic_json<> >; std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<> > >; typename std::_Vector_base<_Tp, _Alloc>::pointer = nlohmann::basic_json<>*]
     vector<_Tp, _Alloc>::
     ^
/usr/include/c++/4.8/bits/vector.tcc:146:5: note:   no known conversion for argument 1 from ‘__gnu_cxx::__normal_iterator<const nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<> > >’ to ‘std::vector<nlohmann::basic_json<> >::iterator {aka __gnu_cxx::__normal_iterator<nlohmann::basic_json<>*, std::vector<nlohmann::basic_json<> > >}’
make: *** [json_unit] Error 1

Printing attribute names

What would be the best way to iterate over a json object and print the attribute names?
My goal would be to have something like this:

example json:

{
"example": {
    "a": "hello",
    "b": "world",
    "c": "text"
  }
}

example printing code:

auto j = nlohmann::json::parse(Read_Entire_File_Into_String("example.json"));
auto element = j["example"];
for (auto const& it: element) {
    std::cout << it.attribute_name() << std::endl;
}
// I made up 'Read_Entire_File_Into_String', but it does what you'd expect.
// the attribute_name() method doesn't exist, but I wish that it had.

example results:

a
b
c

Not everything has an attribute name, in which case, it could return an empty string, throw an exception, or return std::optional.

I thought this might be easy to implement, but it appears that all of the attribute names are stored in the parent object, which means that when we iterate over an object, each iterator points to an object that has no way of finding out its own attribute name.

for example, if I were to edit json.hpp and give the basic_json class this public member function:

    inline string_t attribute_name() const noexcept
    {
        std::string str;
        if (m_type == value_t::object){
            for (auto i = m_value.object->cbegin(); i != m_value.object->cend(); ++i){
                str += escape_string(i->first) + " ";
            }
        }

        return str;
    }

and run client code like this:

#include "json.hpp"
#include <iostream>

void Recursive_Print(nlohmann::json const& element, unsigned int depth);

int main(){
  auto element = nlohmann::json::parse(Read_Entire_File_Into_String("changelog.json"));

  if (element.is_null()){ std::cout << "null " << element.attribute_name() << std::endl;}
  if (element.is_boolean()){std::cout << "bool " << element.attribute_name() << std::endl;}
  if (element.is_number()){std::cout << "number " << element.attribute_name() << std::endl;}
  if (element.is_object()){std::cout << "object " << element.attribute_name() << std::endl;}
  if (element.is_array()){std::cout << "array " << element.attribute_name() << std::endl;}
  if (element.is_string()){std::cout << "string " << element.attribute_name() << std::endl;}
}
void Recursive_Print(nlohmann::json const& element, unsigned int depth){
  for (auto const& it: element) {
    Print_Character_N_Times('-',depth); 
    if (it.is_null()){ std::cout << "null " << it.attribute_name() << std::endl;}
    if (it.is_boolean()){std::cout << "bool " << it.attribute_name() << std::endl;}
    if (it.is_number()){std::cout << "number " << it.attribute_name() << std::endl;}
    if (it.is_object()){std::cout << "object " << it.attribute_name() << std::endl; Recursive_Print(it,++depth);}
    if (it.is_array()){std::cout << "array " << it.attribute_name() << std::endl; Recursive_Print(it,++depth);}
    if (it.is_string()){std::cout << "string " << it.attribute_name() << std::endl;}
  }
}
//PRETTY MESSY.  BUT YOU GET THE GIST

it would result in the following:

object example 
-object a b c 
--string 
--string 
--string

I think that illustrates my point about attribute names being stored in the parents.

Anyway, do you have any thoughts on how I could accomplish this?

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.