1 // __ _____ _____ _____
2 // __| | __| | | | JSON for Modern C++ (supporting code)
3 // | | |__ | | | | | | version 3.11.2
4 // |_____|_____|_____|_|___| https://github.com/nlohmann/json
5 //
6 // SPDX-FileCopyrightText: 2013-2022 Niels Lohmann <https://nlohmann.me>
7 // SPDX-License-Identifier: MIT
8
9 #include "doctest_compatibility.h"
10
11 #include <nlohmann/json.hpp>
12 using nlohmann::json;
13
14 #include <list>
15
16 namespace
17 {
18 TEST_CASE("Use arbitrary stdlib container")
19 {
20 std::string raw_data = "[1,2,3,4]";
21 std::list<char> data(raw_data.begin(), raw_data.end());
22
23 json as_json = json::parse(data.begin(), data.end());
24 CHECK(as_json.at(0) == 1);
25 CHECK(as_json.at(1) == 2);
26 CHECK(as_json.at(2) == 3);
27 CHECK(as_json.at(3) == 4);
28 }
29
30 struct MyContainer
31 {
32 const char* data;
33 };
34
begin(const MyContainer & c)35 const char* begin(const MyContainer& c)
36 {
37 return c.data;
38 }
39
end(const MyContainer & c)40 const char* end(const MyContainer& c)
41 {
42 return c.data + strlen(c.data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
43 }
44
45 TEST_CASE("Custom container non-member begin/end")
46 {
47
48 MyContainer data{"[1,2,3,4]"};
49 json as_json = json::parse(data);
50 CHECK(as_json.at(0) == 1);
51 CHECK(as_json.at(1) == 2);
52 CHECK(as_json.at(2) == 3);
53 CHECK(as_json.at(3) == 4);
54
55 }
56
57 TEST_CASE("Custom container member begin/end")
58 {
59 struct MyContainer2
60 {
61 const char* data;
62
begin__anon8459a38b0111::MyContainer263 const char* begin() const
64 {
65 return data;
66 }
67
end__anon8459a38b0111::MyContainer268 const char* end() const
69 {
70 return data + strlen(data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
71 }
72 };
73
74 MyContainer2 data{"[1,2,3,4]"};
75 json as_json = json::parse(data);
76 CHECK(as_json.at(0) == 1);
77 CHECK(as_json.at(1) == 2);
78 CHECK(as_json.at(2) == 3);
79 CHECK(as_json.at(3) == 4);
80 }
81
82 TEST_CASE("Custom iterator")
83 {
84 const char* raw_data = "[1,2,3,4]";
85
86 struct MyIterator
87 {
88 using difference_type = std::size_t;
89 using value_type = char;
90 using pointer = const char*;
91 using reference = const char&;
92 using iterator_category = std::input_iterator_tag;
93
operator ++__anon8459a38b0111::MyIterator94 MyIterator& operator++()
95 {
96 ++ptr; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
97 return *this;
98 }
99
operator *__anon8459a38b0111::MyIterator100 reference operator*() const
101 {
102 return *ptr;
103 }
104
operator !=__anon8459a38b0111::MyIterator105 bool operator!=(const MyIterator& rhs) const
106 {
107 return ptr != rhs.ptr;
108 }
109
110 const char* ptr;
111 };
112
113 // avoid -Wunused-local-typedefs
114 CHECK(std::is_same<MyIterator::difference_type, std::size_t>::value);
115 CHECK(std::is_same<MyIterator::value_type, char>::value);
116 CHECK(std::is_same<MyIterator::pointer, const char*>::value);
117 CHECK(std::is_same<MyIterator::reference, const char&>::value);
118 CHECK(std::is_same<MyIterator::iterator_category, std::input_iterator_tag>::value);
119
120 MyIterator begin{raw_data};
121 MyIterator end{raw_data + strlen(raw_data)}; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
122
123 json as_json = json::parse(begin, end);
124 CHECK(as_json.at(0) == 1);
125 CHECK(as_json.at(1) == 2);
126 CHECK(as_json.at(2) == 3);
127 CHECK(as_json.at(3) == 4);
128 }
129
130 } // namespace
131