Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
be49adf
Extract tuple value reading and writing to a function.
Dec 13, 2021
b75dfce
Corrected nulls not being parsed as such.
Jan 27, 2022
82c04e1
Added support for optionals.
Dec 13, 2021
22764cb
Some formatting changes.
Aug 8, 2024
9789cfe
__has_include doesn't work on all our platforms.
Aug 8, 2024
388d67d
Converted tests to GTest framework.
Aug 8, 2024
5a8599d
Add support for full string identifiers in objects
Apr 20, 2023
08fab02
Corrections for inclusion in some cases.
May 26, 2023
7146490
Added writing a vector of bool.
Feb 27, 2024
84ed339
Corrected subclass deserialization.
Jul 30, 2024
c76ec5f
Rearange funcs for compiler discovery.
Jul 30, 2024
e487e43
Format documents according to our style.
Jul 29, 2024
9bedced
clang-tidy according to our style.
Jul 29, 2024
56956a8
Monolithic builder.
Jul 31, 2024
1c846bb
Split out UTF8 Handling.
Jul 31, 2024
4cf7378
Virtualize Builder.
Jul 31, 2024
40a508f
Added IndependentValue.
Jul 30, 2024
213d933
Changed ToDocument to Writer.
Aug 1, 2024
87e128d
Allow reading of a lone json string
Aug 1, 2024
cf3977b
Reflection-base builder.
Jul 31, 2024
9193eff
Added document parser.
Aug 1, 2024
ab5176b
Removed now unused Read functions.
Aug 2, 2024
c34c6ac
Precompute reflection names
Aug 2, 2024
cef9ec6
Simplify handling of optionals.
Aug 2, 2024
5a7050d
Allow Document to be ivar in reflection.
Aug 5, 2024
5759779
Changed Write to templated struct func.
Aug 5, 2024
fec6929
Support NaN
Aug 8, 2024
0ab107f
Added example as unit test.
Aug 12, 2024
b646988
Added tuple serialization.
Aug 12, 2024
31f8e11
Silence clangd diagnostics about unused.
Aug 16, 2024
a437de6
Properly escape null characters in string
Aug 14, 2024
df1e1fb
Actually initialize Value to null in ctor.
Aug 20, 2024
b5e01ed
Restore flags in OutputStream post-change.
Aug 20, 2024
c64af72
Added explicit namespaces.
Aug 22, 2024
98ee782
Added includes in tests
Aug 22, 2024
0d5cd04
Removed duplicate test and multimap
Aug 22, 2024
bc4104e
Made `JSONCompatWriteParams` global for tests.
Aug 22, 2024
d7780d0
Added optional main to run tests standalone.
Aug 22, 2024
be578e4
Account for unicode character length.
Aug 28, 2024
db83cdd
In-place optional without intermediate obj.
Aug 29, 2024
ead8b79
Added multimap.
Aug 29, 2024
8aed574
Added substitution of ivar names in json.
Sep 6, 2024
7ca02a3
No temporary in constexpr for old compiler.
Sep 9, 2024
0080e70
Added missing header includes.
Sep 17, 2024
300cc00
Use decay_t in tuple write
Jan 24, 2025
198c837
Added reflectors for monostate
Jan 24, 2025
1edfb4b
Added test for if reflector allows type
Jan 24, 2025
5efd2f3
Added variant reflectors
Jan 24, 2025
1f25bab
IndependentValue -> use variant reflectors.
Jan 24, 2025
96e9d96
Added explanation for typical compile error
Feb 13, 2025
da34044
Add support for shared_ptr objects.
drzoidberg33 Feb 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 67 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,46 +8,53 @@

struct Settings
{
int x = 0;
int y = 0;
int width = 0;
int height = 0;
bool fullscreen = false;
std::string renderer = "";

JSON5_MEMBERS(x, y, width, height, fullscreen, renderer)
int x = 0;
int y = 0;
int width = 0;
int height = 0;
bool fullscreen = false;
std::string renderer = "";

JSON5_MEMBERS(x, y, width, height, fullscreen, renderer)
};

Settings s;

// Fill 's' instance from file
json5::from_file("settings.json", s);
json5::FromFile("settings.json", s);

