Skip to content

Commit

Permalink
Merge pull request leapmotion#6 from leapmotion/bug-json11
Browse files Browse the repository at this point in the history
JSON11 MSVC defects
  • Loading branch information
gtremper committed Jul 30, 2014
2 parents 27cf65c + f8b87ef commit 54e5b43
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 20 deletions.
25 changes: 16 additions & 9 deletions contrib/json11/json11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ using std::make_shared;
using std::initializer_list;
using std::move;

#ifdef _MSC_VER
// MSVC has funny names for snprintf, we just use it instead
#define snprintf(str, size, format, ...) _snprintf_s(str, size, _TRUNCATE, format, __VA_ARGS__)
#endif

/* * * * * * * * * * * * * * * * * * * *
* Serialization
*/
Expand Down Expand Up @@ -158,7 +163,7 @@ class Value : public JsonValue {

class JsonDouble final : public Value<Json::NUMBER, double> {
double number_value() const { return m_value; }
int int_value() const { return m_value; }
int int_value() const { return static_cast<int>(m_value); }
bool equals(const JsonValue * other) const { return m_value == other->number_value(); }
bool less(const JsonValue * other) const { return m_value < other->number_value(); }
public:
Expand All @@ -171,7 +176,7 @@ class JsonInt final : public Value<Json::NUMBER, int> {
bool equals(const JsonValue * other) const { return m_value == other->number_value(); }
bool less(const JsonValue * other) const { return m_value < other->number_value(); }
public:
JsonInt(double value) : Value(value) {}
JsonInt(double value) : Value(static_cast<int>(value)) {}
};

class JsonBoolean final : public Value<Json::BOOL, bool> {
Expand Down Expand Up @@ -212,6 +217,8 @@ class JsonNull final : public Value<Json::NUL, std::nullptr_t> {
* Static globals - static-init-safe
*/
struct Statics {
Statics() {}

const std::shared_ptr<JsonValue> null = make_shared<JsonNull>();
const std::shared_ptr<JsonValue> t = make_shared<JsonBoolean>(true);
const std::shared_ptr<JsonValue> f = make_shared<JsonBoolean>(false);
Expand All @@ -235,8 +242,8 @@ const Json & static_null() {
* Constructors
*/

Json::Json() noexcept : m_ptr(statics().null) {}
Json::Json(std::nullptr_t) noexcept : m_ptr(statics().null) {}
Json::Json() JSON11_NOEXCEPT : m_ptr(statics().null) {}
Json::Json(std::nullptr_t) JSON11_NOEXCEPT : m_ptr(statics().null) {}
Json::Json(double value) : m_ptr(make_shared<JsonDouble>(value)) {}
Json::Json(int value) : m_ptr(make_shared<JsonInt>(value)) {}
Json::Json(bool value) : m_ptr(value ? statics().t : statics().f) {}
Expand Down Expand Up @@ -380,16 +387,16 @@ struct JsonParser {
return;

if (pt < 0x80) {
out += pt;
out += static_cast<char>(pt);
} else if (pt < 0x800) {
out += (pt >> 6) | 0xC0;
out += (pt & 0x3F) | 0x80;
out += static_cast<char>(pt >> 6) | 0xC0;
out += static_cast<char>(pt & 0x3F) | 0x80;
} else if (pt < 0x10000) {
out += (pt >> 12) | 0xE0;
out += static_cast<char>(pt >> 12) | 0xE0;
out += ((pt >> 6) & 0x3F) | 0x80;
out += (pt & 0x3F) | 0x80;
} else {
out += (pt >> 18) | 0xF0;
out += static_cast<char>(pt >> 18) | 0xF0;
out += ((pt >> 12) & 0x3F) | 0x80;
out += ((pt >> 6) & 0x3F) | 0x80;
out += (pt & 0x3F) | 0x80;
Expand Down
43 changes: 32 additions & 11 deletions contrib/json11/json11.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@
#include <memory>
#include <initializer_list>

#ifdef _MSC_VER
// noexcept was added to MSVC in Visual Studio 2014
#if _MSC_VER > 1800
#define JSON11_NOEXCEPT noexcept
#else
#define JSON11_NOEXCEPT throw()
#endif
#else
#define JSON11_NOEXCEPT noexcept
#endif

namespace json11 {

class JsonValue;
Expand All @@ -72,8 +83,8 @@ class Json final {
typedef std::map<std::string, Json> object;

// Constructors for the various types of JSON value.
Json() noexcept; // NUL
Json(std::nullptr_t) noexcept; // NUL
Json() JSON11_NOEXCEPT; // NUL
Json(std::nullptr_t) JSON11_NOEXCEPT; // NUL
Json(double value); // NUMBER
Json(int value); // NUMBER
Json(bool value); // BOOL
Expand All @@ -90,17 +101,27 @@ class Json final {
Json(const T & t) : Json(t.to_json()) {}

// Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
template <class M, typename std::enable_if<
std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value
&& std::is_constructible<Json, decltype(std::declval<M>().begin()->second)>::value,
int>::type = 0>
Json(const M & m) : Json(object(m.begin(), m.end())) {}
template <class M>
Json(
const typename std::enable_if<
std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value &&
std::is_constructible<std::string, decltype(std::declval<M>().begin()->second)>::value,
M
>::type& m
) :
Json(object(m.begin(), m.end()))
{}

// Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc)
template <class V, typename std::enable_if<
std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
int>::type = 0>
Json(const V & v) : Json(array(v.begin(), v.end())) {}
template <class V>
Json(
const typename std::enable_if<
std::is_constructible<Json, decltype(std::declval<V>().begin()->first)>::value,
V
>::type& v
) :
Json(array(v.begin(), v.end()))
{}

// This prevents Json(some_pointer) from accidentally producing a bool. Use
// Json(bool(some_pointer)) if that behavior is desired.
Expand Down

0 comments on commit 54e5b43

Please sign in to comment.