1 /*
2 __ _____ _____ _____
3 __| | __| | | | JSON for Modern C++ (test suite)
4 | | |__ | | | | | | version 3.10.0
5 |_____|_____|_____|_|___| https://github.com/nlohmann/json
6
7 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
8 SPDX-License-Identifier: MIT
9 Copyright (c) 2013-2019 Niels Lohmann <http://nlohmann.me>.
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy
12 of this software and associated documentation files (the "Software"), to deal
13 in the Software without restriction, including without limitation the rights
14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 copies of the Software, and to permit persons to whom the Software is
16 furnished to do so, subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 SOFTWARE.
28 */
29
30 #include "doctest_compatibility.h"
31
32 #include <nlohmann/json.hpp>
33 using nlohmann::json;
34
35 #include <list>
36
37 namespace
38 {
39 TEST_CASE("Use arbitrary stdlib container")
40 {
41 std::string raw_data = "[1,2,3,4]";
42 std::list<char> data(raw_data.begin(), raw_data.end());
43
44 json as_json = json::parse(data.begin(), data.end());
45 CHECK(as_json.at(0) == 1);
46 CHECK(as_json.at(1) == 2);
47 CHECK(as_json.at(2) == 3);
48 CHECK(as_json.at(3) == 4);
49 }
50
51 struct MyContainer
52 {
53 const char* data;
54 };
55
begin(const MyContainer & c)56 const char* begin(const MyContainer& c)
57 {
58 return c.data;
59 }
60
end(const MyContainer & c)61 const char* end(const MyContainer& c)
62 {
63 return c.data + strlen(c.data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
64 }
65
66 TEST_CASE("Custom container non-member begin/end")
67 {
68
69 MyContainer data{"[1,2,3,4]"};
70 json as_json = json::parse(data);
71 CHECK(as_json.at(0) == 1);
72 CHECK(as_json.at(1) == 2);
73 CHECK(as_json.at(2) == 3);
74 CHECK(as_json.at(3) == 4);
75
76 }
77
78 TEST_CASE("Custom container member begin/end")
79 {
80 struct MyContainer2
81 {
82 const char* data;
83
begin__anon3e9915cb0111::MyContainer284 const char* begin() const
85 {
86 return data;
87 }
88
end__anon3e9915cb0111::MyContainer289 const char* end() const
90 {
91 return data + strlen(data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
92 }
93 };
94
95 MyContainer2 data{"[1,2,3,4]"};
96 json as_json = json::parse(data);
97 CHECK(as_json.at(0) == 1);
98 CHECK(as_json.at(1) == 2);
99 CHECK(as_json.at(2) == 3);
100 CHECK(as_json.at(3) == 4);
101 }
102
103 TEST_CASE("Custom iterator")
104 {
105 const char* raw_data = "[1,2,3,4]";
106
107 struct MyIterator
108 {
109 using difference_type = std::size_t;
110 using value_type = char;
111 using pointer = const char*;
112 using reference = const char&;
113 using iterator_category = std::input_iterator_tag;
114
operator ++__anon3e9915cb0111::MyIterator115 MyIterator& operator++()
116 {
117 ++ptr; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
118 return *this;
119 }
120
operator *__anon3e9915cb0111::MyIterator121 reference operator*() const
122 {
123 return *ptr;
124 }
125
operator !=__anon3e9915cb0111::MyIterator126 bool operator!=(const MyIterator& rhs) const
127 {
128 return ptr != rhs.ptr;
129 }
130
131 const char* ptr;
132 };
133
134 // avoid -Wunused-local-typedefs
135 CHECK(std::is_same<MyIterator::difference_type, std::size_t>::value);
136 CHECK(std::is_same<MyIterator::value_type, char>::value);
137 CHECK(std::is_same<MyIterator::pointer, const char*>::value);
138 CHECK(std::is_same<MyIterator::reference, const char&>::value);
139 CHECK(std::is_same<MyIterator::iterator_category, std::input_iterator_tag>::value);
140
141 MyIterator begin{raw_data};
142 MyIterator end{raw_data + strlen(raw_data)}; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
143
144 json as_json = json::parse(begin, end);
145 CHECK(as_json.at(0) == 1);
146 CHECK(as_json.at(1) == 2);
147 CHECK(as_json.at(2) == 3);
148 CHECK(as_json.at(3) == 4);
149 }
150
151 } // namespace
152