Skip to content

Commit

Permalink
Documentation change (#3672)
Browse files Browse the repository at this point in the history
Co-authored-by: Florian Albrechtskirchinger <falbrechtskirchinger@gmail.com>
  • Loading branch information
nlohmann and falbrechtskirchinger authored Aug 5, 2022
1 parent 9e1a7c8 commit 7b6cf59
Show file tree
Hide file tree
Showing 65 changed files with 583 additions and 303 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,12 @@ jobs:

ci_test_documentation:
runs-on: ubuntu-latest
strategy:
matrix:
target: [ci_test_examples, ci_test_api_documentation]
steps:
- uses: actions/checkout@v3
- name: Run CMake
run: cmake -S . -B build -DJSON_CI=On
- name: Build
run: cmake --build build --target ci_test_documentation
run: cmake --build build --target ${{ matrix.target }}
8 changes: 7 additions & 1 deletion cmake/ci.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -953,12 +953,18 @@ add_custom_target(ci_icpc
# test documentation
###############################################################################

add_custom_target(ci_test_documentation
add_custom_target(ci_test_examples
COMMAND make CXX="${GCC_TOOL}" check_output_portable -j8
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/docs
COMMENT "Check that all examples compile and create the desired output"
)

add_custom_target(ci_test_api_documentation
COMMAND ${Python3_EXECUTABLE} scripts/check_structure.py
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/docs/mkdocs
COMMENT "Lint the API documentation"
)

###############################################################################
# Clean up all generated files.
###############################################################################
Expand Down
37 changes: 37 additions & 0 deletions docs/examples/from_json__default_constructible.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

namespace ns
{
// a simple struct to model a person
struct person
{
std::string name;
std::string address;
int age;
};
} // namespace ns

namespace ns
{
void from_json(const json& j, person& p)
{
j.at("name").get_to(p.name);
j.at("address").get_to(p.address);
j.at("age").get_to(p.age);
}
} // namespace ns

int main()
{
json j;
j["name"] = "Ned Flanders";
j["address"] = "744 Evergreen Terrace";
j["age"] = 60;

auto p = j.get<ns::person>();

std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl;
}
1 change: 1 addition & 0 deletions docs/examples/from_json__default_constructible.output
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Ned Flanders (60) lives in 744 Evergreen Terrace
53 changes: 53 additions & 0 deletions docs/examples/from_json__non_default_constructible.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

namespace ns
{
// a simple struct to model a person (not default constructible)
struct person
{
person(std::string n, std::string a, int aa)
: name(std::move(n)), address(std::move(a)), age(aa)
{}

std::string name;
std::string address;
int age;
};
} // namespace ns

namespace nlohmann
{
template <>
struct adl_serializer<ns::person>
{
static ns::person from_json(const json& j)
{
return {j.at("name"), j.at("address"), j.at("age")};
}

// Here's the catch! You must provide a to_json method! Otherwise, you
// will not be able to convert person to json, since you fully
// specialized adl_serializer on that type
static void to_json(json& j, ns::person p)
{
j["name"] = p.name;
j["address"] = p.address;
j["age"] = p.age;
}
};
} // namespace nlohmann

int main()
{
json j;
j["name"] = "Ned Flanders";
j["address"] = "744 Evergreen Terrace";
j["age"] = 60;

auto p = j.get<ns::person>();

std::cout << p.name << " (" << p.age << ") lives in " << p.address << std::endl;
}
1 change: 1 addition & 0 deletions docs/examples/from_json__non_default_constructible.output
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Ned Flanders (60) lives in 744 Evergreen Terrace
14 changes: 14 additions & 0 deletions docs/examples/nlohmann_json_namespace.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include <iostream>
#include <nlohmann/json.hpp>

// possible use case: use NLOHMANN_JSON_NAMESPACE instead of nlohmann
using json = NLOHMANN_JSON_NAMESPACE::json;

// macro needed to output the NLOHMANN_JSON_NAMESPACE as string literal
#define Q(x) #x
#define QUOTE(x) Q(x)

int main()
{
std::cout << QUOTE(NLOHMANN_JSON_NAMESPACE) << std::endl;
}
1 change: 1 addition & 0 deletions docs/examples/nlohmann_json_namespace.output
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nlohmann::json_v3_11_1
33 changes: 33 additions & 0 deletions docs/examples/nlohmann_json_namespace_begin.c++17.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <iostream>
#include <optional>
#include <nlohmann/json.hpp>

// partial specialization (see https://json.nlohmann.me/features/arbitrary_types/)
NLOHMANN_JSON_NAMESPACE_BEGIN
template <typename T>
struct adl_serializer<std::optional<T>>
{
static void to_json(json& j, const std::optional<T>& opt)
{
if (opt == std::nullopt)
{
j = nullptr;
}
else
{
j = *opt;
}
}
};
NLOHMANN_JSON_NAMESPACE_END

int main()
{
std::optional<int> o1 = 1;
std::optional<int> o2 = std::nullopt;

NLOHMANN_JSON_NAMESPACE::json j;
j.push_back(o1);
j.push_back(o2);
std::cout << j << std::endl;
}
1 change: 1 addition & 0 deletions docs/examples/nlohmann_json_namespace_begin.c++17.output
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[1,null]
32 changes: 32 additions & 0 deletions docs/examples/to_json.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <iostream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

namespace ns
{
// a simple struct to model a person
struct person
{
std::string name;
std::string address;
int age;
};
} // namespace ns

namespace ns
{
void to_json(json& j, const person& p)
{
j = json{ {"name", p.name}, {"address", p.address}, {"age", p.age} };
}
} // namespace ns

int main()
{
ns::person p = {"Ned Flanders", "744 Evergreen Terrace", 60};

json j = p;

std::cout << j << std::endl;
}
1 change: 1 addition & 0 deletions docs/examples/to_json.output
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"address":"744 Evergreen Terrace","age":60,"name":"Ned Flanders"}
40 changes: 36 additions & 4 deletions docs/mkdocs/docs/api/adl_serializer/from_json.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ noexcept(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_
-> decltype(::nlohmann::from_json(std::forward<BasicJsonType>(j), detail::identity_tag<TargetType> {}))
```
This function is usually called by the [`get()`](../basic_json/get.md) function of the
[basic_json](../basic_json) class (either explicit or via conversion operators).
This function is usually called by the [`get()`](../basic_json/get.md) function of the [basic_json](../basic_json)
class (either explicitly or via the conversion operators).
1. This function is chosen for default-constructible value types.
2. This function is chosen for value types which are not default-constructible.
Expand All @@ -32,9 +32,41 @@ This function is usually called by the [`get()`](../basic_json/get.md) function
Copy of the JSON value, converted to `ValueType`
!!! note
## Examples
This documentation page is a stub.
??? example "Example: (1) Default-constructible type"
The example below shows how a `from_json` function can be implemented for a user-defined type. This function is
called by the `adl_serializer` when `get<ns::person>()` is called.
```cpp
--8<-- "examples/from_json__default_constructible.cpp"
```
Output:
```json
--8<-- "examples/from_json__default_constructible.output"
```
??? example "Example: (2) Non-default-constructible type"
The example below shows how a `from_json` is implemented as part of a specialization of the `adl_serializer` to
realize the conversion of a non-default-constructible type.
```cpp
--8<-- "examples/from_json__non_default_constructible.cpp"
```
Output:
```json
--8<-- "examples/from_json__non_default_constructible.output"
```
## See also
- [to_json](to_json.md)
## Version history
Expand Down
23 changes: 20 additions & 3 deletions docs/mkdocs/docs/api/adl_serializer/to_json.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,26 @@ This function is usually called by the constructors of the [basic_json](../basic
`val` (in)
: value to read from
!!! note
This documentation page is a stub.
## Examples
??? example
The example below shows how a `to_json` function can be implemented for a user-defined type. This function is called
by the `adl_serializer` when the constructor `basic_json(ns::person)` is called.
```cpp
--8<-- "examples/to_json.cpp"
```
Output:
```json
--8<-- "examples/to_json.output"
```
## See also
- [from_json](from_json.md)
## Version history
Expand Down
4 changes: 2 additions & 2 deletions docs/mkdocs/docs/api/basic_json/boolean_t.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ using boolean_t = BooleanType;

The type used to store JSON booleans.

[RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two literals
`#!json true` and `#!json false`.
[RFC 8259](https://tools.ietf.org/html/rfc8259) implicitly describes a boolean as a type which differentiates the two
literals `#!json true` and `#!json false`.

To store objects in C++, a type is defined by the template parameter `BooleanType` which chooses the type to use.

Expand Down
17 changes: 17 additions & 0 deletions docs/mkdocs/docs/api/basic_json/json_serializer.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@ using json_serializer = JSONSerializer<T, SFINAE>;

The default values for `json_serializer` is [`adl_serializer`](../adl_serializer).

## Examples

??? example

The example below shows how a conversion of a non-default-constructible type is implemented via a specialization of
the `adl_serializer`.
```cpp
--8<-- "examples/from_json__non_default_constructible.cpp"
```

Output:

```json
--8<-- "examples/from_json__non_default_constructible.output"
```

## Version history

- Since version 2.0.0.
3 changes: 2 additions & 1 deletion docs/mkdocs/docs/api/basic_json/object_comparator_t.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,5 @@ and [`default_object_comparator_t`](default_object_comparator_t.md) otherwise.
## Version history

- Added in version 3.0.0.
- Changed to be conditionally defined as `#!cpp typename object_t::key_compare` or `default_object_comparator_t` in version 3.11.0.
- Changed to be conditionally defined as `#!cpp typename object_t::key_compare` or `default_object_comparator_t` in
version 3.11.0.
3 changes: 2 additions & 1 deletion docs/mkdocs/docs/api/basic_json/object_t.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ Objects are stored as pointers in a `basic_json` type. That is, for any access t
The order name/value pairs are added to the object is *not* preserved by the library. Therefore, iterating an object may
return name/value pairs in a different order than they were originally stored. In fact, keys will be traversed in
alphabetical order as `std::map` with `std::less` is used by default. Please note this behavior conforms to
[RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified "unordered" nature of JSON objects.
[RFC 8259](https://tools.ietf.org/html/rfc8259), because any order implements the specified "unordered" nature of JSON
objects.

## Examples

Expand Down
6 changes: 4 additions & 2 deletions docs/mkdocs/docs/api/basic_json/operator[].md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ const_reference operator[](const json_pointer& ptr) const;
```

1. Returns a reference to the array element at specified location `idx`.
2. Returns a reference to the object element with specified key `key`. The non-const qualified overload takes the key by value.
2. Returns a reference to the object element with specified key `key`. The non-const qualified overload takes the key by
value.
3. See 2. This overload is only available if `KeyType` is comparable with `#!cpp typename object_t::key_type` and
`#!cpp typename object_comparator_t::is_transparent` denotes a type.
4. Returns a reference to the element with specified JSON pointer `ptr`.
Expand Down Expand Up @@ -234,6 +235,7 @@ Strong exception safety: if an exception occurs, the original value stays intact
## Version history

1. Added in version 1.0.0.
2. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. Removed overloads for `T* key` (replaced by 3) in version 3.11.0.
2. Added in version 1.0.0. Added overloads for `T* key` in version 1.1.0. Removed overloads for `T* key` (replaced by 3)
in version 3.11.0.
3. Added in version 3.11.0.
4. Added in version 2.0.0.
4 changes: 2 additions & 2 deletions docs/mkdocs/docs/api/basic_json/operator_eq.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class basic_json {
```
1. Compares two JSON values for equality according to the following rules:
- Two JSON values are equal if (1) neither value is discarded, or (2) they are of the same
type and their stored values are the same according to their respective `operator==`.
- Two JSON values are equal if (1) neither value is discarded, or (2) they are of the same type and their stored
values are the same according to their respective `operator==`.
- Integer and floating-point numbers are automatically converted before comparison.
2. Compares a JSON value and a scalar or a scalar and a JSON value for equality by converting the
Expand Down
Loading

0 comments on commit 7b6cf59

Please sign in to comment.