json11
json11 copied to clipboard
MSVC12 Compatibility
I really like the library design and would like to use it cross platform. Unfortunately there are a few roadblocks for using it with MSVC12 (VS2013):
- In json11.cpp the Statics struct can't be initialized because not every member has an initializer
- Missing noexcept and snprintf
- The templates that should define implicit constructors for map and vector like objects seem to fail because std::declval<V>() can not be properly resolved and therefore begin can't be found
The first one can be easily fixed by removing the initializers and adding them to the initializer-list in statics():
struct Statics {
const std::shared_ptr<JsonValue> null;
const std::shared_ptr<JsonValue> t;
const std::shared_ptr<JsonValue> f;
const string empty_string;
const vector<Json> empty_vector;
const map<string, Json> empty_map;
};
const Statics & statics() {
static const Statics s {
make_shared<JsonNull>(),
make_shared<JsonBoolean>(true),
make_shared<JsonBoolean>(false),
"",
vector<Json>(),
map<string, Json>()
};
return s;
}
The missing noexcept and sprintf are a bit harder. MSVC12 does not (yet) include them. It is possible to create a preprocessor define for noexcept after the STL header includes (as an error is thrown when trying to define the missing noexcept myself). snprintf can be replaced by _snprintf but unfortunately behaves a bit different (snprintf truncates and always 0-terminates, _snprintf does not 0-terminate if the buffer is too small, also the return values are different which are not used anyway).
I didn't invest enough much time digging in c++11s templating features to understand the third problem yet. A simple solution is to comment out the two constructors but I am sure there is a better solution.
This is an issue for me and I don't know if you are interested in supporting MSVC12 (don't know if this gets better with the next compiler update).
PS: Having this library header only would be really nice too, but that's secondary for now
Hm, apparently VS2013 is supposed to support declval. But, it looks like I forgot to include
json11 only uses snprintf to print numbers, so it should be "safe" to replace all instances of snprintf with sprintf... I'd want to triple-check all the buffer sizes, though.
I forgot to mention that I already added <type_traits> to check if this is the issue. Unfortunately not, for reference here is my build output: https://gist.github.com/PaulFreund/11154815
Just wanted to tell you that I created a copy for me that is header only and compatible with gcc and msvc12 although I currently excluded the two templates that won't compile with msvc12. It's currently very rough and looks like patchwork but it works for now. Currently I am looking into making the objects mutable so I can spare a few copies.
I was able to get it to compile by adding this right above namespace json11
#ifdef _MSC_VER
#if _MSC_VER <= 1800 // VS 2013
#define noexcept
#define snprintf _snprintf_s
#endif
#endif
_snprintf_s
is identical to the Unix snprintf
, and since noexcept
isn't supported in VS2013, we just erase them.
Intellisense still doesn't like the fail
method, but it seems mostly harmless.
@retrop we can mimic noexcept
with throw()
and I don't think snprintf
is equal to _snprintf_s
see:
- http://stackoverflow.com/questions/12833241/difference-between-c03-throw-specifier-c11-noexcept
- https://github.com/llvm-mirror/libcxx/blob/master/include/support/win32/support.h
note:
I know that on paper noexcept != throw()
but the way it is used in json11
they are more or less equal.
#ifdef _MSC_VER
#if _MSC_VER <= 1800 // VS 2013
#define noexcept throw()
#define snprintf _snprintf
#endif
#endif