Skip to content

Commit c45adda

Browse files
committed
Arrays
Signed-off-by: TymianekPL <tymi@tymi.org>
1 parent 55e2fd6 commit c45adda

File tree

3 files changed

+92
-7
lines changed

3 files changed

+92
-7
lines changed

Test/Test.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ int main()
88
object["test1"] = "Hello World";
99
object["test2"] = 123.0;
1010
object["sub"]["veryNested"] = 6.0;
11+
cppjson::Array& array = object["array"];
12+
array[] = 2;
13+
array[] = 6.0;
14+
array[0] = 1;
15+
array[] = "Stirng";
16+
try
17+
{
18+
array[2] = true;
19+
}
20+
catch (const std::logic_error& error)
21+
{
22+
std::println("Error = {}", error.what());
23+
}
1124

1225
std::println("{}", object);
1326
std::println("object[\"test1\"] = {}", object["test1"]);

cppjson/include/cppjson/object.hpp

Lines changed: 77 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <unordered_map>
99
#include <functional>
1010
#include <concepts>
11+
#include <vector>
1112

1213
namespace cppjson
1314
{
@@ -18,17 +19,17 @@ namespace cppjson
1819
Object,
1920
Number,
2021
Bool,
21-
// TODO: Array
22+
Array
2223
};
2324

2425
class JsonObject
2526
{
2627
public:
2728
explicit JsonObject();
2829
JsonObject(const JsonObject& other);
29-
JsonObject(JsonObject&& other);
30+
JsonObject(JsonObject&& other) noexcept;
3031
JsonObject& operator=(const JsonObject& other);
31-
JsonObject& operator=(JsonObject&& other);
32+
JsonObject& operator=(JsonObject&& other) noexcept;
3233
~JsonObject();
3334

3435
template <typename T>
@@ -86,9 +87,10 @@ namespace cppjson
8687
}
8788

8889
template <typename T>
89-
T& operator=(T&& assignment)
90+
std::conditional_t<std::integral<T> && !std::same_as<T, bool>, void, T&> operator=(T&& assignment)
9091
{
91-
return static_cast<T&>(*this) = std::forward<T>(assignment);
92+
if constexpr (std::integral<T> && !std::same_as<T, bool>) static_cast<double&>(*this) = static_cast<double>(assignment);
93+
else return static_cast<T&>(*this) = std::forward<T>(assignment);
9294
}
9395

9496
template <std::size_t N>
@@ -142,6 +144,35 @@ namespace cppjson
142144
friend struct std::formatter<cppjson::JsonObject>;
143145
friend struct std::formatter<cppjson::Object>;
144146
};
147+
148+
class Array
149+
{
150+
public:
151+
explicit Array() = default;
152+
~Array() = default;
153+
154+
Object::ObjectProxy operator[]()
155+
{
156+
return Object::ObjectProxy{ this->_objects.emplace_back() };
157+
}
158+
159+
Object::ObjectProxy operator[](const int index)
160+
{
161+
if (index >= this->_objects.size()) throw std::logic_error("Out of bound");
162+
return Object::ObjectProxy{ this->_objects.at(index) };
163+
}
164+
165+
Object::ConstObjectProxy operator[](const int index) const
166+
{
167+
if (index >= this->_objects.size()) throw std::logic_error("Out of bound");
168+
return Object::ConstObjectProxy{ this->_objects.at(index) };
169+
}
170+
private:
171+
std::vector<JsonObject> _objects{};
172+
173+
friend struct std::formatter<cppjson::JsonObject>;
174+
friend struct std::formatter<cppjson::Array>;
175+
};
145176
} // namespace cppjson
146177

147178

@@ -176,6 +207,24 @@ struct std::formatter<cppjson::JsonObject>
176207

177208
return std::format_to(context.out(), "{}", built);
178209
}
210+
case cppjson::JsonType::Array:
211+
{
212+
const auto& array = object.DangerousAs<cppjson::Array>();
213+
214+
std::string built = "[ ";
215+
for (const auto& element : array._objects)
216+
built += std::format("{}, ", element);
217+
218+
if (!array._objects.empty()) // remove trailing commas
219+
{
220+
built.pop_back();
221+
built.pop_back();
222+
built += " ]";
223+
}
224+
else built += "]";
225+
226+
return std::format_to(context.out(), "{}", built);
227+
}
179228
}
180229

181230
throw std::logic_error("Unknown type");
@@ -205,6 +254,29 @@ struct std::formatter<cppjson::Object>
205254
}
206255
};
207256

257+
template <>
258+
struct std::formatter<cppjson::Array>
259+
{
260+
constexpr auto parse(std::format_parse_context& context) { return context.begin(); }
261+
262+
auto format(const cppjson::Array& array, std::format_context& context) const
263+
{
264+
std::string built = "[ ";
265+
for (const auto& element : array._objects)
266+
built += std::format("{}, ", element);
267+
268+
if (!array._objects.empty()) // remove trailing commas
269+
{
270+
built.pop_back();
271+
built.pop_back();
272+
built += " ]";
273+
}
274+
else built += "]";
275+
276+
return std::format_to(context.out(), "{}", built);
277+
}
278+
};
279+
208280

209281
template <>
210282
struct std::formatter<cppjson::Object::ObjectProxy>

cppjson/src/object.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ cppjson::JsonObject::JsonObject(const cppjson::JsonObject& other)
1616
this->_dataStorage = static_cast<std::byte*>(::operator new(DataStorageSize));
1717
std::memcpy(this->_dataStorage, other._dataStorage, DataStorageSize);
1818
}
19-
cppjson::JsonObject::JsonObject(JsonObject&& other)
19+
cppjson::JsonObject::JsonObject(JsonObject&& other) noexcept
2020
{
2121
this->_dataType = std::exchange(other._dataType, cppjson::JsonType::Null);
2222
this->_dataStorage = std::exchange(other._dataStorage, static_cast<std::byte*>(::operator new(DataStorageSize)));
@@ -31,7 +31,7 @@ cppjson::JsonObject& cppjson::JsonObject::operator=(const cppjson::JsonObject& o
3131
}
3232
return *this;
3333
}
34-
cppjson::JsonObject& cppjson::JsonObject::operator=(cppjson::JsonObject&& other)
34+
cppjson::JsonObject& cppjson::JsonObject::operator=(cppjson::JsonObject&& other) noexcept
3535
{
3636
if (&other != this)
3737
{

0 commit comments

Comments
 (0)