Code Monkey home page Code Monkey logo

staticjson's Introduction

StaticJSON

Fast, direct and static typed parsing of JSON with C++.

Overview

JSON is a popular format for data exchange. Reading and writing JSON in C++, however, is nontrivial. Even with the help of libraries, one still needs to write lots of boilerplate code, and it is extremely hard to guard against all possible errors, since JSON is dynamically typed while C++ employs static typing.

More importantly, manually writing such code is a violation of DRY principle. When manually written, the class definition, parsing and serialization code can easily become out of sync, leading to brittle code and subtle bugs.

StaticJSON is an attempt to solve this problem by automating such process.

Usage

StaticJSON requires a C++11 compiler.

Method 1: use vcpkg

Run command vcpkg install staticjson, then in your CMakeLists.txt, add

 find_package(staticjson CONFIG REQUIRED)
 target_link_libraries(${YOUR_TARGET} PRIVATE staticjson::staticjson)

Method 2: just build everything together

Just drop the include and src directory into your own project and build along with other sources. It requires you to separately install rapidjson.

Quick start

Builtin types

#include <staticjson/staticjson.hpp>

int builtin_test() {
    using namespace staticjson;
    std::string a = to_json_string(std::vector<double>{1.0, 2.0, -3.1415});
    std::string b = to_pretty_json_string(std::map<std::string, std::shared_ptr<std::list<bool>>>{});

    std::vector<std::unordered_map<std::string, std::int64_t>> data;
    const char* json_string = "[{\" hello \": 535353, \" world \": 849},"
        " {\" k \": -548343}]";
    assert(from_json_string(json_string, &data, nullptr));
    assert(data.size() == 2);
    assert(data[1][" k "] == -548343);

    to_pretty_json_file(stdout, data);
    return 0;
}

Register custom class types

For your own classes, you need to add some definitions first before you can use the from_json and to_json functions. There are two ways of doing this.

Intrusive definition

This way requires you to implement a special method in the class prototyped void staticjson_init(staticjson::ObjectHandler* h). Example definition

struct Date
{
    int year, month, day;

    void staticjson_init(ObjectHandler* h)
    {
        h->add_property("year", &year);
        h->add_property("month", &month);
        h->add_property("day", &day);
        h->set_flags(Flags::DisallowUnknownKey);
    }
};

struct BlockEvent
{
    std::uint64_t serial_number, admin_ID = 255;
    Date date;
    std::string description, details;

    void staticjson_init(ObjectHandler* h)
    {
        h->add_property("serial_number", &serial_number);
        h->add_property("administrator ID", &admin_ID, Flags::Optional);
        h->add_property("date", &date, Flags::Optional);
        h->add_property("description", &description, Flags::Optional);
        h->add_property("details", &details, Flags::Optional);
    }
};

Non-intrusive definition

This requires you to overload a special function for your custom class. For example, the Date overload is written as

namespace staticjson
{
void init(Date* d, ObjectHandler* h)
{
    h->add_property("year", &d->year);
    h->add_property("month", &d->month);
    h->add_property("day", &d->day);
    h->set_flags(Flags::DisallowUnknownKey);
}
}

You may need to declare staticjson::init as a friend function in order to access private and protected members.

Register enumeration types

Example

enum class CalendarType
{
    Gregorian,
    Chinese,
    Jewish,
    Islam
};

STATICJSON_DECLARE_ENUM(CalendarType,
                        {"Gregorian", CalendarType::Gregorian},
                        {"Chinese", CalendarType::Chinese},
                        {"Jewish", CalendarType::Jewish},
                        {"Islam", CalendarType::Islam})

This will convert the enum type to/from strings, and signal error if the string is not in the list.

Note that this macro must not be instantiated inside a namespace.

Custom conversion

If you want a type to be serialized in a different way, such as a custom Date object as an ISO8601 string or an arbitrary precision integer as a list of 32-bit integers, you can enable the custom conversion for the type. To do so, specialize the template class in namespace staticjson

