Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature-#189 #190

Merged
merged 9 commits into from
Aug 16, 2021
Merged
18 changes: 16 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,22 @@ 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 json::type::String */
{"second", std::string("How are you today?")}, /* stores a std::string hence a json::type::String. */
{"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 json::type::Null . */
{"tenth", true} /* stores a bool hence json::type::True . */
});
});

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

Expand Down
83 changes: 80 additions & 3 deletions include/crow/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -1224,15 +1224,30 @@ namespace crow
class wvalue : public returnable
{
friend class crow::mustache::template_t;

public:
using object_type =
#ifdef CROW_JSON_USE_MAP
std::map<std::string, wvalue>;
#else
std::unordered_map<std::string, wvalue>;
#endif

public:
type t() const { return t_; }
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::uint64_t value) noexcept : ui(value) {}
constexpr number(std::int64_t value) noexcept : si(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 @@ -1243,9 +1258,35 @@ 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(static_cast<std::uint64_t>(value)) {}
wvalue(std::uint16_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
wvalue(std::uint32_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
wvalue(std::uint64_t value) : returnable("application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}

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

wvalue(float value) : returnable("application/json"), t_(type::Number), nt(num_type::Floating_point), num(static_cast<double>(value)) {}
wvalue(double value) : returnable("application/json"), t_(type::Number), nt(num_type::Floating_point), num(static_cast<double>(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)) {}
mrozigor marked this conversation as resolved.
Show resolved Hide resolved
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")
{
t_ = type::List;
Expand Down Expand Up @@ -1508,6 +1549,42 @@ namespace crow
return *this;
}

wvalue& operator=(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list)
{
if (t_ != type::Object) {
reset();
t_ = type::Object;
o = std::unique_ptr<object_type>(new object_type(initializer_list));
} else {
(*o) = initializer_list;
}
return *this;
}

wvalue& operator=(object_type const& value)
{
if (t_ != type::Object) {
reset();
t_ = type::Object;
o = std::unique_ptr<object_type>(new object_type(value));
} else {
(*o) = value;
}
return *this;
}

wvalue& operator=(object_type&& value)
{
if (t_ != type::Object) {
reset();
t_ = type::Object;
o = std::unique_ptr<object_type>(new object_type(std::move(value)));
} else {
(*o) = std::move(value);
}
return *this;
}

wvalue& operator[](unsigned index)
{
if (t_ != type::List)
Expand Down
Loading