Commit a1448007 authored by Niels's avatar Niels

+ implemented member and non-member swap

parent 7724d347
...@@ -34,7 +34,6 @@ due to alignment. ...@@ -34,7 +34,6 @@ due to alignment.
@bug Numbers are currently handled too generously. There are several formats @bug Numbers are currently handled too generously. There are several formats
that are forbidden by the standard, but are accepted by the parser. that are forbidden by the standard, but are accepted by the parser.
@todo Implement json::swap()
@todo Implement json::insert(), json::emplace(), json::emplace_back, json::erase @todo Implement json::insert(), json::emplace(), json::emplace_back, json::erase
@todo Implement json::reverse_iterator, json::const_reverse_iterator, @todo Implement json::reverse_iterator, json::const_reverse_iterator,
json::rbegin(), json::rend(), json::crbegin(), json::crend()? json::rbegin(), json::rend(), json::crbegin(), json::crend()?
...@@ -178,6 +177,7 @@ class json ...@@ -178,6 +177,7 @@ class json
operator std::string() const; operator std::string() const;
/// implicit conversion to integer (only for numbers) /// implicit conversion to integer (only for numbers)
operator int() const; operator int() const;
operator long() const;
/// implicit conversion to double (only for numbers) /// implicit conversion to double (only for numbers)
operator double() const; operator double() const;
/// implicit conversion to Boolean (only for Booleans) /// implicit conversion to Boolean (only for Booleans)
...@@ -289,6 +289,9 @@ class json ...@@ -289,6 +289,9 @@ class json
/// removes all elements from compounds and resets values to default /// removes all elements from compounds and resets values to default
void clear() noexcept; void clear() noexcept;
/// swaps content with other object
void swap(json&) noexcept;
/// return the type of the object /// return the type of the object
value_type type() const noexcept; value_type type() const noexcept;
...@@ -418,7 +421,7 @@ class json ...@@ -418,7 +421,7 @@ class json
/// read the next character, stripping whitespace /// read the next character, stripping whitespace
bool next(); bool next();
/// raise an exception with an error message /// raise an exception with an error message
inline void error(const std::string&) const __attribute__((noreturn)); [[noreturn]] inline void error(const std::string&) const;
/// parse a quoted string /// parse a quoted string
inline std::string parseString(); inline std::string parseString();
/// transforms a unicode codepoint to it's UTF-8 presentation /// transforms a unicode codepoint to it's UTF-8 presentation
...@@ -450,6 +453,19 @@ class json ...@@ -450,6 +453,19 @@ class json
/// user-defined literal operator to create JSON objects from strings /// user-defined literal operator to create JSON objects from strings
nlohmann::json operator "" _json(const char*, std::size_t); nlohmann::json operator "" _json(const char*, std::size_t);
// specialization of std::swap
namespace std
{
template <>
/// swaps the values of two JSON objects
inline void swap(nlohmann::json& j1,
nlohmann::json& j2) noexcept(is_nothrow_move_constructible<nlohmann::json>::value and
is_nothrow_move_assignable<nlohmann::json>::value)
{
j1.swap(j2);
}
}
/*! /*!
@file @file
@copyright The code is licensed under the MIT License @copyright The code is licensed under the MIT License
...@@ -1720,6 +1736,12 @@ void json::clear() noexcept ...@@ -1720,6 +1736,12 @@ void json::clear() noexcept
} }
} }
void json::swap(json& o) noexcept
{
std::swap(type_, o.type_);
std::swap(value_, o.value_);
}
json::value_type json::type() const noexcept json::value_type json::type() const noexcept
{ {
return type_; return type_;
......
...@@ -1268,6 +1268,12 @@ void json::clear() noexcept ...@@ -1268,6 +1268,12 @@ void json::clear() noexcept
} }
} }
void json::swap(json& o) noexcept
{
std::swap(type_, o.type_);
std::swap(value_, o.value_);
}
json::value_type json::type() const noexcept json::value_type json::type() const noexcept
{ {
return type_; return type_;
......
...@@ -34,7 +34,6 @@ due to alignment. ...@@ -34,7 +34,6 @@ due to alignment.
@bug Numbers are currently handled too generously. There are several formats @bug Numbers are currently handled too generously. There are several formats
that are forbidden by the standard, but are accepted by the parser. that are forbidden by the standard, but are accepted by the parser.
@todo Implement json::swap()
@todo Implement json::insert(), json::emplace(), json::emplace_back, json::erase @todo Implement json::insert(), json::emplace(), json::emplace_back, json::erase
@todo Implement json::reverse_iterator, json::const_reverse_iterator, @todo Implement json::reverse_iterator, json::const_reverse_iterator,
json::rbegin(), json::rend(), json::crbegin(), json::crend()? json::rbegin(), json::rend(), json::crbegin(), json::crend()?
...@@ -289,6 +288,9 @@ class json ...@@ -289,6 +288,9 @@ class json
/// removes all elements from compounds and resets values to default /// removes all elements from compounds and resets values to default
void clear() noexcept; void clear() noexcept;
/// swaps content with other object
void swap(json&) noexcept;
/// return the type of the object /// return the type of the object
value_type type() const noexcept; value_type type() const noexcept;
...@@ -418,7 +420,7 @@ class json ...@@ -418,7 +420,7 @@ class json
/// read the next character, stripping whitespace /// read the next character, stripping whitespace
bool next(); bool next();
/// raise an exception with an error message /// raise an exception with an error message
inline void error(const std::string&) const __attribute__((noreturn)); [[noreturn]] inline void error(const std::string&) const;
/// parse a quoted string /// parse a quoted string
inline std::string parseString(); inline std::string parseString();
/// transforms a unicode codepoint to it's UTF-8 presentation /// transforms a unicode codepoint to it's UTF-8 presentation
...@@ -450,3 +452,16 @@ class json ...@@ -450,3 +452,16 @@ class json
/// user-defined literal operator to create JSON objects from strings /// user-defined literal operator to create JSON objects from strings
nlohmann::json operator "" _json(const char*, std::size_t); nlohmann::json operator "" _json(const char*, std::size_t);
// specialization of std::swap
namespace std
{
template <>
/// swaps the values of two JSON objects
inline void swap(nlohmann::json& j1,
nlohmann::json& j2) noexcept(is_nothrow_move_constructible<nlohmann::json>::value and
is_nothrow_move_assignable<nlohmann::json>::value)
{
j1.swap(j2);
}
}
...@@ -311,6 +311,17 @@ TEST_CASE("array") ...@@ -311,6 +311,17 @@ TEST_CASE("array")
json::const_iterator i4(i1); json::const_iterator i4(i1);
json::const_iterator i5(i2); json::const_iterator i5(i2);
} }
SECTION("Container operations")
{
json a1 = {1, 2, 3, 4};
json a2 = {"one", "two", "three"};
a1.swap(a2);
CHECK(a1 == json({"one", "two", "three"}));
CHECK(a2 == json({1, 2, 3, 4}));
}
} }
TEST_CASE("object") TEST_CASE("object")
...@@ -714,6 +725,22 @@ TEST_CASE("object") ...@@ -714,6 +725,22 @@ TEST_CASE("object")
json::const_iterator i4(i1); json::const_iterator i4(i1);
json::const_iterator i5(i2); json::const_iterator i5(i2);
} }
SECTION("Container operations")
{
json o1 = { {"one", "eins"}, {"two", "zwei"} };
json o2 = { {"one", 1}, {"two", 2} };
o1.swap(o2);
CHECK(o1 == json({ {"one", 1}, {"two", 2} }));
CHECK(o2 == json({ {"one", "eins"}, {"two", "zwei"} }));
std::swap(o1, o2);
CHECK(o1 == json({ {"one", "eins"}, {"two", "zwei"} }));
CHECK(o2 == json({ {"one", 1}, {"two", 2} }));
}
} }
TEST_CASE("null") TEST_CASE("null")
...@@ -777,6 +804,22 @@ TEST_CASE("null") ...@@ -777,6 +804,22 @@ TEST_CASE("null")
j1.clear(); j1.clear();
CHECK(j1 == json(nullptr)); CHECK(j1 == json(nullptr));
} }
SECTION("Container operations")
{
json n1;
json n2;
n1.swap(n2);
CHECK(n1 == json());
CHECK(n2 == json());
std::swap(n1, n2);
CHECK(n1 == json());
CHECK(n2 == json());
}
} }
TEST_CASE("string") TEST_CASE("string")
...@@ -871,6 +914,22 @@ TEST_CASE("string") ...@@ -871,6 +914,22 @@ TEST_CASE("string")
CHECK(json("\f").dump(0) == "\"\\f\""); CHECK(json("\f").dump(0) == "\"\\f\"");
CHECK(json("\r").dump(0) == "\"\\r\""); CHECK(json("\r").dump(0) == "\"\\r\"");
} }
SECTION("Container operations")
{
json s1 = "foo";
json s2 = "bar";
s1.swap(s2);
CHECK(s1 == json("bar"));
CHECK(s2 == json("foo"));
std::swap(s1, s2);
CHECK(s1 == json("foo"));
CHECK(s2 == json("bar"));
}
} }
TEST_CASE("boolean") TEST_CASE("boolean")
...@@ -950,6 +1009,22 @@ TEST_CASE("boolean") ...@@ -950,6 +1009,22 @@ TEST_CASE("boolean")
j1.clear(); j1.clear();
CHECK(j1.get<bool>() == false); CHECK(j1.get<bool>() == false);
} }
SECTION("Container operations")
{
json b1 = true;
json b2 = false;
b1.swap(b2);
CHECK(b1 == json(false));
CHECK(b2 == json(true));
std::swap(b1, b2);
CHECK(b1 == json(true));
CHECK(b2 == json(false));
}
} }
TEST_CASE("number (int)") TEST_CASE("number (int)")
...@@ -1036,6 +1111,22 @@ TEST_CASE("number (int)") ...@@ -1036,6 +1111,22 @@ TEST_CASE("number (int)")
CHECK(j2.find("foo") == j2.end()); CHECK(j2.find("foo") == j2.end());
CHECK(j2.find(std::string("foo")) == j2.end()); CHECK(j2.find(std::string("foo")) == j2.end());
} }
SECTION("Container operations")
{
json n1 = 23;
json n2 = 42;
n1.swap(n2);
CHECK(n1 == json(42));
CHECK(n2 == json(23));
std::swap(n1, n2);
CHECK(n1 == json(23));
CHECK(n2 == json(42));
}
} }
TEST_CASE("number (float)") TEST_CASE("number (float)")
...@@ -1115,6 +1206,22 @@ TEST_CASE("number (float)") ...@@ -1115,6 +1206,22 @@ TEST_CASE("number (float)")
j1.clear(); j1.clear();
CHECK(j1.get<double>() == 0.0); CHECK(j1.get<double>() == 0.0);
} }
SECTION("Container operations")
{
json n1 = 23.42;
json n2 = 42.23;
n1.swap(n2);
CHECK(n1 == json(42.23));
CHECK(n2 == json(23.42));
std::swap(n1, n2);
CHECK(n1 == json(23.42));
CHECK(n2 == json(42.23));
}
} }
TEST_CASE("Iterators") TEST_CASE("Iterators")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment