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> 12using nlohmann::json; 13 14#include <list> 15 16namespace 17{ 18TEST_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 30struct MyContainer 31{ 32 const char* data; 33}; 34 35const char* begin(const MyContainer& c) 36{ 37 return c.data; 38} 39 40const char* end(const MyContainer& c) 41{ 42 return c.data + strlen(c.data); // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 43} 44 45TEST_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 57TEST_CASE("Custom container member begin/end") 58{ 59 struct MyContainer2 60 { 61 const char* data; 62 63 const char* begin() const 64 { 65 return data; 66 } 67 68 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 82TEST_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 94 MyIterator& operator++() 95 { 96 ++ptr; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic) 97 return *this; 98 } 99 100 reference operator*() const 101 { 102 return *ptr; 103 } 104 105 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