Skip to content

Commit

Permalink
+ Added (implicit) constructors for json "supported" types.
Browse files Browse the repository at this point in the history
  + added corresponding tests.
+ Added json-map examples.
  • Loading branch information
Lucas David committed Aug 9, 2021
1 parent 762af68 commit 235f2b9
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 6 deletions.
37 changes: 35 additions & 2 deletions examples/example_json_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
#define CROW_JSON_USE_MAP
#include "crow.h"



int main()
{
crow::SimpleApp app;
Expand All @@ -19,6 +17,41 @@ CROW_ROUTE(app, "/json")
return x;
});

CROW_ROUTE(app, "/json-initializer-list-constructor")
([] {
return crow::json::wvalue({
{"first", "Hello world!"}, /* stores a char const* hence a type::String */
{"second", "How are you today?"}, /* stores a char const* hence a std::int64_t. */
{"third", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
{"fourth", 54l}, /* stores a long (as 54l is a long literal) hence a std::int64_t. */
{"fifth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
{"sixth", 54ul}, /* stores an unsigned long (as 54ul is an unsigned long literal) hence a std::uint64_t. */
{"seventh", 2.f}, /* stores a float (as 2.f is a float literal) hence a double. */
{"eighth", 2.}, /* stores a double (as 2. is a double literal) hence a double. */
{"ninth", nullptr}, /* stores a std::nullptr hence type::Null . */
{"tenth", true} /* stores a bool hence type::True . */
});
});

CROW_ROUTE(app, "/json-map-constructor")
([] {
crow::json::wvalue::object_type map({
{"first", "Hello world!"}, /* stores a char const* hence a type::String */
{"second", "How are you today?"}, /* stores a char const* hence a std::int64_t. */
{"third", 54}, /* stores an int (as 54 is an int literal) hence a std::int64_t. */
{"fourth", 54l}, /* stores a long (as 54l is a long literal) hence a std::int64_t. */
{"fifth", 54u}, /* stores an unsigned int (as 54u is a unsigned int literal) hence a std::uint64_t. */
{"sixth", 54ul}, /* stores an unsigned long (as 54ul is an unsigned long literal) hence a std::uint64_t. */
{"seventh", 2.f}, /* stores a float (as 2.f is a float literal) hence a double. */
{"eighth", 2.}, /* stores a double (as 2. is a double literal) hence a double. */
{"ninth", nullptr}, /* stores a std::nullptr hence type::Null . */
{"tenth", true} /* stores a bool hence type::True . */
});

return crow::json::wvalue(map);
});


// enables all log
app.loglevel(crow::LogLevel::Debug);

Expand Down
44 changes: 40 additions & 4 deletions include/crow/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -1238,10 +1238,26 @@ namespace crow
private:
type t_{type::Null}; ///< The type of the value.
num_type nt{num_type::Null}; ///< The specific type of the number if \ref t_ is a number.
union {
union number {
double d;
int64_t si;
uint64_t ui {};
uint64_t ui;

public:
constexpr number() noexcept : ui() {} /* default constructor initializes unsigned integer. */

constexpr number(std::uint8_t value) noexcept : ui(static_cast<std::uint64_t>(value)) {}
constexpr number(std::uint16_t value) noexcept : ui(static_cast<std::uint64_t>(value)) {}
constexpr number(std::uint32_t value) noexcept : ui(static_cast<std::uint64_t>(value)) {}
constexpr number(std::uint64_t value) noexcept : ui(value) {}

constexpr number(std::int8_t value) noexcept : si(static_cast<std::int64_t>(value)) {}
constexpr number(std::int16_t value) noexcept : si(static_cast<std::int64_t>(value)) {}
constexpr number(std::int32_t value) noexcept : si(static_cast<std::int64_t>(value)) {}
constexpr number(std::int64_t value) noexcept : si(value) {}

constexpr number(float value) noexcept : d(static_cast<double>(value)) {}
constexpr number(double value) noexcept : d(value) {}
} num; ///< Value if type is a number.
std::string s; ///< Value if type is a string.
std::unique_ptr<std::vector<wvalue>> l; ///< Value if type is a list.
Expand All @@ -1252,13 +1268,33 @@ namespace crow
#endif

public:

wvalue() : returnable("application/json") {}

wvalue(std::nullptr_t) : returnable("application/json"), t_(type::Null) {}

wvalue(bool value) : returnable("application/json"), t_(value ? type::True : type::False) {}

wvalue(std::uint8_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(value) {}
wvalue(std::uint16_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(value) {}
wvalue(std::uint32_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(value) {}
wvalue(std::uint64_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(value) {}

wvalue(std::int8_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(value) {}
wvalue(std::int16_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(value) {}
wvalue(std::int32_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(value) {}
wvalue(std::int64_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Signed_integer), num(value) {}

wvalue(float value) : returnable("application/json"), t_(type::Number), nt(num_type::Floating_point), num(value) {}
wvalue(double value) : returnable("application/json"), t_(type::Number), nt(num_type::Floating_point), num(value) {}

wvalue(char const* value) : returnable("application/json"), t_(type::String), s(value) {}

wvalue(std::string const& value) : returnable("application/json"), t_(type::String), s(value) {}
wvalue(std::string&& value) : returnable("application/json"), t_(type::String), s(std::move(value)) {}

wvalue(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list) : returnable("application/json"), t_(type::Object), o(new object_type(initializer_list)) {}

wvalue(object_type const& value) : returnable("application/json"), t_(type::Object), o(new object_type(value)) {}

wvalue(object_type&& value) : returnable("application/json"), t_(type::Object), o(new object_type(std::move(value))) {}

wvalue(std::vector<wvalue>& r) : returnable("application/json")
Expand Down
109 changes: 109 additions & 0 deletions tests/unittest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,115 @@ TEST_CASE("json_copy_r_to_w_to_w_to_r")
CHECK("other" == x["obj"]["other"].key());
}

TEST_CASE("json::wvalue::wvalue(bool)") {
CHECK(json::wvalue(true).t() == json::type::True);
CHECK(json::wvalue(false).t() == json::type::False);
}

TEST_CASE("json::wvalue::wvalue(std::uint8_t)") {
std::uint8_t i = 42;
json::wvalue value = i;

CHECK(value.t() == json::type::Number);
CHECK(value.dump() == "42");
}

TEST_CASE("json::wvalue::wvalue(std::uint16_t)") {
std::uint16_t i = 42;
json::wvalue value = i;

CHECK(value.t() == json::type::Number);
CHECK(value.dump() == "42");
}

TEST_CASE("json::wvalue::wvalue(std::uint32_t)") {
std::uint32_t i = 42;
json::wvalue value = i;

CHECK(value.t() == json::type::Number);
CHECK(value.dump() == "42");
}

TEST_CASE("json::wvalue::wvalue(std::uint64_t)") {
std::uint64_t i = 42;
json::wvalue value = i;

CHECK(value.t() == json::type::Number);
CHECK(value.dump() == "42");
}

TEST_CASE("json::wvalue::wvalue(std::int8_t)") {
std::int8_t i = -42;
json::wvalue value = i;

CHECK(value.t() == json::type::Number);
CHECK(value.dump() == "-42");
}

TEST_CASE("json::wvalue::wvalue(std::int16_t)") {
std::int16_t i = -42;
json::wvalue value = i;

CHECK(value.t() == json::type::Number);
CHECK(value.dump() == "-42");
}

TEST_CASE("json::wvalue::wvalue(std::int32_t)") {
std::int32_t i = -42;
json::wvalue value = i;

CHECK(value.t() == json::type::Number);
CHECK(value.dump() == "-42");
}

TEST_CASE("json::wvalue::wvalue(std::int64_t)") {
std::int64_t i = -42;
json::wvalue value = i;

CHECK(value.t() == json::type::Number);
CHECK(value.dump() == "-42");
}

TEST_CASE("json::wvalue::wvalue(float)") {
float f = 4.2;
json::wvalue value = f;

CHECK(value.t() == json::type::Number);
CHECK(value.dump() == "4.2");
}

TEST_CASE("json::wvalue::wvalue(double)") {
double d = 4.2;
json::wvalue value = d;

CHECK(value.t() == json::type::Number);
CHECK(value.dump() == "4.2");
}

TEST_CASE("json::wvalue::wvalue(char const*)") {
char const* str = "Hello world!";
json::wvalue value = str;

CHECK(value.t() == json::type::String);
CHECK(value.dump() == "\"Hello world!\"");
}

TEST_CASE("json::wvalue::wvalue(std::string const&)") {
std::string str = "Hello world!";
json::wvalue value = str;

CHECK(value.t() == json::type::String);
CHECK(value.dump() == "\"Hello world!\"");
}

TEST_CASE("json::wvalue::wvalue(std::string&&)") {
std::string str = "Hello world!";
json::wvalue value = std::move(str);

CHECK(value.t() == json::type::String);
CHECK(value.dump() == "\"Hello world!\"");
}

TEST_CASE("json::wvalue::wvalue(std::initializer_list<std::pair<std::string const, json::wvalue>>)") {
json::wvalue integer, number, truth, lie, null;
integer = 2147483647;
Expand Down

0 comments on commit 235f2b9

Please sign in to comment.