namespace staticjson
{
template <>
struct Converter<Date>
{
    typedef std::string shadow_type; 
    // This typedef is a must. The shadow type is a C++ type 
    // that can be directly converted to and from JSON values.

    static std::unique_ptr<ErrorBase> from_shadow(const shadow_type& shadow, Date& value)
    {
        bool success = value.parseISO8601(shadow);
        if (success)
            return nullptr;
        return std::make_unique<CustomError>("Invalid ISO 8601 string");
    }

    static void to_shadow(const Date& value, shadow_type& shadow)
    {
        shadow = value.toISO8601();
    }
};
}

Error handling

StaticJSON strives not to let any mismatch between the C++ type specifications and the JSON object slip. It detects and reports all kinds of errors, including type mismatch, integer out of range, floating number precision loss, required fields missing, duplicate keys etc. Many of them can be tuned on or off. It also reports an stack trace in case of error (not actual C++ exception).

The third parameter of all from_json family of functions is a nullable pointer to staticjson::ParseStatus object. If present, the error information will be dumped into it. An example error message is

Parsing failed at offset 1000 with error code 16:
Terminate parsing due to Handler error.

Traceback (last call first)
* Type mismatch between expected type "unsigned long long" and actual type "string"
* Error at object member with name "serial_number"
* Error at array element at index 0
* Error at object member with name "dark_history"
* Error at array element at index 1

List of builtin supported types

  • Boolean types: bool, char
  • Integer types: int, unsigned int, long, unsigned long, long long, unsigned long long
  • Floating point types: float, double
  • String types: std::string
  • Array types: std::vector<•>, std::deque<•>, std::list<•>, std::array<•>
  • Nullable types: std::nullptr_t, std::unique_ptr<•>, std::shared_ptr<•>
  • Map types: std::{map, multimap, unordered_map, unordered_multimap}<std::string, •>
  • Tuple types: std::tuple<...>

Dynamic typing

If you need occasional escape from the rigidity of C++'s static type system, but do not want complete dynamism, you can still find the middle ground in StaticJSON.

  • You can embed a staticjson::Document (alias of rapidjson::Document) in your class/struct, which allows static typing for some class members and dynamic typing for others. Note Document is already nullable so do not use a smart pointer to Document.
  • You can convert a Document or Value to and from a C++ type registered in StaticJSON. The functions are aptly named from_json_value, from_json_document, to_json_value, to_json_document.

Export as JSON Schema

Function export_json_schema allows you to export the validation rules used by StaticJSON as JSON schema. It can then be used in other languages to do the similar validation. Note the two rules are only approximate match, because certain rules cannot be expressed in JSON schema yet, and because some languages have different treatments of numbers from C++.

Misc

The project was originally named autojsoncxx and requires a code generator to run.

staticjson's People

Contributors

dvd0101 avatar jsfdez avatar lucretiel avatar netheril96 avatar savagecm avatar seker avatar shadowteolog avatar syoyo avatar tribal-tec avatar vitalyisaev2 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

staticjson's Issues

Polymorphism

Hi ,I noticed I get object sliced if I using a list shared_ptr to store base class pointer. Is there a way to support polymorphism properly?

Error while build

Hi

I am new to C++ programming. While building project I came across following error.

error: 'autojsoncxx' has not been declared

I know, its a wrong place to raise such questions. But any help or hint would be wonderful. I also includes project folders in "Project Includes" and I am using eclipse Luna.

Thanks and Regards

Conversion of custom string class to std string

Hi, I have an external library, which defines the custom string class. I prefer not to touch its source code. So I wondering if there is a way to call a custom conversion function to convert the std string to custom string class while deserializing.

RapidJson double inclusion

Hi,

In my project I have a confusing scenario.

There are two modules, module 1 and module 2, module 1 has a older version of RAPIDJSON and module 2 uses a new one,

module 2 has some header inclusions from module 1 which also includes rapidjson header files in return,
so eventually module 2 is having inclusion of both the version d of rapid json.

I though of using a different namespace and also noticed there is easy provision provided by rapid json to do so,

As an experiment I had put a new namespace in the rapidjson.h for module 2 and it works excepts the macros defined in the headers. One example is the RAPIDJSON_PARSE_ERROR macro. This macro had a different set of arguments in headers from module 1 whereas in module 2 headers, it has 3 arguments. Similarly there are few other macros. I guess macros don’t come under the namespace and hence we had to replace the conflicting macros (even with new namespace) by prefixing it with <module 2>_ in all the new RapidJSON headers.

I have checked with module 1 team and they are not in a position to update to new rapidjson.

I do understand that module 2 should not have included hearers from module 1, but currently we have no other solution for this.

Can someone suggest a good solution for this...?

shadow_type can't be JsonDocument.

In ConversionHandler::reset();

void reset() override
    {
        internal.prepare_for_reuse();
        shadow = shadow_type();
    }

If shadow_type is JsonDocument, then internal will be JSONHandler which reference the shadow.m_alloc. And if you call shadow = shadow_type();, it will destroy the m_alloc referenced by internal.

support for std::array

Please can you confirm if it is possible to add support for std::array. it should have same semantics to iterator the list. (e.g. std::vector, std::list etc)

question

Can I have a rapidjson::Document in Person(my own define class)

Person.hpp

Persion p;

p.tree is a std::shared_ptrrapidjson::Document or std::unique_ptrrapidjson::Document?
or p.tree is a std::shared_ptrrapidjson::Value

Thanks!

Multiply defined symbols when using optional_support

Take this pseudocode example.

a.h:

#pragma once
#include <optional>
#include <staticjson/staticjson.hpp>
struct a 
{
  int value;
  std::optional<float> f;
  void staticjson_init(staticjson::ObjectHandler *h);
};

a.cpp:

#include <staticjson/optional_support.hpp>
void a::staticjson_init(staticjson::ObjectHandler *h)
{
   h->add_property("value", &value);
   h->add_property("f", &f, Flags::Optional);
}

If you end up including optional_support.hpp in several files you will get a multiply defined symbol, but it would appear that it is required to include the header to get support for optional.

src/physicalcomponent.o:(.data.rel.ro.local+0x0): multiple definition of `staticjson::nonpublic::nullopt'
src/object.o:(.data.rel.ro.local+0x0): first defined here

A potential fix is to make nullopt static in the template. I will submit a matching pull request.

Duplicate key in map

Hi, I'm testing with a map , I did not set AllowDuplicatekey, but it did not return an error. e.g the json has 3 items, but it read 2 sucessfully.

struct Map
{
  std::map <string, string>  m;

	void	staticjson_init (staticjson::ObjectHandler* h)
	{
		h->add_property ("Map", &m);
		h->set_flags (staticjson::Flags::DisallowUnknownKey);
	}
}
{
 "Map": 
 {
 "one": { "x":"onedata"},
 "two" : { "x":"twodata"},
 "two" : { "x":"this is not taken"}
 }
}

access to tutorial and documentation site for the older autojsoncxx project

Hi,

these links to the autojsoncxx web page and tutorials no longer work, even after replacing the autojsoncxx part of the URL with StaticJSON

https://netheril96.github.io/autojsoncxx/
http://netheril96.github.io/autojsoncxx/tutorial/

this was a very good reference for users of the older autojsoncxx project. Can you reinstate those web pages (maybe marking them as deprecated). The examples given on the pages were helpful.

Alternatively, the pages could be checked into the autojsoncxx branch.

Christian

Please consider adding support for package managers

Thank you for this excellent library.

However, this:

Just drop the include and src directory into your own project

means a lot of folks, including myself, can't really use it. Being able to manage and easily update dependencies is important, especially for a non-header-only library.

So, purely as a feature request and with the intention of making using StaticJSON more accessible, please consider either adding a:

Thanks

swap free functions should be inline

There are two swap free functions in error.hpp that are not inline. These are causing the following linker errors in my project:

.../boost/include/boost/exception/detail/exception_ptr.hpp:120: error: multiple definition of `autojsoncxx::error::swap(autojsoncxx::error::ErrorStack&, autojsoncxx::error::ErrorStack&)'

.../boost/include/boost/exception/detail/exception_ptr.hpp:122: error: multiple definition of `autojsoncxx::error::swap(autojsoncxx::error::ParsingResult&, autojsoncxx::error::ParsingResult&)'

Making those two swap functions inline eliminates the linker errors.

Autojsoncxx does not handle duplicate fields

Autojsoncxx does not handle duplicate fields. Autojsoncxx only keeps the last occurence.
Can you throw an error when processing duplicate fields?
Thank you.

Here is a sample:


spec file:
[
{
"name": "TestInfo",
"namespace": "Test",
"members": [
["std::string", "param_1", {"required": true}],
["autojsoncxx::utility::int64_t", "param_2", {"default": 0}]
]
}
]


main.cpp:

include "test.hpp"

include "autojsoncxx/autojsoncxx.hpp"

include

int main(int /argc/, char _/_argv*/[])
{
const std::string rawRequest = "{"param_1": "value_1", "param_1": "value_2", "param_2": 123}";

autojsoncxx::ParsingResult parsingResult;

Test::TestInfo info;
autojsoncxx::from_json_string(rawRequest, info, parsingResult);

if(parsingResult.has_error())
{
    std::cout << "error" << std::endl;
    return -1;
}

std::cout << info.param_1 << std::endl; // error: param_1 field occurs twice ( "value_1" and "value_2")
return 0;

}

Bug deserializaing float

I found a bug with deserializing float, it needs a certain number of precision?

struct Test
{
    int  i;
    float f;
   void staticjson_init (ObjectHandler* h)
   {
      h->add_property ("intvar", &i);
      h->add_property ("floatvar", &f);
      h->set_flags (Flags::DisallowUnknownKey);
   }
}

Test test; 
// this works fine
from_json_string ("{ \"floatvar\":2.700000047683716,\"intvar\":1}", &test, nullptr);
// This will not work if float value is 2.7, int value deserialized is wrong
from_json_string ("{ \"floatvar\":2.7,\"intvar\":1}", &test, nullptr);

utf8-with-bom

json schema file do not support utf8-with-bom type

WString support?

Hi, when I try to use a wstring in add_property, I get a compile error

staticjson_init': is not a member of 'std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t>>

Got compile error on v1.0.0

Tried to build v1.0.0 with gcc8, got below build error:
In file included from /opt/rh/devtoolset-8/root/usr/include/c++/8/string:52,
from /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/locale_classes.h:40,
from /opt/rh/devtoolset-8/root/usr/include/c++/8/bits/ios_base.h:41,
from /opt/rh/devtoolset-8/root/usr/include/c++/8/ios:42,
from /opt/rh/devtoolset-8/root/usr/include/c++/8/ostream:38,
from /opt/rh/devtoolset-8/root/usr/include/c++/8/iterator:64,
from /root/json_decode/rapidjson/rapidjson-1.1.0/include/rapidjson/document.h:48,
from /root/json_decode/StaticJSON/StaticJSON-master/include/staticjson/basic.hpp:3,
from /root/json_decode/StaticJSON/StaticJSON-master/include/staticjson/document.hpp:2,
from /root/json_decode/StaticJSON/StaticJSON-master/src/staticjson.cpp:1:
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/basic_string.h: In instantiation of ‘class std::basic_string<char, std::char_traits, staticjson::mempool::PooledAllocator >’:
/root/json_decode/StaticJSON/StaticJSON-master/include/staticjson/basic.hpp:263:70: required from here
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/basic_string.h:3106:63: error: no class template named ‘rebind’ in ‘class staticjson::mempool::PooledAllocator’
typedef typename _Alloc::template rebind<_CharT>::other _CharT_alloc_type;
^~~~~~~~~~~~~~~~~
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/basic_string.h:3119:68: error: no class template named ‘rebind’ in ‘class staticjson::mempool::PooledAllocator’
typedef __gnu_cxx::__normal_iterator<pointer, basic_string> iterator;
^~~~~~~~
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/basic_string.h:3121:61: error: no class template named ‘rebind’ in ‘class staticjson::mempool::PooledAllocator’
const_iterator;
^~~~~~~~~~~~~~
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/basic_string.h:3122:53: error: no class template named ‘rebind’ in ‘class staticjson::mempool::PooledAllocator’
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
^~~~~~~~~~~~~~~~~~~~~~
/opt/rh/devtoolset-8/root/usr/include/c++/8/bits/basic_string.h:3123:52: error: no class template named ‘rebind’ in ‘class staticjson::mempool::PooledAllocator’
typedef std::reverse_iterator reverse_iterator;
^~~~~~~~~~~~~~~~
In file included from /root/json_decode/StaticJSON/StaticJSON-master/include/staticjson/document.hpp:2,
from /root/json_decode/StaticJSON/StaticJSON-master/src/staticjson.cpp:1:
/root/json_decode/StaticJSON/StaticJSON-master/include/staticjson/basic.hpp: In function ‘std::string staticjson::mempool::to_std_string(const String&)’:
/root/json_decode/StaticJSON/StaticJSON-master/include/staticjson/basic.hpp:263:83: error: ‘const String’ {aka ‘const class std::basic_string<char, std::char_traits, staticjson::mempool::PooledAllocator >’} has no member named ‘size’
inline std::string to_std_string(const String& str) { return {str.data(), str.size()}; }
^~~~
/root/json_decode/StaticJSON/StaticJSON-master/include/staticjson/basic.hpp:263:89: error: could not convert ‘{(& str)->std::basic_string<char, std::char_traits, staticjson::mempool::PooledAllocator >::data(), }’ from ‘’ to ‘std::string’ {aka ‘std::basic_string’}
inline std::string to_std_string(const String& str) { return {str.data(), str.size()}; }
^
/root/json_decode/StaticJSON/StaticJSON-master/src/staticjson.cpp: In member function ‘void staticjson::ObjectHandler::postinit()’:
/root/json_decode/StaticJSON/StaticJSON-master/src/staticjson.cpp:320:72: error: ‘const class std::basic_string<char, std::char_traits, staticjson::mempool::PooledAllocator >’ has no member named ‘size’
max_string_size = std::max<size_t>(max_string_size, pair.first.size());
^~~~
/root/json_decode/StaticJSON/StaticJSON-master/src/staticjson.cpp:324:22: error: ‘using String = class std::basic_string<char, std::char_traits, staticjson::mempool::PooledAllocator >’ {aka ‘class std::basic_string<char, std::char_traits, staticjson::mempool::PooledAllocator >’} has no member named ‘reserve’; did you mean ‘reference’?

.gitignore

maybe u can add

rapidjson.tgz
rapidjson*/

to the .gitignore file

ArrayHandler only supports PATCH, not PUT

Imagine you have an object with a std::vector of values. You receive a JSON array with new values. Now using the standard ArrayHandler for std::vector, it will emplace_back all new values to the existing one. This is correct if the JSON payload was part of an HTTP PATCH.

Now I would like support of PUT, where it clears the vector first before adding all new values. Is there already support in the library? I haven't seen any so far, so I'm dropping this question here. Maybe it's just me, but I find it the current behavior counter-intuitive.

Using your library and wondering how do I do this?

Here is a sample code of what I am trying to do:

#include "stdafx.h"
#include <windows.h>
#include

#include "staticjson/document.hpp"
#include "staticjson/staticjson.hpp"
#include "staticjson/io.hpp"

#include "rapidjson/schema.h"

class Base {
private:
int i;
float f;
public:
Base(int i, float f) {
this->i = i;
this->f = f;
}

virtual int staticjson_init(staticjson::ObjectHandler* h) {
	h->add_property("i", &i);
	h->add_property("f", &f);
	return sizeof(*this);
}

};

class Derived : public Base {
private:
double d;
long l;
public:
Derived(double d, long l) : Base(0, 0.0f) {
this->d = d;
this->l = l;
}

virtual int staticjson_init(staticjson::ObjectHandler* h) {
	Base::staticjson_init(h);
	h->add_property("d", &d);
	h->add_property("l", &l);
	return sizeof(*this);
}

};

class Container {
private:
int i;
std::string s;
Base* base;
public:
Container(int i, std::string& s) {
this->i = i;
this->s = s;
}

void setBase(Base* b) {
	this->base = b;
}

virtual void staticjson_init(staticjson::ObjectHandler* h) {
	h->add_property("i", &i);
	h->add_property("s", &s);
	h->Key("Object", strlen("Object"), true);
	h->StartObject();
	h->EndObject(base->staticjson_init(h));
}

};

int main()
{
Container c(55, std::string("a string"));
Derived d(66.35, 1234567890L);
Base b(33, 25.55f);

c.setBase(&d);
std::string s = staticjson::to_json_string(c);
fprintf(stdout, "c serialized value = %s\n", s.c_str());
c.setBase(&b);
s = staticjson::to_json_string(c);
fprintf(stdout, "c serialized value = %s\n", s.c_str());
return 0;

}

This code works and I get the following result:
c serialized value = {"d":66.35,"f":0.0,"i":55,"l":1234567890,"s":"a string"}
c serialized value = {"f":25.549999237060548,"i":55,"s":"a string"}

What I would like to do is get this result:
c serialized value = {"base": {"d":66.35,"l":1234567890}, "f":0.0,"i":55,"s":"a string"}
c serialized value = {"base":{"i":33, "f":"25.55"}, "f":25.549999237060548,"i":55,"s":"a string"}

Minimal example for nested optional JSON fields

I am curious, if (de)serializing from and to minimal nested optional JSON fields <-> struct describing the JSON with boolean fields to existence of the optional fields is a supported use case.

If yes, can you give me some pointers on the big picture of how the code would look?
Ideally with a minimal usable example, if it is not too much effort.

Thanks for your effort.

UPDATE: Code for the use case
Assume a JSON schema

{
  "required_field":"data1","optional_field":{"req_field_of_optional":"data2","nested_opt_field":"data3"}
}

which fills

struct json_repr {
  typeof(data1) required_field;
  bool optional_field_isUsed;
  typeof(data2) req_field_of_optional;
  bool nested_opt_field_isUsed;
  typeof(data3) nested_opt_field;
};

Another conforming JSON schema would be

{
  "required_field":"data1"
}

and another one

{
  "required_field":"data1","optional_field":{"req_field_of_optional":"data2"}
}

Better error descrption

Hi, I was looking to get a better description of parsing error because it's hard to diagonse a big json file with offsets. The descrption prints "Invalid escape character in string" but it does not tell you which item, only offsets. Is there a way to get more info? I see the ParseStatue m_stack is empty.

Feature

why not add a way to support {"a": 1, "b":"c"}(one map multitype)

with std::tuple we can generate ["1", 2, 1.0, {...}]

but how to implement {"a": 1, "b":"c"}

Feature suggestions

Just some feature requests for your consideration:

  1. would there be any interest in supporting the generation and parsing of enum types? The names of the enum could be mapped to std::string. A string not matching the enum type would cause a parsing error.

  2. would it be feasible for StaticJSON to generate a JSON schema that defines what a valid JSON file has to look like?

can you please mention dependency on rapidjson

Hi, Can you please mention dependency on rapidjson in the documentation. I was on latest version of rapidjson installed separately via vcpkg(windows) or normal(linux), however it caused loads of link error and took me a while to figure it out.

After I removed rapidjson folder from staticjson, everything worked correctly. Hopefully this will help some one. If possible, please simply remove rapidjson folder and ask users to install separately.

Thanks a lot for the library.

Add support for RapidJSON DOM members

I would find it useful to be able to deserialize the "static" part of a JSON object into a C++ struct, but still have access to members of complex, dynamic types. For example, for this JSON definition:

{
    "name": "Record",
    "members":
    [
        ["std::string", "id", {"required": true}],
        ["unsigned long", "revision"],
        ["rapidjson::Document", "document"]
    ]
}

the resulting C++ struct would look like this:

struct Record
{
    std::string key;
    unsigned long revision;
    rapidjson::Document document;
};

The document member above would allow me to treat the "document" sub-object as a dynamic JSON value.

Hints on implementing support for `std::optional<T>`

Hello,
I am looking to implement support for C++17's STL-type std::optional<T> in your library in order to better use it in one of my projects. Can you provide a rough outline of what needs to be done in order to support it? The currently available implementations for other STL types like deque are sadly not commented that well, which makes understanding the internals of your library a bit difficult.

Regards

Support comments

Hi, I know it is not in RFC, but libraries likw json.net or even rapidjson support comments, can u add that in please?

Using in Visual C++ Project

Apologies for the newb question, but I'm trying to utilise this in a VS 2017 project and I'm not quite sure how to do this.

As a relative beginner to C++, I've just been using vcpkg to add libraries (like RapidJSON) as needed which seems to work very well, but I can't do that in this case so I'm a bit stuck.

Is there any chance you could provide some tips for doing this? Perhaps even an ultra-simple Visual Studio example project?

Many thanks in advance.

support for enumset

Thanks for the lib, saved me a lot of time.

As usual I did 80% of work very fast and them stack a bit with enum sets. I have a few, looks like so:

enum class MySet : uint8_t { F1 = 1, F2 = 2, F4=4 };
inline MySet operator|(MySet lhs, MySet rhs) { return MySet(uint8_t(lhs) | uint8_t(rhs)); }
....

It would be nice to serialize it as an array of set bit names:

["F1", "F4"]

So I was looking in EnumHandler and ArrayHandler to figure out how to merge them in order to archive that kind of serialization, but I've failed at the end - templates are not at my fingertips.

Do you have any kind of documentation about serializer internals? Or an advice on how that kind of trick could be done :)

compile things

before problem: Thank you for do great thing!

First:

(why do this?)
I must use:

#define AUTOJSONCXX_HAS_MODERN_TYPES 1

to support std::unique_ptrrapidjson::Document

Second:

in error.hpp line 26
RAPIDJSON_NAMESPACE_BEGIN macro is defined by rapidjson why you define this?

Third:

in vs2013 update 5:
in utility.hpp line 198

inline bool string_equal(const char* str1, std::size_t len1, const char* str2, std::size_t len2)
    {
        return len1 == len2 && std::equal(str1, str1 + len1, str2);
    }

this warning is not good to see:

C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xutility(2798): warning C4996: 'std::_Equal1': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
1> C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\xutility(2783) : 参见“std::_Equal1”的声明
1> H:\test\test\include\autojsoncxx/utility.hpp(198): 参见对正在编译的函数 模板 实例化“bool std::equal<const char*,const char*>(_InIt1,_InIt1,_InIt2)”的引用
1> with
1> [
1> _InIt1=const char *
1> , _InIt2=const char *
1> ]

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.