// Save 's' to file
json5::to_file("settings.json", s);
json5::ToFile("settings.json", s);
```

## `json5.hpp`
TBD
Provides the basic types of `json5::Document`, `json5::Value`, and `json5::IndependentValue`. A `Value` represents a value within JSON but it relies on a `Document` for storage of non-primitive (string, array, object) data. A `Value` may be more difficult to manipulate which is why the `IndependentValue` is provided. An `IndependentValue` is self-contained and indepenedent of any other object. It contains a variant which respresents all possible JSON value types. Parsing is faster with a `Document` than with an `IndependentValue` due to its compact nature and small number of memory allocations.

## `json5_input.hpp`
Provides functions to load `json5::document` from string, stream or file.
Provides functions to load `json5::Document` or `json5::IndependentValue` from string, stream or file.

## `json5_output.hpp`
Provides functions to convert `json5::document` into string, stream or file.
Provides functions to convert `json5::Document` or `json5::IndependentValue` into string, stream or file.

## `json5_builder.hpp`
Defines `Builder`s for building `Document`s and `IndependentValue`s. Also provides the basis for building arbitrary objects via reflection.

## `json5_reflect.hpp`
Provides functionality to read/write structs/classes from/to a string, stream, or file

### Basic supported types:
- `bool`
- `int`, `float`, `double`
- `int`, `float`, `double`, and other numeric types
- `std::string`
- `std::vector`, `std::map`, `std::unordered_map`, `std::array`
- `std::vector`, `std::array`, `std::map`, `std::unordered_map`, `std::array`
- `C array`

### Reading from JSON
Reading is accomplished via the templated class `json5::detail::Reflector`. A custom deserializer can be made via a template specialiaztion (or partial specialization) for the class type. Often one would want to inherit `json5::detail::RefReflector` which holds a reference to the target object. Then override the relevant functions in `json5::detail::BaseReflector`. This is works because `Parser` will parse the JSON, calling functions on `ReflectionBuilder` which uses a stack of `BaseReflector` objects as it parses depth first into an object.
Writing is accomplished via the templated struct `json5::detail::ReflectionWriter`. A custom serialization should create a template specialization (or partial specialiaztion) for this struct and implement `static inline void Write(Writer& w, const T& in)` with the proper value for `T` (in need not be a const ref but could instead take by value like is done when serializing numbers but non-primitives likely should be const ref). This was changed from a templated function becuase partial specializations are not possible with functions but are possible with structs.

## `json5_base.hpp`
Contains `Error` definitions, `ValueType` enum, and macro definitions.

## `json5_filter.hpp`

Expand All @@ -59,47 +66,68 @@ TBD
### Serialize custom type:
```cpp
// Let's have a 3D vector struct:
struct vec3 { float x, y, z; };
struct Vec3
{
float x, y, z;
};

// Let's have a triangle struct with 'vec3' members
struct Triangle
{
vec3 a, b, c;
vec3 a, b, c;
};

JSON5_CLASS(Triangle, a, b, c)

namespace json5::detail {

// Write vec3 as JSON array of 3 numbers
inline json5::value write( writer &w, const vec3 &in )
{
w.push_array();
w += write( w, in.x );
w += write( w, in.y );
w += write( w, in.z );
return w.pop();
}

// Read vec3 from JSON array
inline error read( const json5::value &in, vec3 &out )
{
return read( json5::array_view( in ), out.x, out.y, out.z );
}

// Write Vec3 to JSON array
template <>
class ReflectionWriter<Vec3> : public TupleReflectionWriter<float, float, float>
{
public:
static inline void Write(Writer& w, const Vec3& in) { TupleReflectionWriter::Write(w, in.x, in.y, in.z); }
};

// Read Vec3 from JSON array
template <>
class Reflector<Vec3> : public TupleReflector<float, float, float>
{
public:
explicit Reflector(Vec3& vec)
: TupleReflector(vec.x, vec.y, vec.z)
{}
};

// Write Triangle as JSON array of 3 numbers
template <>
class ReflectionWriter<Triangle> : public TupleReflectionWriter<Vec3, Vec3, Vec3>
{
public:
static inline void Write(Writer& w, const Triangle& in) { TupleReflectionWriter::Write(w, in.a, in.b, in.c); }
};

// Read Triangle from JSON array
template <>
class Reflector<Triangle> : public TupleReflector<Vec3, Vec3, Vec3>
{
public:
explicit Reflector(Triangle& tri)
: TupleReflector(tri.a, tri.b, tri.c)
{}
};
} // namespace json5::detail
```

### Serialize enum:
```cpp
enum class MyEnum
{
Zero,
First,
Second,
Third
Zero,
First,
Second,
Third
};

// (must be placed in global namespce, requires C++20)
JSON5_ENUM( MyEnum, Zero, First, Second, Third )
JSON5_ENUM(MyEnum, Zero, First, Second, Third)
```
Loading