diff --git a/.gitignore b/.gitignore index 31f4be72..430bb1c4 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,17 @@ *.la *.a +# Visual studio cruft +*.opensdf +*.sdf +*.suo +*.user +*/x64 +*/Debug* +*/Release* +*.log +*.tlog* + out.txt ptr.txt test.txt @@ -19,10 +30,11 @@ unittests boost_serialize arr.txt performance -sandbox -sandbox_rtti -sandbox_json +./sandbox +./sandbox_rtti +./sandbox_json include_renamed .ycm_extra_conf.py* doc/html +rtti.txt doc/latex diff --git a/Makefile b/Makefile index 9ac8d876..f5c46096 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,9 @@ sandbox_json: sandbox_json.cpp sandbox_rtti: sandbox_rtti.cpp ${CC} sandbox_rtti.cpp -o sandbox_rtti ${CPPFLAGS} -O3 +sandbox_vs: sandbox_vs.cpp + ${CC} sandbox_vs.cpp -o sandbox_vs ${CPPFLAGS} + unittests: unittests.cpp ${CC} unittests.cpp -o unittests -lboost_unit_test_framework ${CPPFLAGS} ./unittests --show_progress diff --git a/include/cereal/access.hpp b/include/cereal/access.hpp index 7a4ca0ff..fdf4b967 100644 --- a/include/cereal/access.hpp +++ b/include/cereal/access.hpp @@ -30,6 +30,7 @@ #define CEREAL_ACCESS_HPP_ #include +#include namespace cereal { @@ -86,7 +87,7 @@ namespace cereal static void load_and_allocate(...) { } }; - + //! A class that can be made a friend to give cereal access to non public functions /*! If you desire non-public serialization functions within a class, cereal can only access these if you declare cereal::access a friend. @@ -109,21 +110,20 @@ namespace cereal { public: template inline - static auto member_serialize(Archive & ar, T & t) -> decltype(t.serialize(ar)) - { t.serialize(ar); } + static auto member_serialize(Archive & ar, T & t) -> decltype(t.serialize(ar)) + { t.serialize(ar); } + + template inline + static auto member_save(Archive & ar, T const & t) -> decltype(t.save(ar)) + { t.save(ar); } template inline - static auto member_save(Archive & ar, T const & t) -> decltype(t.save(ar)) - { t.save(ar); } - - // Used during detection of non const member save - template inline - static auto non_const_member_save(Archive & ar, T & t) -> decltype(t.save(ar)) - { t.save(ar); } + static auto member_save_non_const(Archive & ar, T & t) -> decltype(t.save(ar)) + { t.save(ar); } template inline - static auto member_load(Archive & ar, T & t) -> decltype(t.load(ar)) - { t.load(ar); } + static auto member_load(Archive & ar, T & t) -> decltype(t.load(ar)) + { t.load(ar); } template static void load_and_allocate(...) diff --git a/include/cereal/archives/binary.hpp b/include/cereal/archives/binary.hpp index 4238d019..432be165 100644 --- a/include/cereal/archives/binary.hpp +++ b/include/cereal/archives/binary.hpp @@ -53,12 +53,12 @@ namespace cereal BinaryOutputArchive(std::ostream & stream) : OutputArchive(this), itsStream(stream) - { } + { } //! Writes size bytes of data to the output stream - void saveBinary( const void * data, size_t size ) + void saveBinary( const void * data, std::size_t size ) { - size_t const writtenSize = itsStream.rdbuf()->sputn( reinterpret_cast( data ), size ); + auto const writtenSize = static_cast( itsStream.rdbuf()->sputn( reinterpret_cast( data ), size ) ); if(writtenSize != size) throw Exception("Failed to write " + std::to_string(size) + " bytes to output stream! Wrote " + std::to_string(writtenSize)); @@ -85,9 +85,9 @@ namespace cereal { } //! Reads size bytes of data from the input stream - void loadBinary( void * const data, size_t size ) + void loadBinary( void * const data, std::size_t size ) { - size_t const readSize = itsStream.rdbuf()->sgetn( reinterpret_cast( data ), size ); + auto const readSize = static_cast( itsStream.rdbuf()->sgetn( reinterpret_cast( data ), size ) ); if(readSize != size) throw Exception("Failed to read " + std::to_string(size) + " bytes from input stream! Read " + std::to_string(readSize)); @@ -136,14 +136,14 @@ namespace cereal template inline void save(BinaryOutputArchive & ar, BinaryData const & bd) { - ar.saveBinary(bd.data, bd.size); + ar.saveBinary( bd.data, static_cast( bd.size ) ); } //! Loading binary data template inline void load(BinaryInputArchive & ar, BinaryData & bd) { - ar.loadBinary(bd.data, bd.size); + ar.loadBinary(bd.data, static_cast(bd.size)); } } // namespace cereal diff --git a/include/cereal/archives/json.hpp b/include/cereal/archives/json.hpp index 52cb03d3..9b485be6 100644 --- a/include/cereal/archives/json.hpp +++ b/include/cereal/archives/json.hpp @@ -98,24 +98,45 @@ namespace cereal itsWriter.EndObject(); } - void saveValue(bool b) { itsWriter.Bool(b); } - void saveValue(int i) { itsWriter.Int(i); } - void saveValue(unsigned u) { itsWriter.Uint(u); } - void saveValue(int64_t i64) { itsWriter.Int64(i64); } - void saveValue(uint64_t u64) { itsWriter.Uint64(u64); } - void saveValue(double d) { itsWriter.Double(d); } - void saveValue(std::string const & s) { itsWriter.String(s.c_str(), s.size()); } - void saveValue(char const * s) { itsWriter.String(s); } + void saveValue(bool b) { itsWriter.Bool(b); } + void saveValue(int i) { itsWriter.Int(i); } + void saveValue(unsigned u) { itsWriter.Uint(u); } + void saveValue(int64_t i64) { itsWriter.Int64(i64); } + void saveValue(uint64_t u64) { itsWriter.Uint64(u64); } + void saveValue(double d) { itsWriter.Double(d); } + void saveValue(std::string const & s) { itsWriter.String(s.c_str(), static_cast( s.size() )); } + void saveValue(char const * s) { itsWriter.String(s); } + +#ifdef _MSC_VER + // Visual Studio has problems disambiguating the above for unsigned long, so we provide an explicit + // overload for long and serialize it as its size necessitates + // + // When loading we don't need to do this specialization since we catch the types with + // templates according to their size + + //! 32 bit long saving + template inline + typename std::enable_if::type + saveLong(T lu){ saveValue( static_cast( lu ) ); } + + //! non 32 bit long saving + template inline + typename std::enable_if::type + saveLong(T lu){ saveValue( static_cast( lu ) ); } + + //! MSVC only long overload + void saveValue( unsigned long lu ){ saveLong( lu ); }; +#endif //! Save exotic arithmetic types as binary template - typename std::enable_if::value && - (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long)), void>::type - saveValue(T const & t) - { - auto base64string = base64::encode( reinterpret_cast( &t ), sizeof(T) ); - saveValue( base64string ); - } + typename std::enable_if::value && + (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long)), void>::type + saveValue(T const & t) + { + auto base64string = base64::encode( reinterpret_cast( &t ), sizeof(T) ); + saveValue( base64string ); + } //! Write the name of the upcoming node and prepare object/array state /*! Since writeName is called for every value that is output, regardless of @@ -325,7 +346,7 @@ namespace cereal void loadValue(bool & val) { val = itsValueStack.back().value().GetBool(); ++itsValueStack.back(); } void loadValue(int64_t & val) { val = itsValueStack.back().value().GetInt64(); ++itsValueStack.back(); } void loadValue(uint64_t & val) { val = itsValueStack.back().value().GetUint64(); ++itsValueStack.back(); } - void loadValue(float & val) { val = itsValueStack.back().value().GetDouble(); ++itsValueStack.back(); } + void loadValue(float & val) { val = static_cast(itsValueStack.back().value().GetDouble()); ++itsValueStack.back(); } void loadValue(double & val) { val = itsValueStack.back().value().GetDouble(); ++itsValueStack.back(); } void loadValue(std::string & val) { val = itsValueStack.back().value().GetString(); ++itsValueStack.back(); } @@ -358,7 +379,7 @@ namespace cereal }; //! Loads the size for a SizeTag - void loadSize(size_t & size) + void loadSize(size_type & size) { size = (itsValueStack.rbegin() + 1)->value().Size(); } diff --git a/include/cereal/archives/portable_binary.hpp b/include/cereal/archives/portable_binary.hpp index b9f76b14..27eeb38a 100644 --- a/include/cereal/archives/portable_binary.hpp +++ b/include/cereal/archives/portable_binary.hpp @@ -42,17 +42,17 @@ namespace cereal inline bool is_little_endian() { static std::int32_t test = 1; - return *reinterpret_cast( &test ); + return *reinterpret_cast( &test ) == 1; } //! Swaps the order of bytes for some chunk of memory /*! @param data The data as a uint8_t pointer @tparam DataSize The true size of the data @ingroup Internal */ - template + template inline void swap_bytes( std::uint8_t * data ) { - for( size_t i = 0, end = DataSize / 2; i < end; ++i ) + for( std::size_t i = 0, end = DataSize / 2; i < end; ++i ) std::swap( data[i], data[DataSize - i - 1] ); } } // end namespace portable_binary_detail @@ -85,9 +85,9 @@ namespace cereal } //! Writes size bytes of data to the output stream - void saveBinary( const void * data, size_t size ) + void saveBinary( const void * data, std::size_t size ) { - size_t const writtenSize = itsStream.rdbuf()->sputn( reinterpret_cast( data ), size ); + auto const writtenSize = static_cast( itsStream.rdbuf()->sputn( reinterpret_cast( data ), size ) ); if(writtenSize != size) throw Exception("Failed to write " + std::to_string(size) + " bytes to output stream! Wrote " + std::to_string(writtenSize)); @@ -138,11 +138,11 @@ namespace cereal /*! @param data The data to save @param size The number of bytes in the data @tparam DataSize T The size of the actual type of the data elements being loaded */ - template - void loadBinary( void * const data, size_t size ) + template + void loadBinary( void * const data, std::size_t size ) { // load data - size_t const readSize = itsStream.rdbuf()->sgetn( reinterpret_cast( data ), size ); + auto const readSize = static_cast( itsStream.rdbuf()->sgetn( reinterpret_cast( data ), size ) ); if(readSize != size) throw Exception("Failed to read " + std::to_string(size) + " bytes from input stream! Read " + std::to_string(readSize)); @@ -151,7 +151,7 @@ namespace cereal if( itsConvertEndianness ) { std::uint8_t * ptr = reinterpret_cast( data ); - for( size_t i = 0; i < size; i += DataSize ) + for( std::size_t i = 0; i < size; i += DataSize ) portable_binary_detail::swap_bytes( ptr ); } } @@ -211,7 +211,7 @@ namespace cereal (std::is_floating_point::value && std::numeric_limits::is_iec559), "Portable binary only supports IEEE 754 standardized floating point" ); - ar.saveBinary(bd.data, bd.size); + ar.saveBinary( bd.data, static_cast( bd.size ) ); } //! Loading binary data from portable binary @@ -223,7 +223,7 @@ namespace cereal (std::is_floating_point::value && std::numeric_limits::is_iec559), "Portable binary only supports IEEE 754 standardized floating point" ); - ar.template loadBinary(bd.data, bd.size); + ar.template loadBinary( bd.data, static_cast( bd.size ) ); } } // namespace cereal diff --git a/include/cereal/archives/xml.hpp b/include/cereal/archives/xml.hpp index 5f0a3174..7db51034 100644 --- a/include/cereal/archives/xml.hpp +++ b/include/cereal/archives/xml.hpp @@ -155,7 +155,7 @@ namespace cereal template inline void saveValue( T const & value ) { - itsOS.clear(); itsOS.seekp(0); + itsOS.clear(); itsOS.seekp( 0, std::ios::beg ); itsOS << value << std::ends; // allocate strings for all of the data in the XML object @@ -286,7 +286,7 @@ namespace cereal itsData.push_back('\0'); // rapidxml will do terrible things without the data being null terminated itsXML.parse( reinterpret_cast( itsData.data() ) ); } - catch( rapidxml::parse_error const & e ) + catch( rapidxml::parse_error const & ) { //std::cerr << "-----Original-----" << std::endl; //stream.seekg(0); @@ -337,7 +337,7 @@ namespace cereal typename std::enable_if::value && !std::is_same::value && sizeof(T) < sizeof(long long), void>::type loadValue( T & value ) { - value = std::stoul( itsNodes.top().node->value() ); + value = static_cast( std::stoul( itsNodes.top().node->value() ) ); } //! Loads a type best represented as an unsigned long long @@ -345,7 +345,7 @@ namespace cereal typename std::enable_if::value && !std::is_same::value && sizeof(T) >= sizeof(long long), void>::type loadValue( T & value ) { - value = std::stoull( itsNodes.top().node->value() ); + value = static_cast( std::stoull( itsNodes.top().node->value() ) ); } //! Loads a type best represented as an int @@ -353,7 +353,7 @@ namespace cereal typename std::enable_if::value && sizeof(T) <= sizeof(int), void>::type loadValue( T & value ) { - value = std::stoi( itsNodes.top().node->value() ); + value = static_cast( std::stoi( itsNodes.top().node->value() ) ); } //! Loads a type best represented as a long @@ -361,7 +361,7 @@ namespace cereal typename std::enable_if::value && (sizeof(T) > sizeof(int)) && (sizeof(T) <= sizeof(long)), void>::type loadValue( T & value ) { - value = std::stol( itsNodes.top().node->value() ); + value = static_cast( std::stol( itsNodes.top().node->value() ) ); } //! Loads a type best represented as a long long @@ -369,7 +369,7 @@ namespace cereal typename std::enable_if::value && (sizeof(T) > sizeof(long)) && (sizeof(T) <= sizeof(long long)), void>::type loadValue( T & value ) { - value = std::stoll( itsNodes.top().node->value() ); + value = static_cast( std::stoll( itsNodes.top().node->value() ) ); } //! Loads a type best represented as a float diff --git a/include/cereal/cereal.hpp b/include/cereal/cereal.hpp index 4966142c..eae69102 100644 --- a/include/cereal/cereal.hpp +++ b/include/cereal/cereal.hpp @@ -269,8 +269,8 @@ namespace cereal //! Member serialization template inline - typename std::enable_if() || - (traits::is_output_serializable() && traits::has_member_serialize()), + typename std::enable_if::value || + (traits::is_output_serializable::value && traits::has_member_serialize::value), ArchiveType &>::type processImpl(T const & t) { @@ -280,8 +280,8 @@ namespace cereal //! Non member serialization template inline - typename std::enable_if() || - (traits::is_output_serializable() && traits::has_non_member_serialize()), + typename std::enable_if::value || + (traits::is_output_serializable::value && traits::has_non_member_serialize::value), ArchiveType &>::type processImpl(T const & t) { @@ -291,8 +291,8 @@ namespace cereal //! Member split (save) template inline - typename std::enable_if() || - (traits::is_output_serializable() && traits::has_member_save()), + typename std::enable_if::value || + (traits::is_output_serializable::value && traits::has_member_save::value), ArchiveType &>::type processImpl(T const & t) { @@ -302,8 +302,8 @@ namespace cereal //! Non member split (save) template inline - typename std::enable_if() || - (traits::is_output_serializable() && traits::has_non_member_save()), + typename std::enable_if::value || + (traits::is_output_serializable::value && traits::has_non_member_save::value), ArchiveType &>::type processImpl(T const & t) { @@ -314,7 +314,7 @@ namespace cereal //! Empty class specialization template inline typename std::enable_if<(Flags & AllowEmptyClassElision) && - !traits::is_output_serializable() && traits::is_empty_class(), ArchiveType &>::type + !traits::is_output_serializable::value && std::is_empty::value, ArchiveType &>::type processImpl(T const &) { return *self; @@ -322,12 +322,12 @@ namespace cereal //! No matching serialization template inline - typename std::enable_if() && !traits::is_output_serializable() && - (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !traits::is_empty_class())), + typename std::enable_if::value && !traits::is_output_serializable::value && + (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty::value)), ArchiveType &>::type processImpl(T const &) { - static_assert(traits::is_output_serializable(), "Trying to serialize an unserializable type with an output archive.\n\n" + static_assert(traits::is_output_serializable::value, "Trying to serialize an unserializable type with an output archive.\n\n" "Types must either have a serialize function, or separate save/load functions (but not both).\n" "Serialize functions generally have the following signature:\n\n" "template\n" @@ -491,8 +491,8 @@ namespace cereal //! Member serialization template inline - typename std::enable_if() || - (traits::is_input_serializable() && traits::has_member_serialize()), + typename std::enable_if::value || + (traits::is_input_serializable::value && traits::has_member_serialize::value), ArchiveType &>::type processImpl(T & t) { @@ -502,8 +502,8 @@ namespace cereal //! Non member serialization template inline - typename std::enable_if() || - (traits::is_input_serializable() && traits::has_non_member_serialize()), + typename std::enable_if::value || + (traits::is_input_serializable::value && traits::has_non_member_serialize::value), ArchiveType &>::type processImpl(T & t) { @@ -513,8 +513,8 @@ namespace cereal //! Member split (load) template inline - typename std::enable_if() || - (traits::is_input_serializable() && traits::has_member_load()), + typename std::enable_if::value || + (traits::is_input_serializable::value && traits::has_member_load::value), ArchiveType &>::type processImpl(T & t) { @@ -524,8 +524,8 @@ namespace cereal //! Non member split (load) template inline - typename std::enable_if() || - (traits::is_input_serializable() && traits::has_non_member_load()), + typename std::enable_if::value || + (traits::is_input_serializable::value && traits::has_non_member_load::value), ArchiveType &>::type processImpl(T & t) { @@ -536,7 +536,7 @@ namespace cereal //! Empty class specialization template inline typename std::enable_if<(Flags & AllowEmptyClassElision) && - !traits::is_input_serializable() && traits::is_empty_class(), ArchiveType &>::type + !traits::is_input_serializable::value && std::is_empty::value, ArchiveType &>::type processImpl(T const &) { return *self; @@ -544,12 +544,12 @@ namespace cereal //! No matching serialization template inline - typename std::enable_if() && !traits::is_input_serializable() && - (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !traits::is_empty_class())), + typename std::enable_if::value && !traits::is_input_serializable::value && + (!(Flags & AllowEmptyClassElision) || ((Flags & AllowEmptyClassElision) && !std::is_empty::value)), ArchiveType &>::type processImpl(T const &) { - static_assert(traits::is_output_serializable(), "Trying to serialize an unserializable type with an output archive.\n\n" + static_assert(traits::is_output_serializable::value, "Trying to serialize an unserializable type with an output archive.\n\n" "Types must either have a serialize function, or separate save/load functions (but not both).\n" "Serialize functions generally have the following signature:\n\n" "template\n" diff --git a/include/cereal/details/helpers.hpp b/include/cereal/details/helpers.hpp index 3ea233e2..06e8d157 100644 --- a/include/cereal/details/helpers.hpp +++ b/include/cereal/details/helpers.hpp @@ -122,10 +122,10 @@ namespace cereal private: // If we get passed an RValue, we'll just make a local copy if it here // otherwise, we store a reference - using DT = typename std::decay::type; - using Type = typename std::conditional::value, - DT, - typename std::add_lvalue_reference
::type>::type; + typedef typename std::decay::type DT; + typedef typename std::conditional::value, + DT, + typename std::add_lvalue_reference
::type>::type Type; // prevent nested nvps static_assert( !std::is_base_of::value, "Cannot pair a name to a NameValuePair" ); @@ -189,9 +189,9 @@ namespace cereal { //! Internally store the pointer as a void *, keeping const if created with //! a const pointer - using PT = typename std::conditional::type>::value, - const void *, - void *>::type; + typedef typename std::conditional::type>::value, + const void *, + void *>::type PT; BinaryData( T && d, uint64_t s ) : data(d), size(s) {} @@ -230,10 +230,10 @@ namespace cereal private: // If we get passed an RValue, we'll just make a local copy if it here // otherwise, we store a reference - using DT = typename std::decay::type; - using Type = typename std::conditional::value, - DT, - typename std::add_lvalue_reference
::type>::type; + typedef typename std::decay::type DT; + typedef typename std::conditional::value, + DT, + typename std::add_lvalue_reference
::type>::type Type; public: SizeTag( T && sz ) : size(const_cast(sz)) {} @@ -265,17 +265,17 @@ namespace cereal template struct MapItem { - using DecayKey = typename std::decay::type; - using KeyType = typename std::conditional< + typedef typename std::decay::type DecayKey; + typedef typename std::conditional< std::is_rvalue_reference::value, DecayKey, - typename std::add_lvalue_reference::type>::type; + typename std::add_lvalue_reference::type>::type KeyType; - using DecayValue = typename std::decay::type; - using ValueType = typename std::conditional< + typedef typename std::decay::type DecayValue; + typedef typename std::conditional< std::is_rvalue_reference::value, DecayValue, - typename std::add_lvalue_reference::type>::type; + typename std::add_lvalue_reference::type>::type ValueType; //! Construct a MapItem from a key and a value /*! @internal */ diff --git a/include/cereal/details/polymorphic_impl.hpp b/include/cereal/details/polymorphic_impl.hpp index 623db1cf..f47e5a49 100644 --- a/include/cereal/details/polymorphic_impl.hpp +++ b/include/cereal/details/polymorphic_impl.hpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include @@ -64,7 +65,7 @@ }; \ bind_to_archives const & init_binding::b = \ ::cereal::detail::StaticObject< \ - bind_to_archives \ + bind_to_archives \ >::getInstance().bind(); \ }} // end namespaces @@ -242,20 +243,20 @@ namespace cereal template struct create_bindings { - static const InputBindingCreator & - load(std::true_type) - { - return cereal::detail::StaticObject>::getInstance(); - } + static const InputBindingCreator & + load(std::true_type) + { + return cereal::detail::StaticObject>::getInstance(); + } - static const OutputBindingCreator & - save(std::true_type) - { - return cereal::detail::StaticObject>::getInstance(); - } + static const OutputBindingCreator & + save(std::true_type) + { + return cereal::detail::StaticObject>::getInstance(); + } - inline static void load(std::false_type) {} - inline static void save(std::false_type) {} + inline static void load(std::false_type) {} + inline static void save(std::false_type) {} }; //! When specialized, causes the compiler to instantiate its parameter @@ -270,20 +271,26 @@ namespace cereal template struct polymorphic_serialization_support { +#ifdef _MSC_VER + //! Creates the appropriate bindings depending on whether the archive supports + //! saving or loading + virtual void instantiate(); +#else // NOT _MSC_VER //! Creates the appropriate bindings depending on whether the archive supports //! saving or loading static void instantiate(); //! This typedef causes the compiler to instantiate this static function typedef instantiate_function unused; +#endif // _MSC_VER }; // instantiate implementation template void polymorphic_serialization_support::instantiate() { - create_bindings::save( std::is_base_of() ); + create_bindings::save( std::is_base_of() ); - create_bindings::load( std::is_base_of() ); + create_bindings::load( std::is_base_of() ); } //! Begins the binding process of a type to all registered archives @@ -296,8 +303,8 @@ namespace cereal { //! Binding for non abstract types void bind(std::false_type) const - { - instantiate_polymorphic_binding( (T*)0, 0, adl_tag{} ); + { + instantiate_polymorphic_binding((T*) 0, 0, adl_tag{}); } //! Binding for abstract types @@ -309,6 +316,8 @@ namespace cereal do not need to make a binding */ bind_to_archives const & bind() const { + static_assert( std::is_polymorphic::value, + "Attempting to register non polymorphic type" ); bind( std::is_abstract() ); return *this; } diff --git a/include/cereal/details/static_object.hpp b/include/cereal/details/static_object.hpp index 0aafd04f..d438eff8 100644 --- a/include/cereal/details/static_object.hpp +++ b/include/cereal/details/static_object.hpp @@ -30,6 +30,8 @@ #ifndef CEREAL_DETAILS_STATIC_OBJECT_HPP_ #define CEREAL_DETAILS_STATIC_OBJECT_HPP_ +#include + namespace cereal { namespace detail @@ -47,7 +49,7 @@ namespace cereal { private: //! Forces instantiation at pre-execution time - static void instantiate(T const &) {} + static void instantiate( T const & ) {} static T & create() { @@ -56,7 +58,7 @@ namespace cereal return t; } - StaticObject( StaticObject const & other ) = delete; + StaticObject( StaticObject const & other ) {} public: static T & getInstance() diff --git a/include/cereal/details/traits.hpp b/include/cereal/details/traits.hpp index f4890e42..f321176f 100644 --- a/include/cereal/details/traits.hpp +++ b/include/cereal/details/traits.hpp @@ -40,280 +40,263 @@ namespace cereal { namespace traits { - template struct Void { typedef void type; }; + typedef std::true_type yes; + typedef std::false_type no; + + //! Creates a test for whether a non const member function exists + /*! This creates a class derived from std::integral_constant that will be true if + the type has the proper member function for the given archive. */ + #define CEREAL_MAKE_HAS_MEMBER_TEST(name) \ + namespace detail \ + { \ + template \ + struct has_member_##name##_impl \ + { \ + template \ + static auto test(int) -> decltype( cereal::access::member_##name( std::declval(), std::declval() ), yes()); \ + template \ + static no test(...); \ + static const bool value = std::is_same(0)), yes>::value; \ + }; \ + } /* end namespace detail */ \ + template \ + struct has_member_##name : std::integral_constant::value> {}; + + //! Creates a test for whether a non const non-member function exists + /*! This creates a class derived from std::integral_constant that will be true if + the type has the proper non-member function for the given archive. */ + #define CEREAL_MAKE_HAS_NON_MEMBER_TEST(name) \ + namespace detail \ + { \ + template \ + struct has_non_member_##name##_impl \ + { \ + template \ + static auto test(int) -> decltype( name( std::declval(), std::declval() ), yes()); \ + template \ + static no test( ... ); \ + static const bool value = std::is_same( 0 ) ), yes>::value; \ + }; \ + } /* end namespace detail */ \ + template \ + struct has_non_member_##name : std::integral_constant::value> {}; // ###################################################################### // Member load_and_allocate template - bool constexpr has_member_load_and_allocate() - { return std::is_same( std::declval() ) ), T*>::value; } + struct has_member_load_and_allocate : + std::integral_constant( std::declval() ) ), T*>::value> {}; // ###################################################################### // Non Member load_and_allocate template - bool constexpr has_non_member_load_and_allocate() - { return std::is_same::load_and_allocate( std::declval() ) ), T*>::value; } + struct has_non_member_load_and_allocate : std::integral_constant::load_and_allocate( std::declval() ) ), T*>::value> {}; // ###################################################################### // Has either a member or non member allocate template - bool constexpr has_load_and_allocate() - { return has_member_load_and_allocate() || has_non_member_load_and_allocate(); } + struct has_load_and_allocate : std::integral_constant::value || has_non_member_load_and_allocate::value> + { }; // ###################################################################### // Member Serialize - template - struct has_member_serialize: std::false_type {}; - - template - struct has_member_serialize< T, A, - typename Void< - decltype( access::member_serialize(std::declval(), std::declval() ) ) - >::type - >: std::true_type {}; + CEREAL_MAKE_HAS_MEMBER_TEST(serialize); // ###################################################################### // Non Member Serialize - char & serialize(...); - template - bool constexpr has_non_member_serialize() - { return std::is_void(), std::declval()))>::value; }; + CEREAL_MAKE_HAS_NON_MEMBER_TEST(serialize); // ###################################################################### // Member Load - template - struct has_member_load: std::false_type {}; - - template - struct has_member_load< T, A, - typename Void< - decltype( access::member_load(std::declval(), std::declval() ) ) - >::type - >: std::true_type {}; + CEREAL_MAKE_HAS_MEMBER_TEST(load); // ###################################################################### // Non Member Load - char & load(...); - template - bool constexpr has_non_member_load() - { return std::is_void(), std::declval()))>::value; }; + CEREAL_MAKE_HAS_NON_MEMBER_TEST(load); // ###################################################################### // Member Save - template - struct has_member_save: std::false_type {}; + namespace detail + { + template + struct has_member_save_impl + { + template + static auto test(int) -> decltype( cereal::access::member_save( std::declval(), std::declval() ), yes()); + template + static no test(...); + static const bool value = std::is_same(0)), yes>::value; - template - struct has_member_save< T, A, - typename Void< - decltype( access::member_save(std::declval(), std::declval() ) ) - >::type - >: std::true_type {}; + template + static auto test2(int) -> decltype( cereal::access::member_save_non_const( std::declval(), std::declval::type&>() ), yes()); + template + static no test2(...); + static const bool not_const_type = std::is_same(0)), yes>::value; + }; + } // end namespace detail + + template + struct has_member_save : std::integral_constant::value> + { + typedef typename detail::has_member_save_impl check; + static_assert( check::value || !check::not_const_type, + "cereal detected a non-const save.\n" + "save member functions must always be const" ); + }; // ###################################################################### // Non-const Member Save namespace detail { - // Detection of any (const or non const) member save - template - struct has_member_save_any: std::false_type {}; + template + struct has_non_member_save_impl + { + template + static auto test(int) -> decltype( save( std::declval(), std::declval() ), yes()); + template + static no test(...); + static const bool value = std::is_same(0)), yes>::value; - template - struct has_member_save_any< T, A, - typename Void< - decltype( access::non_const_member_save(std::declval(), std::declval::type &>() ) ) - >::type - >: std::true_type {}; - } + template + static auto test2(int) -> decltype( save( std::declval(), std::declval::type&>() ), yes()); + template + static no test2(...); + static const bool not_const_type = std::is_same(0)), yes>::value; + }; + } // end namespace detail - // Returns true if we detect a member save function that is not const template - constexpr bool is_non_const_member_save() + struct has_non_member_save : std::integral_constant::value> { - return !has_member_save() && detail::has_member_save_any(); - } - - // ###################################################################### - // Non Member Save - char & save(...); - template - bool constexpr has_non_member_save() - { return std::is_void(), std::declval()))>::value; } - - // ###################################################################### - // Non-const Non member Save - namespace detail - { - template - bool constexpr has_non_member_save_any() - { return std::is_void(), std::declval::type &>()))>::value; } - } - - // Returns true if we detect a non-member save function that is not const - template - bool constexpr is_non_const_non_member_save() - { return !has_non_member_save() && detail::has_non_member_save_any(); } - - // ###################################################################### - // Returns true if we have an invalid save function (non const) - template - bool constexpr has_non_const_save() - { return is_non_const_member_save() || is_non_const_non_member_save(); } + typedef typename detail::has_non_member_save_impl check; + static_assert( check::value || !check::not_const_type, + "cereal detected a non-const type parameter in non-member save.\n" + "save non-member functions must always pass their types as const" ); + }; // ###################################################################### template - constexpr bool has_member_split() - { return has_member_load() && has_member_save(); } + struct has_member_split : std::integral_constant::value && has_member_save::value> {}; // ###################################################################### template - constexpr bool has_non_member_split() - { return has_non_member_load() && has_non_member_save(); } + struct has_non_member_split : std::integral_constant::value && has_non_member_save::value> {}; // ###################################################################### template - constexpr bool is_output_serializable() - { - static_assert( !has_non_const_save(), - "cereal detected a non const save. \n " - "save functions must either be const member functions or accept const type aguments if non-member" ); - - return - has_member_save() ^ - has_non_member_save() ^ - has_member_serialize() ^ - has_non_member_serialize(); - } + struct is_output_serializable : std::integral_constant::value ^ + has_non_member_save::value ^ + has_member_serialize::value ^ + has_non_member_serialize::value> {}; // ###################################################################### template - constexpr bool is_input_serializable() - { - return - has_member_load() ^ - has_non_member_load() ^ - has_member_serialize() ^ - has_non_member_serialize(); - } + struct is_input_serializable : std::integral_constant::value ^ + has_non_member_load::value ^ + has_member_serialize::value ^ + has_non_member_serialize::value> {}; // ###################################################################### - namespace detail { template - constexpr auto is_specialized_member_serialize() -> bool - { return !std::is_base_of>(); } + struct is_specialized_member_serialize : std::integral_constant>::value> {}; template - constexpr auto is_specialized_member_load_save() -> bool - { return !std::is_base_of>(); } + struct is_specialized_member_load_save : std::integral_constant>::value> {}; template - constexpr auto is_specialized_non_member_serialize() -> bool - { return !std::is_base_of>(); } + struct is_specialized_non_member_serialize : std::integral_constant>::value> {}; template - constexpr auto is_specialized_non_member_load_save() -> bool - { return !std::is_base_of>(); } + struct is_specialized_non_member_load_save : std::integral_constant>::value> {}; // Considered an error if specialization exists for more than one type template - constexpr auto is_specialized_error() -> bool - { - return (is_specialized_member_serialize() + - is_specialized_member_load_save() + - is_specialized_non_member_serialize() + - is_specialized_non_member_load_save()) <= 1; - } + struct is_specialized_error : std::integral_constant::value + + is_specialized_member_load_save::value + + is_specialized_non_member_serialize::value + + is_specialized_non_member_load_save::value) <= 1> {}; } // namespace detail template - constexpr auto is_specialized() -> bool + struct is_specialized : std::integral_constant::value || + detail::is_specialized_member_load_save::value || + detail::is_specialized_non_member_serialize::value || + detail::is_specialized_non_member_load_save::value> { - static_assert(detail::is_specialized_error(), "More than one explicit specialization detected for type."); - return detail::is_specialized_member_serialize() || - detail::is_specialized_member_load_save() || - detail::is_specialized_non_member_serialize() || - detail::is_specialized_non_member_load_save(); - } + static_assert(detail::is_specialized_error::value, "More than one explicit specialization detected for type."); + }; template - constexpr auto is_specialized_member_serialize() -> bool + struct is_specialized_member_serialize : std::integral_constant::value && detail::is_specialized_member_serialize::value> { - static_assert( (is_specialized() && detail::is_specialized_member_serialize() && has_member_serialize()) - || !(is_specialized() && detail::is_specialized_member_serialize()), + static_assert( (is_specialized::value && detail::is_specialized_member_serialize::value && has_member_serialize::value) + || !(is_specialized::value && detail::is_specialized_member_serialize::value), "cereal detected member serialization specialization but no member serialize function" ); - return is_specialized() && detail::is_specialized_member_serialize(); - } + }; template - constexpr auto is_specialized_member_load() -> bool + struct is_specialized_member_load : std::integral_constant::value && detail::is_specialized_member_load_save::value> { - static_assert( (is_specialized() && detail::is_specialized_member_load_save() && has_member_load()) - || !(is_specialized() && detail::is_specialized_member_load_save()), + static_assert( (is_specialized::value && detail::is_specialized_member_load_save::value && has_member_load::value) + || !(is_specialized::value && detail::is_specialized_member_load_save::value), "cereal detected member load specialization but no member load function" ); - return is_specialized() && detail::is_specialized_member_load_save(); - } + }; template - constexpr auto is_specialized_member_save() -> bool + struct is_specialized_member_save : std::integral_constant::value && detail::is_specialized_member_load_save::value> { - static_assert( (is_specialized() && detail::is_specialized_member_load_save() && has_member_save()) - || !(is_specialized() && detail::is_specialized_member_load_save()), + static_assert( (is_specialized::value && detail::is_specialized_member_load_save::value && has_member_save::value) + || !(is_specialized::value && detail::is_specialized_member_load_save::value), "cereal detected member save specialization but no member save function" ); - return is_specialized() && detail::is_specialized_member_load_save(); - } + }; template - constexpr auto is_specialized_non_member_serialize() -> bool + struct is_specialized_non_member_serialize : std::integral_constant::value && detail::is_specialized_non_member_serialize::value> { - static_assert( (is_specialized() && detail::is_specialized_non_member_serialize() && has_non_member_serialize()) - || !(is_specialized() && detail::is_specialized_non_member_serialize()), + static_assert( (is_specialized::value && detail::is_specialized_non_member_serialize::value && has_non_member_serialize::value) + || !(is_specialized::value && detail::is_specialized_non_member_serialize::value), "cereal detected non-member serialization specialization but no non-member serialize function" ); - return is_specialized() && detail::is_specialized_non_member_serialize(); - } + }; template - constexpr auto is_specialized_non_member_load() -> bool + struct is_specialized_non_member_load : std::integral_constant::value && detail::is_specialized_non_member_load_save::value> { - static_assert( (is_specialized() && detail::is_specialized_non_member_load_save() && has_non_member_load()) - || !(is_specialized() && detail::is_specialized_non_member_load_save()), + static_assert( (is_specialized::value && detail::is_specialized_non_member_load_save::value && has_non_member_load::value) + || !(is_specialized::value && detail::is_specialized_non_member_load_save::value), "cereal detected non-member load specialization but no non-member load function" ); - return is_specialized() && detail::is_specialized_non_member_load_save(); - } + }; template - constexpr auto is_specialized_non_member_save() -> bool + struct is_specialized_non_member_save : std::integral_constant::value && detail::is_specialized_non_member_load_save::value> { - static_assert( (is_specialized() && detail::is_specialized_non_member_load_save() && has_non_member_save()) - || !(is_specialized() && detail::is_specialized_non_member_load_save()), + static_assert( (is_specialized::value && detail::is_specialized_non_member_load_save::value && has_non_member_save::value) + || !(is_specialized::value && detail::is_specialized_non_member_load_save::value), "cereal detected non-member save specialization but no non-member save function" ); - return is_specialized() && detail::is_specialized_non_member_load_save(); - } - - // ###################################################################### - template - constexpr size_t sizeof_array( size_t rank = std::rank::value ) - { - return rank == 0 ? 1 : std::extent::value * sizeof_array::type>( rank - 1 ); - } + }; // ###################################################################### namespace detail { - template - struct is_empty_class_impl - { static constexpr bool value = false; }; - - template - struct is_empty_class_impl::value>::type> - { - struct S : T - { uint8_t t; }; - - static constexpr bool value = sizeof(S) == sizeof(uint8_t); - }; - struct base_class_id { template @@ -331,10 +314,8 @@ namespace cereal size_t hash; }; struct base_class_id_hash { size_t operator()(base_class_id const & id) const { return id.hash; } }; - } + } // namespace detail - template - using is_empty_class = std::integral_constant::value>; // ###################################################################### //! A macro to use to restrict which types of archives your function will work for. @@ -361,9 +342,10 @@ namespace cereal typename std::enable_if::value || std::is_same::value, void>::type } // namespace traits + // ###################################################################### namespace detail { - template (), bool NonMember = traits::has_non_member_load_and_allocate()> + template ::value, bool NonMember = traits::has_non_member_load_and_allocate::value> struct Load { static_assert( !sizeof(T), "Cereal detected both member and non member load_and_allocate functions!" ); diff --git a/include/cereal/details/util.hpp b/include/cereal/details/util.hpp index e0b39ae9..fc4b4787 100644 --- a/include/cereal/details/util.hpp +++ b/include/cereal/details/util.hpp @@ -31,9 +31,31 @@ #define CEREAL_DETAILS_UTIL_HPP_ #include -#include #include +#ifdef _MSC_VER +namespace cereal +{ + namespace util + { + //! Demangles the type encoded in a string + /*! @internal */ + inline std::string demangle( std::string const & name ) + { + return name; + } + + //! Gets the demangled name of a type + /*! @internal */ + template inline + std::string demangledName() + { + return typeid( T ).name(); + } + } // namespace util +} // namespace cereal +#else // clang or gcc +#include namespace cereal { namespace util @@ -60,6 +82,9 @@ namespace cereal std::string demangledName() { return demangle(typeid(T).name()); } } -} +} // namespace cereal +#endif + + #endif // CEREAL_DETAILS_UTIL_HPP_ diff --git a/include/cereal/external/base64.hpp b/include/cereal/external/base64.hpp index 01a2c140..dcc3f71a 100644 --- a/include/cereal/external/base64.hpp +++ b/include/cereal/external/base64.hpp @@ -39,7 +39,7 @@ namespace base64 return (isalnum(c) || (c == '+') || (c == '/')); } - inline std::string encode(unsigned char const* bytes_to_encode, unsigned int in_len) { + inline std::string encode(unsigned char const* bytes_to_encode, size_t in_len) { std::string ret; int i = 0; int j = 0; @@ -49,10 +49,10 @@ namespace base64 while (in_len--) { char_array_3[i++] = *(bytes_to_encode++); if (i == 3) { - char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; - char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); - char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); - char_array_4[3] = char_array_3[2] & 0x3f; + char_array_4[0] = (unsigned char) ((char_array_3[0] & 0xfc) >> 2); + char_array_4[1] = (unsigned char) ( ( ( char_array_3[0] & 0x03 ) << 4 ) + ( ( char_array_3[1] & 0xf0 ) >> 4 ) ); + char_array_4[2] = (unsigned char) ( ( ( char_array_3[1] & 0x0f ) << 2 ) + ( ( char_array_3[2] & 0xc0 ) >> 6 ) ); + char_array_4[3] = (unsigned char) ( char_array_3[2] & 0x3f ); for(i = 0; (i <4) ; i++) ret += chars[char_array_4[i]]; @@ -83,9 +83,9 @@ namespace base64 } inline std::string decode(std::string const& encoded_string) { - int in_len = encoded_string.size(); - int i = 0; - int j = 0; + size_t in_len = encoded_string.size(); + size_t i = 0; + size_t j = 0; int in_ = 0; unsigned char char_array_4[4], char_array_3[3]; std::string ret; @@ -94,7 +94,7 @@ namespace base64 char_array_4[i++] = encoded_string[in_]; in_++; if (i ==4) { for (i = 0; i <4; i++) - char_array_4[i] = chars.find(char_array_4[i]); + char_array_4[i] = (unsigned char) chars.find( char_array_4[i] ); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); @@ -111,7 +111,7 @@ namespace base64 char_array_4[j] = 0; for (j = 0; j <4; j++) - char_array_4[j] = chars.find(char_array_4[j]); + char_array_4[j] = (unsigned char) chars.find( char_array_4[j] ); char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); diff --git a/include/cereal/external/rapidjson/internal/pow10.h b/include/cereal/external/rapidjson/internal/pow10.h index 0852539e..bf3a9afb 100644 --- a/include/cereal/external/rapidjson/internal/pow10.h +++ b/include/cereal/external/rapidjson/internal/pow10.h @@ -1,54 +1,54 @@ -#ifndef RAPIDJSON_POW10_ -#define RAPIDJSON_POW10_ - -namespace rapidjson { -namespace internal { - -//! Computes integer powers of 10 in double (10.0^n). -/*! This function uses lookup table for fast and accurate results. - \param n positive/negative exponent. Must <= 308. - \return 10.0^n -*/ -inline double Pow10(int n) { - static const double e[] = { // 1e-308...1e308: 617 * 8 bytes = 4936 bytes - 1e-308,1e-307,1e-306,1e-305,1e-304,1e-303,1e-302,1e-301,1e-300, - 1e-299,1e-298,1e-297,1e-296,1e-295,1e-294,1e-293,1e-292,1e-291,1e-290,1e-289,1e-288,1e-287,1e-286,1e-285,1e-284,1e-283,1e-282,1e-281,1e-280, - 1e-279,1e-278,1e-277,1e-276,1e-275,1e-274,1e-273,1e-272,1e-271,1e-270,1e-269,1e-268,1e-267,1e-266,1e-265,1e-264,1e-263,1e-262,1e-261,1e-260, - 1e-259,1e-258,1e-257,1e-256,1e-255,1e-254,1e-253,1e-252,1e-251,1e-250,1e-249,1e-248,1e-247,1e-246,1e-245,1e-244,1e-243,1e-242,1e-241,1e-240, - 1e-239,1e-238,1e-237,1e-236,1e-235,1e-234,1e-233,1e-232,1e-231,1e-230,1e-229,1e-228,1e-227,1e-226,1e-225,1e-224,1e-223,1e-222,1e-221,1e-220, - 1e-219,1e-218,1e-217,1e-216,1e-215,1e-214,1e-213,1e-212,1e-211,1e-210,1e-209,1e-208,1e-207,1e-206,1e-205,1e-204,1e-203,1e-202,1e-201,1e-200, - 1e-199,1e-198,1e-197,1e-196,1e-195,1e-194,1e-193,1e-192,1e-191,1e-190,1e-189,1e-188,1e-187,1e-186,1e-185,1e-184,1e-183,1e-182,1e-181,1e-180, - 1e-179,1e-178,1e-177,1e-176,1e-175,1e-174,1e-173,1e-172,1e-171,1e-170,1e-169,1e-168,1e-167,1e-166,1e-165,1e-164,1e-163,1e-162,1e-161,1e-160, - 1e-159,1e-158,1e-157,1e-156,1e-155,1e-154,1e-153,1e-152,1e-151,1e-150,1e-149,1e-148,1e-147,1e-146,1e-145,1e-144,1e-143,1e-142,1e-141,1e-140, - 1e-139,1e-138,1e-137,1e-136,1e-135,1e-134,1e-133,1e-132,1e-131,1e-130,1e-129,1e-128,1e-127,1e-126,1e-125,1e-124,1e-123,1e-122,1e-121,1e-120, - 1e-119,1e-118,1e-117,1e-116,1e-115,1e-114,1e-113,1e-112,1e-111,1e-110,1e-109,1e-108,1e-107,1e-106,1e-105,1e-104,1e-103,1e-102,1e-101,1e-100, - 1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80, - 1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, - 1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, - 1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, - 1e-19, 1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e+0, - 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, - 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, - 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, - 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, - 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, - 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, - 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, - 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, - 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, - 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, - 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, - 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, - 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, - 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, - 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, - 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 - }; - RAPIDJSON_ASSERT(n <= 308); - return n < -308 ? 0.0 : e[n + 308]; -} - -} // namespace internal -} // namespace rapidjson - -#endif // RAPIDJSON_POW10_ +#ifndef RAPIDJSON_POW10_ +#define RAPIDJSON_POW10_ + +namespace rapidjson { +namespace internal { + +//! Computes integer powers of 10 in double (10.0^n). +/*! This function uses lookup table for fast and accurate results. + \param n positive/negative exponent. Must <= 308. + \return 10.0^n +*/ +inline double Pow10(int n) { + static const double e[] = { // 1e-308...1e308: 617 * 8 bytes = 4936 bytes + 1e-308,1e-307,1e-306,1e-305,1e-304,1e-303,1e-302,1e-301,1e-300, + 1e-299,1e-298,1e-297,1e-296,1e-295,1e-294,1e-293,1e-292,1e-291,1e-290,1e-289,1e-288,1e-287,1e-286,1e-285,1e-284,1e-283,1e-282,1e-281,1e-280, + 1e-279,1e-278,1e-277,1e-276,1e-275,1e-274,1e-273,1e-272,1e-271,1e-270,1e-269,1e-268,1e-267,1e-266,1e-265,1e-264,1e-263,1e-262,1e-261,1e-260, + 1e-259,1e-258,1e-257,1e-256,1e-255,1e-254,1e-253,1e-252,1e-251,1e-250,1e-249,1e-248,1e-247,1e-246,1e-245,1e-244,1e-243,1e-242,1e-241,1e-240, + 1e-239,1e-238,1e-237,1e-236,1e-235,1e-234,1e-233,1e-232,1e-231,1e-230,1e-229,1e-228,1e-227,1e-226,1e-225,1e-224,1e-223,1e-222,1e-221,1e-220, + 1e-219,1e-218,1e-217,1e-216,1e-215,1e-214,1e-213,1e-212,1e-211,1e-210,1e-209,1e-208,1e-207,1e-206,1e-205,1e-204,1e-203,1e-202,1e-201,1e-200, + 1e-199,1e-198,1e-197,1e-196,1e-195,1e-194,1e-193,1e-192,1e-191,1e-190,1e-189,1e-188,1e-187,1e-186,1e-185,1e-184,1e-183,1e-182,1e-181,1e-180, + 1e-179,1e-178,1e-177,1e-176,1e-175,1e-174,1e-173,1e-172,1e-171,1e-170,1e-169,1e-168,1e-167,1e-166,1e-165,1e-164,1e-163,1e-162,1e-161,1e-160, + 1e-159,1e-158,1e-157,1e-156,1e-155,1e-154,1e-153,1e-152,1e-151,1e-150,1e-149,1e-148,1e-147,1e-146,1e-145,1e-144,1e-143,1e-142,1e-141,1e-140, + 1e-139,1e-138,1e-137,1e-136,1e-135,1e-134,1e-133,1e-132,1e-131,1e-130,1e-129,1e-128,1e-127,1e-126,1e-125,1e-124,1e-123,1e-122,1e-121,1e-120, + 1e-119,1e-118,1e-117,1e-116,1e-115,1e-114,1e-113,1e-112,1e-111,1e-110,1e-109,1e-108,1e-107,1e-106,1e-105,1e-104,1e-103,1e-102,1e-101,1e-100, + 1e-99, 1e-98, 1e-97, 1e-96, 1e-95, 1e-94, 1e-93, 1e-92, 1e-91, 1e-90, 1e-89, 1e-88, 1e-87, 1e-86, 1e-85, 1e-84, 1e-83, 1e-82, 1e-81, 1e-80, + 1e-79, 1e-78, 1e-77, 1e-76, 1e-75, 1e-74, 1e-73, 1e-72, 1e-71, 1e-70, 1e-69, 1e-68, 1e-67, 1e-66, 1e-65, 1e-64, 1e-63, 1e-62, 1e-61, 1e-60, + 1e-59, 1e-58, 1e-57, 1e-56, 1e-55, 1e-54, 1e-53, 1e-52, 1e-51, 1e-50, 1e-49, 1e-48, 1e-47, 1e-46, 1e-45, 1e-44, 1e-43, 1e-42, 1e-41, 1e-40, + 1e-39, 1e-38, 1e-37, 1e-36, 1e-35, 1e-34, 1e-33, 1e-32, 1e-31, 1e-30, 1e-29, 1e-28, 1e-27, 1e-26, 1e-25, 1e-24, 1e-23, 1e-22, 1e-21, 1e-20, + 1e-19, 1e-18, 1e-17, 1e-16, 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10, 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1, 1e+0, + 1e+1, 1e+2, 1e+3, 1e+4, 1e+5, 1e+6, 1e+7, 1e+8, 1e+9, 1e+10, 1e+11, 1e+12, 1e+13, 1e+14, 1e+15, 1e+16, 1e+17, 1e+18, 1e+19, 1e+20, + 1e+21, 1e+22, 1e+23, 1e+24, 1e+25, 1e+26, 1e+27, 1e+28, 1e+29, 1e+30, 1e+31, 1e+32, 1e+33, 1e+34, 1e+35, 1e+36, 1e+37, 1e+38, 1e+39, 1e+40, + 1e+41, 1e+42, 1e+43, 1e+44, 1e+45, 1e+46, 1e+47, 1e+48, 1e+49, 1e+50, 1e+51, 1e+52, 1e+53, 1e+54, 1e+55, 1e+56, 1e+57, 1e+58, 1e+59, 1e+60, + 1e+61, 1e+62, 1e+63, 1e+64, 1e+65, 1e+66, 1e+67, 1e+68, 1e+69, 1e+70, 1e+71, 1e+72, 1e+73, 1e+74, 1e+75, 1e+76, 1e+77, 1e+78, 1e+79, 1e+80, + 1e+81, 1e+82, 1e+83, 1e+84, 1e+85, 1e+86, 1e+87, 1e+88, 1e+89, 1e+90, 1e+91, 1e+92, 1e+93, 1e+94, 1e+95, 1e+96, 1e+97, 1e+98, 1e+99, 1e+100, + 1e+101,1e+102,1e+103,1e+104,1e+105,1e+106,1e+107,1e+108,1e+109,1e+110,1e+111,1e+112,1e+113,1e+114,1e+115,1e+116,1e+117,1e+118,1e+119,1e+120, + 1e+121,1e+122,1e+123,1e+124,1e+125,1e+126,1e+127,1e+128,1e+129,1e+130,1e+131,1e+132,1e+133,1e+134,1e+135,1e+136,1e+137,1e+138,1e+139,1e+140, + 1e+141,1e+142,1e+143,1e+144,1e+145,1e+146,1e+147,1e+148,1e+149,1e+150,1e+151,1e+152,1e+153,1e+154,1e+155,1e+156,1e+157,1e+158,1e+159,1e+160, + 1e+161,1e+162,1e+163,1e+164,1e+165,1e+166,1e+167,1e+168,1e+169,1e+170,1e+171,1e+172,1e+173,1e+174,1e+175,1e+176,1e+177,1e+178,1e+179,1e+180, + 1e+181,1e+182,1e+183,1e+184,1e+185,1e+186,1e+187,1e+188,1e+189,1e+190,1e+191,1e+192,1e+193,1e+194,1e+195,1e+196,1e+197,1e+198,1e+199,1e+200, + 1e+201,1e+202,1e+203,1e+204,1e+205,1e+206,1e+207,1e+208,1e+209,1e+210,1e+211,1e+212,1e+213,1e+214,1e+215,1e+216,1e+217,1e+218,1e+219,1e+220, + 1e+221,1e+222,1e+223,1e+224,1e+225,1e+226,1e+227,1e+228,1e+229,1e+230,1e+231,1e+232,1e+233,1e+234,1e+235,1e+236,1e+237,1e+238,1e+239,1e+240, + 1e+241,1e+242,1e+243,1e+244,1e+245,1e+246,1e+247,1e+248,1e+249,1e+250,1e+251,1e+252,1e+253,1e+254,1e+255,1e+256,1e+257,1e+258,1e+259,1e+260, + 1e+261,1e+262,1e+263,1e+264,1e+265,1e+266,1e+267,1e+268,1e+269,1e+270,1e+271,1e+272,1e+273,1e+274,1e+275,1e+276,1e+277,1e+278,1e+279,1e+280, + 1e+281,1e+282,1e+283,1e+284,1e+285,1e+286,1e+287,1e+288,1e+289,1e+290,1e+291,1e+292,1e+293,1e+294,1e+295,1e+296,1e+297,1e+298,1e+299,1e+300, + 1e+301,1e+302,1e+303,1e+304,1e+305,1e+306,1e+307,1e+308 + }; + RAPIDJSON_ASSERT(n <= 308); + return n < -308 ? 0.0 : e[n + 308]; +} + +} // namespace internal +} // namespace rapidjson + +#endif // RAPIDJSON_POW10_ diff --git a/include/cereal/external/rapidjson/reader.h b/include/cereal/external/rapidjson/reader.h index 748e1207..a093dd61 100644 --- a/include/cereal/external/rapidjson/reader.h +++ b/include/cereal/external/rapidjson/reader.h @@ -382,15 +382,35 @@ private: return codepoint; } + // cereal Temporary until constexpr support is added in RTM +#ifdef _MSC_VER + template + bool characterOk( Ch c ) + { + return c < 256; + } + + template <> + bool characterOk( Ch ) + { + return true; + } + +#else template - typename std::enable_if::max() < 265, bool>::type - characterOk(Ch c) - { return true; } + typename std::enable_if < std::numeric_limits::max() < 265, bool>::type + characterOk( Ch c ) + { + return true; + } template - typename std::enable_if::max() >= 265, bool>::type - characterOk(Ch c) - { return c < 256; } + typename std::enable_if::max() >= 265, bool>::type + characterOk( Ch c ) + { + return c < 256; + } +#endif // Parse string, handling the prefix and suffix double quotes and escaping. template diff --git a/include/cereal/external/rapidjson/writer.h b/include/cereal/external/rapidjson/writer.h index 47744ebe..17a89c90 100644 --- a/include/cereal/external/rapidjson/writer.h +++ b/include/cereal/external/rapidjson/writer.h @@ -1,302 +1,326 @@ -#ifndef RAPIDJSON_WRITER_H_ -#define RAPIDJSON_WRITER_H_ - -#include "rapidjson.h" -#include "internal/stack.h" -#include "internal/strfunc.h" -#include // snprintf() or _sprintf_s() -#include // placement new -#include - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4127) // conditional expression is constant -#endif - -namespace rapidjson { - -//! JSON writer -/*! Writer implements the concept Handler. - It generates JSON text by events to an output stream. - - User may programmatically calls the functions of a writer to generate JSON text. - - On the other side, a writer can also be passed to objects that generates events, - - for example Reader::Parse() and Document::Accept(). - - \tparam Stream Type of ouptut stream. - \tparam Encoding Encoding of both source strings and output. - \implements Handler -*/ -template, typename Allocator = MemoryPoolAllocator<> > -class Writer { -public: - typedef typename Encoding::Ch Ch; - - Writer(Stream& stream, int precision = 20, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : - stream_(stream), level_stack_(allocator, levelDepth * sizeof(Level)) - { - (void) snprintf(double_format, sizeof(double_format), "%%0.%dg", precision); - (void) snprintf(long_double_format, sizeof(long_double_format), "%%0.%dLg", precision); - } - -protected: - char double_format[32]; - char long_double_format[32]; -public: - - //@name Implementation of Handler - //@{ - - Writer& Null() { Prefix(kNullType); WriteNull(); return *this; } - Writer& Bool(bool b) { Prefix(b ? kTrueType : kFalseType); WriteBool(b); return *this; } - Writer& Int(int i) { Prefix(kNumberType); WriteInt(i); return *this; } - Writer& Uint(unsigned u) { Prefix(kNumberType); WriteUint(u); return *this; } - Writer& Int64(int64_t i64) { Prefix(kNumberType); WriteInt64(i64); return *this; } - Writer& Uint64(uint64_t u64) { Prefix(kNumberType); WriteUint64(u64); return *this; } - Writer& Double(double d) { Prefix(kNumberType); WriteDouble(d); return *this; } - Writer& LongDouble(long double d) { Prefix(kNumberType); WriteLongDouble(d); return *this; } - Writer& LongLong(long long d) { Prefix(kNumberType); WriteLongLong(d); return *this; } - Writer& ULongLong(unsigned long long d) { Prefix(kNumberType); WriteULongLong(d); return *this; } - - Writer& String(const Ch* str, SizeType length, bool copy = false) { - (void)copy; - Prefix(kStringType); - WriteString(str, length); - return *this; - } - - Writer& StartObject() { - Prefix(kObjectType); - new (level_stack_.template Push()) Level(false); - WriteStartObject(); - return *this; - } - - Writer& EndObject(SizeType memberCount = 0) { - (void)memberCount; - RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); - RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); - level_stack_.template Pop(1); - WriteEndObject(); - return *this; - } - - Writer& StartArray() { - Prefix(kArrayType); - new (level_stack_.template Push()) Level(true); - WriteStartArray(); - return *this; - } - - Writer& EndArray(SizeType elementCount = 0) { - (void)elementCount; - RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); - RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); - level_stack_.template Pop(1); - WriteEndArray(); - return *this; - } - //@} - - //! Simpler but slower overload. - Writer& String(const Ch* str) { return String(str, internal::StrLen(str)); } - -protected: - //! Information for each nested level - struct Level { - Level(bool inArray_) : inArray(inArray_), valueCount(0) {} - bool inArray; //!< true if in array, otherwise in object - size_t valueCount; //!< number of values in this level - }; - - static const size_t kDefaultLevelDepth = 32; - - void WriteNull() { - stream_.Put('n'); stream_.Put('u'); stream_.Put('l'); stream_.Put('l'); - } - - void WriteBool(bool b) { - if (b) { - stream_.Put('t'); stream_.Put('r'); stream_.Put('u'); stream_.Put('e'); - } - else { - stream_.Put('f'); stream_.Put('a'); stream_.Put('l'); stream_.Put('s'); stream_.Put('e'); - } - } - - void WriteInt(int i) { - if (i < 0) { - stream_.Put('-'); - i = -i; - } - WriteUint((unsigned)i); - } - - void WriteUint(unsigned u) { - char buffer[10]; - char *p = buffer; - do { - *p++ = (u % 10) + '0'; - u /= 10; - } while (u > 0); - - do { - --p; - stream_.Put(*p); - } while (p != buffer); - } - - void WriteInt64(int64_t i64) { - if (i64 < 0) { - stream_.Put('-'); - i64 = -i64; - } - WriteUint64((uint64_t)i64); - } - - void WriteUint64(uint64_t u64) { - char buffer[20]; - char *p = buffer; - do { - *p++ = char(u64 % 10) + '0'; - u64 /= 10; - } while (u64 > 0); - - do { - --p; - stream_.Put(*p); - } while (p != buffer); - } - - template - typename std::enable_if::max() < 265, bool>::type - characterOk(Ch c) - { return true; } - - template - typename std::enable_if::max() >= 265, bool>::type - characterOk(Ch c) - { return c < 256; } - - //! \todo Optimization with custom double-to-string converter. - void WriteDouble(double d) { - char buffer[100]; -#if _MSC_VER - int ret = sprintf_s(buffer, sizeof(buffer), double_format, d); -#else - int ret = snprintf(buffer, sizeof(buffer), double_format, d); -#endif - RAPIDJSON_ASSERT(ret >= 1); - for (int i = 0; i < ret; i++) - stream_.Put(buffer[i]); - } - - void WriteLongDouble(long double d) { - char buffer[256]; -#if _MSC_VER - int ret = sprintf_s(buffer, sizeof(buffer), long_double_format, d); -#else - int ret = snprintf(buffer, sizeof(buffer), long_double_format, d); -#endif - RAPIDJSON_ASSERT(ret >= 1); - for (int i = 0; i < ret; i++) - stream_.Put(buffer[i]); - } - - void WriteLongLong(long long d) { - char buffer[256]; -#if _MSC_VER - int ret = sprintf_s(buffer, sizeof(buffer), "%lld", d); -#else - int ret = snprintf(buffer, sizeof(buffer), "%lld", d); -#endif - RAPIDJSON_ASSERT(ret >= 1); - for (int i = 0; i < ret; i++) - stream_.Put(buffer[i]); - } - - void WriteULongLong(unsigned long long d) { - char buffer[256]; -#if _MSC_VER - int ret = sprintf_s(buffer, sizeof(buffer), "%llu", d); -#else - int ret = snprintf(buffer, sizeof(buffer), "%llu", d); -#endif - RAPIDJSON_ASSERT(ret >= 1); - for (int i = 0; i < ret; i++) - stream_.Put(buffer[i]); - } - - void WriteString(const Ch* str, SizeType length) { - static const char hexDigits[] = "0123456789ABCDEF"; - static const char escape[256] = { -#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - //0 1 2 3 4 5 6 7 8 9 A B C D E F - 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 - 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 - 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 - Z16, Z16, // 30~4F - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 - Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF -#undef Z16 - }; - - stream_.Put('\"'); - for (const Ch* p = str; p != str + length; ++p) { - if ((sizeof(Ch) == 1 || characterOk(*p)) && escape[(unsigned char)*p]) { - //if ((sizeof(Ch) == 1 || *p < 256) && escape[(unsigned char)*p]) { - stream_.Put('\\'); - stream_.Put(escape[(unsigned char)*p]); - if (escape[(unsigned char)*p] == 'u') { - stream_.Put('0'); - stream_.Put('0'); - stream_.Put(hexDigits[(*p) >> 4]); - stream_.Put(hexDigits[(*p) & 0xF]); - } - } - else - stream_.Put(*p); - } - stream_.Put('\"'); - } - - void WriteStartObject() { stream_.Put('{'); } - void WriteEndObject() { stream_.Put('}'); } - void WriteStartArray() { stream_.Put('['); } - void WriteEndArray() { stream_.Put(']'); } - - void Prefix(Type type) { - (void)type; - if (level_stack_.GetSize() != 0) { // this value is not at root - Level* level = level_stack_.template Top(); - if (level->valueCount > 0) { - if (level->inArray) - stream_.Put(','); // add comma if it is not the first element in array - else // in object - stream_.Put((level->valueCount % 2 == 0) ? ',' : ':'); - } - if (!level->inArray && level->valueCount % 2 == 0) - RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name - level->valueCount++; - } - else - RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType); - } - - Stream& stream_; - internal::Stack level_stack_; - -private: - // Prohibit assignment for VC C4512 warning - Writer& operator=(const Writer& w); -}; - -} // namespace rapidjson - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -#endif // RAPIDJSON_RAPIDJSON_H_ +#ifndef RAPIDJSON_WRITER_H_ +#define RAPIDJSON_WRITER_H_ + +#include "rapidjson.h" +#include "internal/stack.h" +#include "internal/strfunc.h" +#include // snprintf() or _sprintf_s() +#include // placement new +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4127) // conditional expression is constant +#endif + +namespace rapidjson { + +//! JSON writer +/*! Writer implements the concept Handler. + It generates JSON text by events to an output stream. + + User may programmatically calls the functions of a writer to generate JSON text. + + On the other side, a writer can also be passed to objects that generates events, + + for example Reader::Parse() and Document::Accept(). + + \tparam Stream Type of ouptut stream. + \tparam Encoding Encoding of both source strings and output. + \implements Handler +*/ +template, typename Allocator = MemoryPoolAllocator<> > +class Writer { +public: + typedef typename Encoding::Ch Ch; + + Writer(Stream& stream, int precision = 20, Allocator* allocator = 0, size_t levelDepth = kDefaultLevelDepth) : + stream_(stream), level_stack_(allocator, levelDepth * sizeof(Level)) + { +#if _MSC_VER + (void) sprintf_s(double_format, sizeof(double_format), "%%0.%dg", precision); + (void) sprintf_s( long_double_format, sizeof( long_double_format ), "%%0.%dLg", precision ); +#else + (void) snprintf(double_format, sizeof(double_format), "%%0.%dg", precision); + (void) snprintf( long_double_format, sizeof( long_double_format ), "%%0.%dLg", precision ); +#endif + + } + +protected: + char double_format[32]; + char long_double_format[32]; +public: + + //@name Implementation of Handler + //@{ + + Writer& Null() { Prefix(kNullType); WriteNull(); return *this; } + Writer& Bool(bool b) { Prefix(b ? kTrueType : kFalseType); WriteBool(b); return *this; } + Writer& Int(int i) { Prefix(kNumberType); WriteInt(i); return *this; } + Writer& Uint(unsigned u) { Prefix(kNumberType); WriteUint(u); return *this; } + Writer& Int64(int64_t i64) { Prefix(kNumberType); WriteInt64(i64); return *this; } + Writer& Uint64(uint64_t u64) { Prefix(kNumberType); WriteUint64(u64); return *this; } + Writer& Double(double d) { Prefix(kNumberType); WriteDouble(d); return *this; } + Writer& LongDouble(long double d) { Prefix(kNumberType); WriteLongDouble(d); return *this; } + Writer& LongLong(long long d) { Prefix(kNumberType); WriteLongLong(d); return *this; } + Writer& ULongLong(unsigned long long d) { Prefix(kNumberType); WriteULongLong(d); return *this; } + + Writer& String(const Ch* str, SizeType length, bool copy = false) { + (void)copy; + Prefix(kStringType); + WriteString(str, length); + return *this; + } + + Writer& StartObject() { + Prefix(kObjectType); + new (level_stack_.template Push()) Level(false); + WriteStartObject(); + return *this; + } + + Writer& EndObject(SizeType memberCount = 0) { + (void)memberCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(!level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + WriteEndObject(); + return *this; + } + + Writer& StartArray() { + Prefix(kArrayType); + new (level_stack_.template Push()) Level(true); + WriteStartArray(); + return *this; + } + + Writer& EndArray(SizeType elementCount = 0) { + (void)elementCount; + RAPIDJSON_ASSERT(level_stack_.GetSize() >= sizeof(Level)); + RAPIDJSON_ASSERT(level_stack_.template Top()->inArray); + level_stack_.template Pop(1); + WriteEndArray(); + return *this; + } + //@} + + //! Simpler but slower overload. + Writer& String(const Ch* str) { return String(str, internal::StrLen(str)); } + +protected: + //! Information for each nested level + struct Level { + Level(bool inArray_) : inArray(inArray_), valueCount(0) {} + bool inArray; //!< true if in array, otherwise in object + size_t valueCount; //!< number of values in this level + }; + + static const size_t kDefaultLevelDepth = 32; + + void WriteNull() { + stream_.Put('n'); stream_.Put('u'); stream_.Put('l'); stream_.Put('l'); + } + + void WriteBool(bool b) { + if (b) { + stream_.Put('t'); stream_.Put('r'); stream_.Put('u'); stream_.Put('e'); + } + else { + stream_.Put('f'); stream_.Put('a'); stream_.Put('l'); stream_.Put('s'); stream_.Put('e'); + } + } + + void WriteInt(int i) { + if (i < 0) { + stream_.Put('-'); + i = -i; + } + WriteUint((unsigned)i); + } + + void WriteUint(unsigned u) { + char buffer[10]; + char *p = buffer; + do { + *p++ = (u % 10) + '0'; + u /= 10; + } while (u > 0); + + do { + --p; + stream_.Put(*p); + } while (p != buffer); + } + + void WriteInt64(int64_t i64) { + if (i64 < 0) { + stream_.Put('-'); + i64 = -i64; + } + WriteUint64((uint64_t)i64); + } + + void WriteUint64(uint64_t u64) { + char buffer[20]; + char *p = buffer; + do { + *p++ = char(u64 % 10) + '0'; + u64 /= 10; + } while (u64 > 0); + + do { + --p; + stream_.Put(*p); + } while (p != buffer); + } + + // cereal Temporary until constexpr support is added in RTM +#ifdef _MSC_VER + template + bool characterOk( Ch c ) + { + return c < 256; + } + + template <> + bool characterOk( Ch ) + { + return true; + } + +#else + template + typename std::enable_if < std::numeric_limits::max() < 265, bool>::type + characterOk( Ch c ) + { + return true; + } + + template + typename std::enable_if::max() >= 265, bool>::type + characterOk(Ch c) + { return c < 256; } +#endif + + //! \todo Optimization with custom double-to-string converter. + void WriteDouble(double d) { + char buffer[100]; +#if _MSC_VER + int ret = sprintf_s(buffer, sizeof(buffer), double_format, d); +#else + int ret = snprintf(buffer, sizeof(buffer), double_format, d); +#endif + RAPIDJSON_ASSERT(ret >= 1); + for (int i = 0; i < ret; i++) + stream_.Put(buffer[i]); + } + + void WriteLongDouble(long double d) { + char buffer[256]; +#if _MSC_VER + int ret = sprintf_s(buffer, sizeof(buffer), long_double_format, d); +#else + int ret = snprintf(buffer, sizeof(buffer), long_double_format, d); +#endif + RAPIDJSON_ASSERT(ret >= 1); + for (int i = 0; i < ret; i++) + stream_.Put(buffer[i]); + } + + void WriteLongLong(long long d) { + char buffer[256]; +#if _MSC_VER + int ret = sprintf_s(buffer, sizeof(buffer), "%lld", d); +#else + int ret = snprintf(buffer, sizeof(buffer), "%lld", d); +#endif + RAPIDJSON_ASSERT(ret >= 1); + for (int i = 0; i < ret; i++) + stream_.Put(buffer[i]); + } + + void WriteULongLong(unsigned long long d) { + char buffer[256]; +#if _MSC_VER + int ret = sprintf_s(buffer, sizeof(buffer), "%llu", d); +#else + int ret = snprintf(buffer, sizeof(buffer), "%llu", d); +#endif + RAPIDJSON_ASSERT(ret >= 1); + for (int i = 0; i < ret; i++) + stream_.Put(buffer[i]); + } + + void WriteString(const Ch* str, SizeType length) { + static const char hexDigits[] = "0123456789ABCDEF"; + static const char escape[256] = { +#define Z16 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + //0 1 2 3 4 5 6 7 8 9 A B C D E F + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'b', 't', 'n', 'u', 'f', 'r', 'u', 'u', // 00 + 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', 'u', // 10 + 0, 0, '"', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 + Z16, Z16, // 30~4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,'\\', 0, 0, 0, // 50 + Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16, Z16 // 60~FF +#undef Z16 + }; + + stream_.Put('\"'); + for (const Ch* p = str; p != str + length; ++p) { + if ((sizeof(Ch) == 1 || characterOk(*p)) && escape[(unsigned char)*p]) { + //if ((sizeof(Ch) == 1 || *p < 256) && escape[(unsigned char)*p]) { + stream_.Put('\\'); + stream_.Put(escape[(unsigned char)*p]); + if (escape[(unsigned char)*p] == 'u') { + stream_.Put('0'); + stream_.Put('0'); + stream_.Put(hexDigits[(*p) >> 4]); + stream_.Put(hexDigits[(*p) & 0xF]); + } + } + else + stream_.Put(*p); + } + stream_.Put('\"'); + } + + void WriteStartObject() { stream_.Put('{'); } + void WriteEndObject() { stream_.Put('}'); } + void WriteStartArray() { stream_.Put('['); } + void WriteEndArray() { stream_.Put(']'); } + + void Prefix(Type type) { + (void)type; + if (level_stack_.GetSize() != 0) { // this value is not at root + Level* level = level_stack_.template Top(); + if (level->valueCount > 0) { + if (level->inArray) + stream_.Put(','); // add comma if it is not the first element in array + else // in object + stream_.Put((level->valueCount % 2 == 0) ? ',' : ':'); + } + if (!level->inArray && level->valueCount % 2 == 0) + RAPIDJSON_ASSERT(type == kStringType); // if it's in object, then even number should be a name + level->valueCount++; + } + else + RAPIDJSON_ASSERT(type == kObjectType || type == kArrayType); + } + + Stream& stream_; + internal::Stack level_stack_; + +private: + // Prohibit assignment for VC C4512 warning + Writer& operator=(const Writer& w); +}; + +} // namespace rapidjson + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif // RAPIDJSON_RAPIDJSON_H_ diff --git a/include/cereal/types/array.hpp b/include/cereal/types/array.hpp index 4e145cda..9074a032 100644 --- a/include/cereal/types/array.hpp +++ b/include/cereal/types/array.hpp @@ -38,26 +38,26 @@ namespace cereal //! Saving for std::array primitive types //! using binary serialization, if supported template inline - typename std::enable_if, Archive>() + typename std::enable_if, Archive>::value && std::is_arithmetic::value, void>::type save( Archive & ar, std::array const & array ) { - ar( binary_data( array.data(), N * sizeof(T) ) ); + ar( binary_data( array.data(), sizeof(array) ) ); } //! Loading for std::array primitive types //! using binary serialization, if supported template inline - typename std::enable_if, Archive>() + typename std::enable_if, Archive>::value && std::is_arithmetic::value, void>::type load( Archive & ar, std::array & array ) { - ar( binary_data( array.data(), N * sizeof(T) ) ); + ar( binary_data( array.data(), sizeof(array) ) ); } //! Saving for std::array all other types template inline - typename std::enable_if, Archive>() + typename std::enable_if, Archive>::value || !std::is_arithmetic::value, void>::type save( Archive & ar, std::array const & array ) { @@ -67,7 +67,7 @@ namespace cereal //! Loading for std::array all other types template inline - typename std::enable_if, Archive>() + typename std::enable_if, Archive>::value || !std::is_arithmetic::value, void>::type load( Archive & ar, std::array & array ) { diff --git a/include/cereal/types/bitset.hpp b/include/cereal/types/bitset.hpp index b15187de..9d75166b 100644 --- a/include/cereal/types/bitset.hpp +++ b/include/cereal/types/bitset.hpp @@ -57,7 +57,7 @@ namespace cereal ar( _CEREAL_NVP("type", bitset_detail::type::ulong) ); ar( _CEREAL_NVP("data", b) ); } - catch( std::overflow_error const & e ) + catch( std::overflow_error const & ) { try { @@ -65,7 +65,7 @@ namespace cereal ar( _CEREAL_NVP("type", bitset_detail::type::ullong) ); ar( _CEREAL_NVP("data", b) ); } - catch( std::overflow_error const & e ) + catch( std::overflow_error const & ) { ar( _CEREAL_NVP("type", bitset_detail::type::string) ); ar( _CEREAL_NVP("data", bits.to_string()) ); diff --git a/include/cereal/types/common.hpp b/include/cereal/types/common.hpp index 59949e69..ce682f93 100644 --- a/include/cereal/types/common.hpp +++ b/include/cereal/types/common.hpp @@ -52,15 +52,15 @@ namespace cereal namespace common_detail { - //! Serialization for arrays if BinaryData is supported + //! Serialization for arrays if BinaryData is supported and we are arithmetic /*! @internal */ template inline void serializeArray( Archive & ar, T & array, std::true_type /* binary_supported */ ) { - ar( binary_data( array, traits::sizeof_array() * sizeof(typename std::remove_all_extents::type) ) ); + ar( binary_data( array, sizeof(array) ) ); } - //! Serialization for arrays if BinaryData is not supported + //! Serialization for arrays if BinaryData is not supported or we are not arithmetic /*! @internal */ template inline void serializeArray( Archive & ar, T & array, std::false_type /* binary_supported */ ) @@ -76,7 +76,8 @@ namespace cereal serialize(Archive & ar, T & array) { common_detail::serializeArray( ar, array, - std::integral_constant, Archive>()>() ); + std::integral_constant, Archive>::value && + std::is_arithmetic::type>::value>() ); } } // namespace cereal diff --git a/include/cereal/types/deque.hpp b/include/cereal/types/deque.hpp index 00569ee6..81e03997 100644 --- a/include/cereal/types/deque.hpp +++ b/include/cereal/types/deque.hpp @@ -52,7 +52,7 @@ namespace cereal size_type size; ar( make_size_tag( size ) ); - deque.resize( size ); + deque.resize( static_cast( size ) ); for( auto & i : deque ) ar( i ); diff --git a/include/cereal/types/forward_list.hpp b/include/cereal/types/forward_list.hpp index b3078efe..4512a9c4 100644 --- a/include/cereal/types/forward_list.hpp +++ b/include/cereal/types/forward_list.hpp @@ -58,7 +58,7 @@ namespace cereal size_type size; ar( make_size_tag( size ) ); - forward_list.resize( size ); + forward_list.resize( static_cast( size ) ); for( auto & i : forward_list ) ar( i ); diff --git a/include/cereal/types/list.hpp b/include/cereal/types/list.hpp index 8d6fa003..eb8f8e5b 100644 --- a/include/cereal/types/list.hpp +++ b/include/cereal/types/list.hpp @@ -52,7 +52,7 @@ namespace cereal size_type size; ar( make_size_tag( size ) ); - list.resize( size ); + list.resize( static_cast( size ) ); for( auto & i : list ) ar( i ); diff --git a/include/cereal/types/memory.hpp b/include/cereal/types/memory.hpp index 63979308..0201079f 100644 --- a/include/cereal/types/memory.hpp +++ b/include/cereal/types/memory.hpp @@ -129,7 +129,7 @@ namespace cereal //! Loading std::shared_ptr, case when user load and allocate (wrapper implementation) /*! @internal */ template inline - typename std::enable_if(), void>::type + typename std::enable_if::value, void>::type load( Archive & ar, memory_detail::PtrWrapper &> & wrapper ) { auto & ptr = wrapper.ptr; @@ -152,7 +152,7 @@ namespace cereal //! Loading std::shared_ptr, case when no user load and allocate (wrapper implementation) /*! @internal */ template inline - typename std::enable_if(), void>::type + typename std::enable_if::value, void>::type load( Archive & ar, memory_detail::PtrWrapper &> & wrapper ) { auto & ptr = wrapper.ptr; @@ -196,7 +196,7 @@ namespace cereal //! Loading std::unique_ptr, case when user provides load_and_allocate (wrapper implementation) /*! @internal */ template inline - typename std::enable_if(), void>::type + typename std::enable_if::value, void>::type load( Archive & ar, memory_detail::PtrWrapper &> & wrapper ) { uint8_t isValid; @@ -213,7 +213,7 @@ namespace cereal //! Loading std::unique_ptr, case when no load_and_allocate (wrapper implementation) /*! @internal */ template inline - typename std::enable_if(), void>::type + typename std::enable_if::value, void>::type load( Archive & ar, memory_detail::PtrWrapper &> & wrapper ) { uint8_t isValid; diff --git a/include/cereal/types/polymorphic.hpp b/include/cereal/types/polymorphic.hpp index e6f512ce..4719c94c 100644 --- a/include/cereal/types/polymorphic.hpp +++ b/include/cereal/types/polymorphic.hpp @@ -38,6 +38,12 @@ #include #include +#ifdef _MSC_VER +#define CONSTEXPR +#else +#define CONSTEXPR constexpr +#endif + //! Registers a polymorphic type with cereal /*! Polymorphic types must be registered before pointers to them can be serialized. This also assumes that @@ -59,7 +65,7 @@ template <> \ struct binding_name \ { \ - static constexpr char const * name() { return #T; }; \ + static CONSTEXPR char const * name() { return #T; }; \ }; \ } } /* end namespaces */ \ CEREAL_BIND_TO_ARCHIVES(T); @@ -75,7 +81,7 @@ namespace detail { \ template <> \ struct binding_name \ - { static constexpr char const * name() { return Name; }; }; \ + { static CONSTEXPR char const * name() { return Name; }; }; \ } } /* end namespaces */ \ CEREAL_BIND_TO_ARCHIVES(T); @@ -117,9 +123,14 @@ namespace cereal //! Serialize a shared_ptr if the 2nd msb in the nameid is set, and if we can actually construct the pointee /*! This check lets us try and skip doing polymorphic machinery if we can get away with using the derived class serialize function + + Note that on MSVC 2013 preview, is_default_constructible returns true for abstract classes with + default constructors, but on clang/gcc this will return false. So we also need to check for that here. @internal */ template inline - typename std::enable_if::value || traits::has_load_and_allocate(), bool>::type + typename std::enable_if<(std::is_default_constructible::value + || traits::has_load_and_allocate::value) + && !std::is_abstract::value, bool>::type serialize_wrapper(Archive & ar, std::shared_ptr & ptr, std::uint32_t const nameid) { if(nameid & detail::msb2_32bit) @@ -135,7 +146,9 @@ namespace cereal using the derived class serialize function @internal */ template inline - typename std::enable_if::value || traits::has_load_and_allocate(), bool>::type + typename std::enable_if<(std::is_default_constructible::value + || traits::has_load_and_allocate::value) + && !std::is_abstract::value, bool>::type serialize_wrapper(Archive & ar, std::unique_ptr & ptr, std::uint32_t const nameid) { if(nameid & detail::msb2_32bit) @@ -153,7 +166,9 @@ namespace cereal this was a polymorphic type serialized by its proper pointer type @internal */ template inline - typename std::enable_if::value && !traits::has_load_and_allocate(), bool>::type + typename std::enable_if<(!std::is_default_constructible::value + && !traits::has_load_and_allocate::value) + || std::is_abstract::value, bool>::type serialize_wrapper(Archive &, std::shared_ptr &, std::uint32_t const nameid) { if(nameid & detail::msb2_32bit) @@ -168,7 +183,9 @@ namespace cereal this was a polymorphic type serialized by its proper pointer type @internal */ template inline - typename std::enable_if::value && !traits::has_load_and_allocate(), bool>::type + typename std::enable_if<(!std::is_default_constructible::value + && !traits::has_load_and_allocate::value) + || std::is_abstract::value, bool>::type serialize_wrapper(Archive &, std::unique_ptr &, std::uint32_t const nameid) { if(nameid & detail::msb2_32bit) diff --git a/include/cereal/types/string.hpp b/include/cereal/types/string.hpp index 2be4cd45..94c6d661 100644 --- a/include/cereal/types/string.hpp +++ b/include/cereal/types/string.hpp @@ -37,7 +37,7 @@ namespace cereal { //! Serialization for basic_string types, if binary data is supported template inline - typename std::enable_if, Archive>(), void>::type + typename std::enable_if, Archive>::value, void>::type save(Archive & ar, std::basic_string const & str) { // Save number of chars + the data @@ -47,13 +47,13 @@ namespace cereal //! Serialization for basic_string types, if binary data is supported template inline - typename std::enable_if, Archive>(), void>::type + typename std::enable_if, Archive>::value, void>::type load(Archive & ar, std::basic_string & str) { size_type size; ar( make_size_tag( size ) ); - str.resize(size); - ar( binary_data( &(*str.begin()), size * sizeof(CharT) ) ); + str.resize(static_cast(size)); + ar( binary_data( &(*str.begin()), static_cast(size) * sizeof(CharT) ) ); } } // namespace cereal diff --git a/include/cereal/types/unordered_map.hpp b/include/cereal/types/unordered_map.hpp index 40953456..62638c6c 100644 --- a/include/cereal/types/unordered_map.hpp +++ b/include/cereal/types/unordered_map.hpp @@ -55,7 +55,7 @@ namespace cereal ar( make_size_tag( size ) ); map.clear(); - map.reserve( size ); + map.reserve( static_cast( size ) ); for( size_type i = 0; i < size; ++i ) { diff --git a/include/cereal/types/unordered_set.hpp b/include/cereal/types/unordered_set.hpp index e92a8aaa..5489ceb1 100644 --- a/include/cereal/types/unordered_set.hpp +++ b/include/cereal/types/unordered_set.hpp @@ -55,7 +55,7 @@ namespace cereal ar( make_size_tag( size ) ); set.clear(); - set.reserve( size ); + set.reserve( static_cast( size ) ); for( size_type i = 0; i < size; ++i ) { diff --git a/include/cereal/types/vector.hpp b/include/cereal/types/vector.hpp index d71427ef..5393b5af 100644 --- a/include/cereal/types/vector.hpp +++ b/include/cereal/types/vector.hpp @@ -37,7 +37,7 @@ namespace cereal { //! Serialization for std::vectors of arithmetic (but not bool) using binary serialization, if supported template inline - typename std::enable_if, Archive>() + typename std::enable_if, Archive>::value && std::is_arithmetic::value && !std::is_same::value, void>::type save( Archive & ar, std::vector const & vector ) { @@ -47,20 +47,20 @@ namespace cereal //! Serialization for std::vectors of arithmetic (but not bool) using binary serialization, if supported template inline - typename std::enable_if, Archive>() + typename std::enable_if, Archive>::value && std::is_arithmetic::value && !std::is_same::value, void>::type load( Archive & ar, std::vector & vector ) { size_type vectorSize; ar( make_size_tag( vectorSize ) ); - vector.resize( vectorSize ); - ar( binary_data( vector.data(), vectorSize * sizeof(T) ) ); + vector.resize( static_cast( vectorSize ) ); + ar( binary_data( vector.data(), static_cast( vectorSize ) * sizeof(T) ) ); } //! Serialization for non-arithmetic (and bool) vector types template inline - typename std::enable_if, Archive>() + typename std::enable_if, Archive>::value || !std::is_arithmetic::value || std::is_same::value, void>::type save( Archive & ar, std::vector const & vector ) @@ -72,7 +72,7 @@ namespace cereal //! Serialization for non-arithmetic (and bool) vector types template inline - typename std::enable_if, Archive>() + typename std::enable_if, Archive>::value || !std::is_arithmetic::value || std::is_same::value, void>::type load( Archive & ar, std::vector & vector ) @@ -80,7 +80,7 @@ namespace cereal size_type size; ar( make_size_tag( size ) ); - vector.resize( size ); + vector.resize( static_cast( size ) ); for( auto it = vector.begin(), end = vector.end(); it != end; ++it ) ar( *it ); } diff --git a/performance.cpp b/performance.cpp index 118a7ee1..865dc95b 100644 --- a/performance.cpp +++ b/performance.cpp @@ -24,6 +24,11 @@ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4244 4267) +#endif + #include #include #include @@ -166,9 +171,6 @@ void test( std::string const & name, auto loadResult = loadData( os, {SerializationT::boost::template load} ); totalBoostLoad += loadResult.second; - - if( validateData ) - ; // TODO } // Cereal @@ -181,9 +183,6 @@ void test( std::string const & name, auto loadResult = loadData( os, {SerializationT::cereal::template load} ); totalCerealLoad += loadResult.second; - - if( validateData ) - ; // TODO } } @@ -222,10 +221,15 @@ random_value(std::mt19937 & gen) { return std::uniform_real_distribution(-10000.0, 10000.0)(gen); } template -typename std::enable_if::value, T>::type +typename std::enable_if::value && sizeof(T) != sizeof(char), T>::type random_value(std::mt19937 & gen) { return std::uniform_int_distribution(std::numeric_limits::lowest(), std::numeric_limits::max())(gen); } +template +typename std::enable_if::value && sizeof(T) == sizeof(char), T>::type +random_value(std::mt19937 & gen) +{ return static_cast( std::uniform_int_distribution(std::numeric_limits::lowest(), std::numeric_limits::max())(gen) ); } + template typename std::enable_if::value, std::string>::type random_value(std::mt19937 & gen) @@ -241,7 +245,8 @@ std::basic_string random_basic_string(std::mt19937 & gen, size_t maxSize = 30 { std::basic_string s(std::uniform_int_distribution(3, maxSize)(gen), ' '); for(C & c : s) - c = std::uniform_int_distribution(' ', '~')(gen); + c = static_cast( std::uniform_int_distribution( '~', '~' )(gen) ); + return s; return s; } @@ -408,7 +413,7 @@ int main() std::map m; for(size_t i=0; i(name.str(), m); }; @@ -417,3 +422,7 @@ int main() return 0; } + +#ifdef _MSC_VER +#pragma warning(pop) +#endif diff --git a/sandbox.cpp b/sandbox.cpp index 5d1f8ca4..a434f1be 100644 --- a/sandbox.cpp +++ b/sandbox.cpp @@ -42,7 +42,7 @@ #include #include -#include +//#include #include #include #include @@ -70,7 +70,7 @@ class Derived : public Base { public: using Base::x; - Derived() = default; + Derived() : Base(), y() {} Derived( int d, int b ) { y = d; @@ -244,7 +244,9 @@ struct NonEmptyStruct struct NoDefaultCtor { - NoDefaultCtor() = delete; +private: + NoDefaultCtor() {}; +public: NoDefaultCtor(int x) : y(x) { } diff --git a/sandbox_json.cpp b/sandbox_json.cpp index 3f6f073f..ef62e1ae 100644 --- a/sandbox_json.cpp +++ b/sandbox_json.cpp @@ -40,13 +40,13 @@ #include -#include #include #include #include #include #include #include +#include // ################################### struct Test1 @@ -174,11 +174,18 @@ struct Everything struct SubFixture { - int a = 3; - uint64_t b = 9999; - float c = 100.1; - double d = 2000.9; - std::string s = "hello, world!"; + SubFixture() : a( 3 ), + b( 9999 ), + c( 100.1f ), + d( 2000.9 ), + s( "hello, world!" ) + {} + + int a; + uint64_t b; + float c; + double d; + std::string s; template void serialize(Archive & ar) @@ -202,7 +209,15 @@ struct SubFixture struct Fixture { SubFixture f1, f2, f3; - int array[4] = {1, 2, 3, 4}; + int array[4]; + + Fixture() + { + array[0] = 1; + array[1] = 2; + array[2] = 3; + array[3] = 4; + } template void save(Archive & ar) const @@ -232,9 +247,10 @@ struct Fixture struct AAA { - int one = 1, two = 2; + AAA() : one( 1 ), two( 2 ), three( { {1, 2, 3}, { 4, 5, 6 }, {} } ) {} + int one, two; - std::vector> three = {{1,2,3}, {4,5,6}, {}}; + std::vector> three; template void serialize(Archive & ar) @@ -247,16 +263,18 @@ struct AAA class Stuff { public: - Stuff() = default; + Stuff() {} void fillData() { - data = { {"imaginary", {{0, -1.0f}, - {0, -2.9932f}, - {0, -3.5f}}}, - {"real", {{1.0f, 0}, - {2.2f, 0}, - {3.3f, 0}}} }; + std::vector> t1{ {0, -1.0f}, + { 0, -2.9932f }, + { 0, -3.5f } }; + std::vector> t2{ {1.0f, 0}, + { 2.2f, 0 }, + { 3.3f, 0 } }; + data["imaginary"] = t1; + data["real"] = t2; } private: @@ -300,6 +318,10 @@ int main() std::vector vec = {1, 2, 3, 4, 5}; archive( CEREAL_NVP(vec), arr ); + auto f = std::make_shared(); + auto f2 = f; + archive( f ); + archive( f2 ); } @@ -314,6 +336,6 @@ int main() // assert( f->array[2] == 3 ); // assert( f->array[3] == 4 ); //} - + return 0; } diff --git a/sandbox_rtti.cpp b/sandbox_rtti.cpp index 35f9972e..7a9a3020 100644 --- a/sandbox_rtti.cpp +++ b/sandbox_rtti.cpp @@ -110,7 +110,7 @@ struct OurBase struct OurType : public OurBase { - OurType() = default; + OurType() : OurBase(), x() {} OurType(int x_) : x(x_) {} void foo() {} @@ -201,11 +201,11 @@ int main() //oarchive(ptr2); //oarchive(ptr3); //oarchive(ptr4); - oarchive(ptr5); + //oarchive(ptr5); + - - std::shared_ptr a = std::make_shared(); - oarchive(a); + //std::shared_ptr a = std::make_shared(); + //oarchive(a); } { @@ -223,6 +223,6 @@ int main() //iarchive(ptr2); //iarchive(ptr3); //iarchive(ptr4); - iarchive(ptr5); + //iarchive(ptr5); } } diff --git a/sandbox_vs.cpp b/sandbox_vs.cpp new file mode 100644 index 00000000..aae34c7f --- /dev/null +++ b/sandbox_vs.cpp @@ -0,0 +1,220 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +//#include +#include +#include + +#include +#include +#include + +struct Archive {}; + +struct Test +{ + template + void serialzize( Archive & ar ) + { + std::cout << "hey there" << std::endl; + } + + template + void save( Archive & ar ) const + { + std::cout << "saved by the bell" << std::endl; + } + + template + void load( Archive & ar ) + { + std::cout << "locked and loaded" << std::endl; + } + + template + static Test * load_and_allocate( Archive & ar ) + { + return new Test(); + } +}; + +template +void serialize( Archive & ar, Test & t ) +{ } + +template +void load( Archive & ar, Test & t ) +{ } + +template +void save( Archive & ar, Test const & t ) +{ } + +namespace cereal +{ + template <> + struct LoadAndAllocate + { + template + static Test * load_and_allocate( Archive & ar ) + { + return new Test(); + } + }; +} + +struct A +{ + virtual void foo() = 0; +}; + +struct B : A +{ + void foo() {} + + template + void serialize( Archive & ar ) + { + std::cout << "i'm in your b" << std::endl; + } +}; + +struct C +{ + char a; +}; + +//CEREAL_REGISTER_TYPE(B); + +template +static auto test(int) -> decltype( cereal::access::member_serialize( std::declval(), std::declval() ), std::true_type()) +{ return {}; } + +template +static auto test(...) -> std::false_type +{ return {}; } + +int main() +{ + typedef Test T; + std::cout << std::boolalpha; + + // Test Load and Allocate internal/external + std::cout << "\tload_and_allocate" << std::endl; + std::cout << cereal::traits::has_member_load_and_allocate::value << std::endl; + std::cout << cereal::traits::has_non_member_load_and_allocate::value << std::endl; + + // serialize + std::cout << "\tserialize" << std::endl; + std::cout << cereal::traits::has_member_serialize::value << std::endl; + std::cout << cereal::traits::has_non_member_serialize::value << std::endl; + std::cout << test(0) << std::endl; + + // load + std::cout << "\tload" << std::endl; + std::cout << cereal::traits::has_member_load::value << std::endl; + std::cout << cereal::traits::has_non_member_load::value << std::endl; + + // save + std::cout << "\tsave" << std::endl; + std::cout << cereal::traits::has_member_save::value << std::endl; + std::cout << cereal::traits::has_non_member_save::value << std::endl; + + // splittable + std::cout << "\t splittable" << std::endl; + std::cout << cereal::traits::has_member_split::value << std::endl; + std::cout << cereal::traits::has_non_member_split::value << std::endl; + + // serialiable + std::cout << "\toutput serializable" << std::endl; + std::cout << cereal::traits::is_output_serializable::value << std::endl; + std::cout << cereal::traits::is_input_serializable::value << std::endl; + + // specialized + std::cout << "\tspecialized" << std::endl; + std::cout << cereal::traits::detail::is_specialized_member_serialize::value << std::endl; + std::cout << cereal::traits::detail::is_specialized_member_load_save::value << std::endl; + std::cout << cereal::traits::detail::is_specialized_non_member_serialize::value << std::endl; + std::cout << cereal::traits::detail::is_specialized_non_member_load_save::value << std::endl; + std::cout << cereal::traits::detail::is_specialized_error::value << std::endl; + std::cout << cereal::traits::is_specialized::value << std::endl; + + // array size + std::cout << typeid(A).name() << std::endl; + std::cout << typeid(cereal::traits::has_load_and_allocate).name() << std::endl; + + //Archive a; + //T t; + + //cereal::access::member_save( a, t ); + //cereal::access::member_load( a, t ); + //cereal::access::member_serialize( a, t ); + + //std::stringstream ss; + //{ + // cereal::JSONOutputArchive ar( ss ); + // ar( 5 ); + // ar( cereal::make_nvp("hello", 2.4f ) ); + // std::string s = "hey yo"; + // ar( CEREAL_NVP( s ) ); + // int darp [] = { 1, 2, 3 }; + // ar.saveBinaryValue( darp, sizeof(int) * 3, "darp" ); + // std::unique_ptr ptr( new B() ); + // ar( CEREAL_NVP( ptr ) ); + //} + //{ + // cereal::JSONInputArchive ar( ss ); + // int x; + // ar( x ); + // assert( x == 5 ); + // float f; + // ar( f ); + // assert( f == 2.4f ); + // std::string s; + // ar( s ); + // assert( s == "hey yo" ); + // int darp[3]; + // ar.loadBinaryValue( darp, sizeof(int) * 3 ); + // assert( darp[0] == 1 ); + // assert( darp[1] == 2 ); + // assert( darp[2] == 3 ); + // std::unique_ptr ptr; + // std::cout << "----------" << std::endl; + // std::cout << std::is_default_constructible::value << std::endl; + // std::cout << cereal::traits::has_load_and_allocate::value << std::endl; + // ar( ptr ); + //} + + return 0; +} diff --git a/unittests.cpp b/unittests.cpp index a032ca01..ca1714b9 100644 --- a/unittests.cpp +++ b/unittests.cpp @@ -75,6 +75,8 @@ namespace cereal struct StructBase { + StructBase() {} + StructBase( int xx, int yy ) : x( xx ), y( yy ) {} int x, y; bool operator==(StructBase const & other) const { return x == other.x && y == other.y; } @@ -171,17 +173,22 @@ random_value(std::mt19937 & gen) { return std::uniform_real_distribution(-10000.0, 10000.0)(gen); } template -typename std::enable_if::value, T>::type +typename std::enable_if::value && sizeof(T) != sizeof(char), T>::type random_value(std::mt19937 & gen) { return std::uniform_int_distribution(std::numeric_limits::lowest(), std::numeric_limits::max())(gen); } +template +typename std::enable_if::value && sizeof(T) == sizeof(char), T>::type +random_value(std::mt19937 & gen) +{ return static_cast( std::uniform_int_distribution(std::numeric_limits::lowest(), std::numeric_limits::max())(gen) ); } + template typename std::enable_if::value, std::string>::type random_value(std::mt19937 & gen) { std::string s(std::uniform_int_distribution(3, 30)(gen), ' '); for(char & c : s) - c = std::uniform_int_distribution(' ', '~')(gen); + c = static_cast( std::uniform_int_distribution( '~', '~' )(gen) ); return s; } @@ -190,7 +197,7 @@ std::basic_string random_basic_string(std::mt19937 & gen) { std::basic_string s(std::uniform_int_distribution(3, 30)(gen), ' '); for(C & c : s) - c = std::uniform_int_distribution(' ', '~')(gen); + c = static_cast( std::uniform_int_distribution( '~', '~' )(gen) ); return s; } @@ -199,7 +206,7 @@ std::string random_binary_string(std::mt19937 & gen) { std::string s(N, ' '); for(auto & c : s ) - c = std::uniform_int_distribution('0', '1')(gen); + c = static_cast( std::uniform_int_distribution( '0', '1' )(gen) ); return s; } @@ -241,16 +248,16 @@ void test_pod() } bool i_bool = false; - uint8_t i_uint8 = 0.0; - int8_t i_int8 = 0.0; - uint16_t i_uint16 = 0.0; - int16_t i_int16 = 0.0; - uint32_t i_uint32 = 0.0; - int32_t i_int32 = 0.0; - uint64_t i_uint64 = 0.0; - int64_t i_int64 = 0.0; - float i_float = 0.0; - double i_double = 0.0; + uint8_t i_uint8 = 0; + int8_t i_int8 = 0; + uint16_t i_uint16 = 0; + int16_t i_int16 = 0; + uint32_t i_uint32 = 0; + int32_t i_int32 = 0; + uint64_t i_uint64 = 0; + int64_t i_int64 = 0; + float i_float = 0; + double i_double = 0; std::istringstream is(os.str()); { @@ -277,7 +284,7 @@ void test_pod() BOOST_CHECK_EQUAL(i_int32 , o_int32); BOOST_CHECK_EQUAL(i_uint64 , o_uint64); BOOST_CHECK_EQUAL(i_int64 , o_int64); - BOOST_CHECK_CLOSE(i_float , o_float, 1e-5); + BOOST_CHECK_CLOSE(i_float , o_float, (float)1e-5); BOOST_CHECK_CLOSE(i_double , o_double, 1e-5); } } @@ -371,23 +378,23 @@ void test_array() { std::array o_podarray; for(auto & elem : o_podarray) - elem = random_value(gen); + elem = random_value(gen); std::array o_iserarray; for(auto & elem : o_iserarray) - elem = { random_value(gen), random_value(gen) }; + elem = StructInternalSerialize( random_value(gen), random_value(gen) ); std::array o_isplarray; for(auto & elem : o_isplarray) - elem = { random_value(gen), random_value(gen) }; + elem = StructInternalSplit( random_value(gen), random_value(gen) ); std::array o_eserarray; for(auto & elem : o_eserarray) - elem = { random_value(gen), random_value(gen) }; + elem = StructExternalSerialize( random_value(gen), random_value(gen) ); std::array o_esplarray; for(auto & elem : o_esplarray) - elem = { random_value(gen), random_value(gen) }; + elem = StructExternalSplit( random_value(gen), random_value(gen) ); std::ostringstream os; { @@ -456,23 +463,23 @@ void test_deque() { std::deque o_poddeque(100); for(auto & elem : o_poddeque) - elem = random_value(gen); + elem = random_value(gen); std::deque o_iserdeque(100); for(auto & elem : o_iserdeque) - elem = { random_value(gen), random_value(gen) }; + elem = StructInternalSerialize( random_value(gen), random_value(gen) ); std::deque o_ispldeque(100); for(auto & elem : o_ispldeque) - elem = { random_value(gen), random_value(gen) }; + elem = StructInternalSplit( random_value(gen), random_value(gen) ); std::deque o_eserdeque(100); for(auto & elem : o_eserdeque) - elem = { random_value(gen), random_value(gen) }; + elem = StructExternalSerialize( random_value(gen), random_value(gen) ); std::deque o_espldeque(100); for(auto & elem : o_espldeque) - elem = { random_value(gen), random_value(gen) }; + elem = StructExternalSplit( random_value(gen), random_value(gen) ); std::ostringstream os; { @@ -547,23 +554,23 @@ void test_forward_list() { std::forward_list o_podforward_list(100); for(auto & elem : o_podforward_list) - elem = random_value(gen); + elem = random_value(gen); std::forward_list o_iserforward_list(100); for(auto & elem : o_iserforward_list) - elem = { random_value(gen), random_value(gen) }; + elem = StructInternalSerialize( random_value(gen), random_value(gen) ); std::forward_list o_isplforward_list(100); for(auto & elem : o_isplforward_list) - elem = { random_value(gen), random_value(gen) }; + elem = StructInternalSplit( random_value(gen), random_value(gen) ); std::forward_list o_eserforward_list(100); for(auto & elem : o_eserforward_list) - elem = { random_value(gen), random_value(gen) }; + elem = StructExternalSerialize( random_value(gen), random_value(gen) ); std::forward_list o_esplforward_list(100); for(auto & elem : o_esplforward_list) - elem = { random_value(gen), random_value(gen) }; + elem = StructExternalSplit( random_value(gen), random_value(gen) ); std::ostringstream os; { @@ -632,23 +639,23 @@ void test_list() { std::list o_podlist(100); for(auto & elem : o_podlist) - elem = random_value(gen); + elem = random_value(gen); std::list o_iserlist(100); for(auto & elem : o_iserlist) - elem = { random_value(gen), random_value(gen) }; + elem = StructInternalSerialize( random_value(gen), random_value(gen) ); std::list o_ispllist(100); for(auto & elem : o_ispllist) - elem = { random_value(gen), random_value(gen) }; + elem = StructInternalSplit( random_value(gen), random_value(gen) ); std::list o_eserlist(100); for(auto & elem : o_eserlist) - elem = { random_value(gen), random_value(gen) }; + elem = StructExternalSerialize( random_value(gen), random_value(gen) ); std::list o_espllist(100); for(auto & elem : o_espllist) - elem = { random_value(gen), random_value(gen) }; + elem = StructExternalSplit( random_value(gen), random_value(gen) ); std::ostringstream os; { @@ -2095,23 +2102,23 @@ void test_vector() { std::vector o_podvector(100); for(auto & elem : o_podvector) - elem = random_value(gen); + elem = random_value(gen); std::vector o_iservector(100); for(auto & elem : o_iservector) - elem = { random_value(gen), random_value(gen) }; + elem = StructInternalSerialize( random_value(gen), random_value(gen) ); std::vector o_isplvector(100); for(auto & elem : o_isplvector) - elem = { random_value(gen), random_value(gen) }; + elem = StructInternalSplit( random_value(gen), random_value(gen) ); std::vector o_eservector(100); for(auto & elem : o_eservector) - elem = { random_value(gen), random_value(gen) }; + elem = StructExternalSerialize( random_value(gen), random_value(gen) ); std::vector o_esplvector(100); for(auto & elem : o_esplvector) - elem = { random_value(gen), random_value(gen) }; + elem = StructExternalSplit( random_value(gen), random_value(gen) ); std::ostringstream os; { @@ -2682,7 +2689,7 @@ BOOST_AUTO_TEST_CASE( json_structs_specialized ) // ###################################################################### struct PolyBase { - PolyBase() = default; + PolyBase() {} PolyBase( int xx, float yy ) : x(xx), y(yy) {} int x; float y; @@ -2703,7 +2710,7 @@ struct PolyBase struct PolyDerived : PolyBase { - PolyDerived() = default; + PolyDerived() {} PolyDerived( int xx, float yy, bool aa, double bb ) : PolyBase( xx, yy ), a(aa), b(bb) {} @@ -2739,7 +2746,7 @@ void test_polymorphic() std::random_device rd; std::mt19937 gen(rd()); - auto rngB = [&](){ return random_value( gen ) % 2; }; + auto rngB = [&](){ return random_value( gen ) % 2 == 0; }; auto rngI = [&](){ return random_value( gen ); }; auto rngF = [&](){ return random_value( gen ); }; auto rngD = [&](){ return random_value( gen ); }; @@ -2801,10 +2808,17 @@ BOOST_AUTO_TEST_CASE( json_polymorphic ) namespace mynamespace { struct MyCustomClass {}; } +#ifdef _MSC_VER +BOOST_AUTO_TEST_CASE( util ) +{ + BOOST_CHECK_EQUAL( cereal::util::demangledName(), "struct mynamespace::MyCustomClass" ); +} +#else BOOST_AUTO_TEST_CASE( util ) { BOOST_CHECK_EQUAL( cereal::util::demangledName(), "mynamespace::MyCustomClass" ); } +#endif template inline void swapBytes( T & t ) @@ -2877,16 +2891,16 @@ BOOST_AUTO_TEST_CASE( portable_binary_archive ) swapBytes(o_double); bool i_bool = false; - uint8_t i_uint8 = 0.0; - int8_t i_int8 = 0.0; - uint16_t i_uint16 = 0.0; - int16_t i_int16 = 0.0; - uint32_t i_uint32 = 0.0; - int32_t i_int32 = 0.0; - uint64_t i_uint64 = 0.0; - int64_t i_int64 = 0.0; - float i_float = 0.0; - double i_double = 0.0; + uint8_t i_uint8 = 0; + int8_t i_int8 = 0; + uint16_t i_uint16 = 0; + int16_t i_int16 = 0; + uint32_t i_uint32 = 0; + int32_t i_int32 = 0; + uint64_t i_uint64 = 0; + int64_t i_int64 = 0; + float i_float = 0; + double i_double = 0; std::istringstream is(os.str()); { @@ -2913,7 +2927,7 @@ BOOST_AUTO_TEST_CASE( portable_binary_archive ) BOOST_CHECK_EQUAL(i_int32 , o_int32); BOOST_CHECK_EQUAL(i_uint64 , o_uint64); BOOST_CHECK_EQUAL(i_int64 , o_int64); - BOOST_CHECK_CLOSE(i_float , o_float, 1e-5); + BOOST_CHECK_CLOSE(i_float , o_float, (float)1e-5); BOOST_CHECK_CLOSE(i_double , o_double, 1e-5); } -} +} \ No newline at end of file diff --git a/vs2013/.gitignore b/vs2013/.gitignore new file mode 100644 index 00000000..8cdd74e6 --- /dev/null +++ b/vs2013/.gitignore @@ -0,0 +1,2 @@ +*/Debug +*/Release \ No newline at end of file diff --git a/vs2013/performance/performance.vcxproj b/vs2013/performance/performance.vcxproj new file mode 100644 index 00000000..6a312712 --- /dev/null +++ b/vs2013/performance/performance.vcxproj @@ -0,0 +1,138 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {2F374733-FCA8-4CBB-91A0-2B0B34393D86} + performance + + + + Application + true + v120 + MultiByte + + + Application + true + v120 + MultiByte + + + Application + false + v120 + true + MultiByte + + + Application + false + v120 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + C:\Boost\lib;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + C:\Boost\lib\x64;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + C:\Boost\lib;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + C:\Boost\lib\x64;$(LibraryPath) + + + + Level3 + Disabled + true + + + true + + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/vs2013/performance/performance.vcxproj.filters b/vs2013/performance/performance.vcxproj.filters new file mode 100644 index 00000000..1dfa88a6 --- /dev/null +++ b/vs2013/performance/performance.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/vs2013/sandbox/sandbox.vcxproj b/vs2013/sandbox/sandbox.vcxproj new file mode 100644 index 00000000..89ca7d73 --- /dev/null +++ b/vs2013/sandbox/sandbox.vcxproj @@ -0,0 +1,136 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {DAC23DBB-630B-46B9-B115-F1449697898A} + sandbox + + + + Application + true + v120 + MultiByte + + + Application + true + v120 + MultiByte + + + Application + false + v120 + true + MultiByte + + + Application + false + v120 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_54;$(IncludePath) + C:\Boost\lib;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_54;$(IncludePath) + C:\Boost\lib;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + + + + Level3 + Disabled + true + + + true + + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/vs2013/sandbox/sandbox.vcxproj.filters b/vs2013/sandbox/sandbox.vcxproj.filters new file mode 100644 index 00000000..04dc4368 --- /dev/null +++ b/vs2013/sandbox/sandbox.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/vs2013/sandbox_json/sandbox_json.vcxproj b/vs2013/sandbox_json/sandbox_json.vcxproj new file mode 100644 index 00000000..9191e492 --- /dev/null +++ b/vs2013/sandbox_json/sandbox_json.vcxproj @@ -0,0 +1,134 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {52E96EC3-125A-4525-BC72-F3C524F24640} + sandbox_json + + + + Application + true + v120 + MultiByte + + + Application + true + v120 + MultiByte + + + Application + false + v120 + true + MultiByte + + + Application + false + v120 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_54;$(IncludePath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_54;$(IncludePath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + + + + Level3 + Disabled + true + + + true + + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/vs2013/sandbox_json/sandbox_json.vcxproj.filters b/vs2013/sandbox_json/sandbox_json.vcxproj.filters new file mode 100644 index 00000000..77b07597 --- /dev/null +++ b/vs2013/sandbox_json/sandbox_json.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/vs2013/sandbox_rtti/sandbox_rtti.vcxproj b/vs2013/sandbox_rtti/sandbox_rtti.vcxproj new file mode 100644 index 00000000..c0094303 --- /dev/null +++ b/vs2013/sandbox_rtti/sandbox_rtti.vcxproj @@ -0,0 +1,136 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {C81EF3F9-7849-4506-898C-85D0D564CD6A} + sandbox_rtti + + + + Application + true + v120 + MultiByte + + + Application + true + v120 + MultiByte + + + Application + false + v120 + true + MultiByte + + + Application + false + v120 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_54;$(IncludePath) + C:\Boost\lib;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_54;$(IncludePath) + C:\Boost\lib;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + + + + Level3 + Disabled + true + + + true + + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/vs2013/sandbox_rtti/sandbox_rtti.vcxproj.filters b/vs2013/sandbox_rtti/sandbox_rtti.vcxproj.filters new file mode 100644 index 00000000..8e68b66b --- /dev/null +++ b/vs2013/sandbox_rtti/sandbox_rtti.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/vs2013/sandbox_vs/sandbox_vs.vcxproj b/vs2013/sandbox_vs/sandbox_vs.vcxproj new file mode 100644 index 00000000..dbb41bce --- /dev/null +++ b/vs2013/sandbox_vs/sandbox_vs.vcxproj @@ -0,0 +1,138 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {A67E36D2-32BE-4D4D-BA2E-8FD59378E734} + sandbox_vs + + + + Application + true + v120 + MultiByte + + + Application + true + v120 + MultiByte + + + Application + false + v120 + true + MultiByte + + + Application + false + v120 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + C:\Boost\lib;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + C:\Boost\lib;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + + + + Level3 + Disabled + true + + + true + %(AdditionalDependencies) + + + + + Level3 + Disabled + true + + + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + %(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/vs2013/sandbox_vs/sandbox_vs.vcxproj.filters b/vs2013/sandbox_vs/sandbox_vs.vcxproj.filters new file mode 100644 index 00000000..81871f53 --- /dev/null +++ b/vs2013/sandbox_vs/sandbox_vs.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/vs2013/unittests/unittests.vcxproj b/vs2013/unittests/unittests.vcxproj new file mode 100644 index 00000000..337b4b2f --- /dev/null +++ b/vs2013/unittests/unittests.vcxproj @@ -0,0 +1,144 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {D447E13A-97A4-4907-9F61-A9BCCDB91EF7} + unittests + + + + Application + true + v120 + MultiByte + + + Application + true + v120 + MultiByte + + + Application + false + v120 + true + MultiByte + + + Application + false + v120 + true + MultiByte + + + + + + + + + + + + + + + + + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + C:\Boost\lib;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + C:\Boost\lib\x64;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + C:\Boost\lib;$(LibraryPath) + + + $(SolutionDir)\..\include;C:\Boost\include\boost-1_55;$(IncludePath) + C:\Boost\lib\x64;$(LibraryPath) + + + + Level3 + Disabled + true + true + + + true + %(AdditionalDependencies) + NotSet + Console + + + + + Level3 + Disabled + true + /bigobj %(AdditionalOptions) + + + true + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + %(AdditionalDependencies) + + + + + Level3 + MaxSpeed + true + true + true + + + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/vs2013/unittests/unittests.vcxproj.filters b/vs2013/unittests/unittests.vcxproj.filters new file mode 100644 index 00000000..8e9d9755 --- /dev/null +++ b/vs2013/unittests/unittests.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/vs2013/vs2013.sln b/vs2013/vs2013.sln new file mode 100644 index 00000000..532da88c --- /dev/null +++ b/vs2013/vs2013.sln @@ -0,0 +1,76 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.20617.1 PREVIEW +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sandbox_vs", "sandbox_vs\sandbox_vs.vcxproj", "{A67E36D2-32BE-4D4D-BA2E-8FD59378E734}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sandbox_json", "sandbox_json\sandbox_json.vcxproj", "{52E96EC3-125A-4525-BC72-F3C524F24640}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sandbox", "sandbox\sandbox.vcxproj", "{DAC23DBB-630B-46B9-B115-F1449697898A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sandbox_rtti", "sandbox_rtti\sandbox_rtti.vcxproj", "{C81EF3F9-7849-4506-898C-85D0D564CD6A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unittests", "unittests\unittests.vcxproj", "{D447E13A-97A4-4907-9F61-A9BCCDB91EF7}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "performance", "performance\performance.vcxproj", "{2F374733-FCA8-4CBB-91A0-2B0B34393D86}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A67E36D2-32BE-4D4D-BA2E-8FD59378E734}.Debug|Win32.ActiveCfg = Debug|Win32 + {A67E36D2-32BE-4D4D-BA2E-8FD59378E734}.Debug|Win32.Build.0 = Debug|Win32 + {A67E36D2-32BE-4D4D-BA2E-8FD59378E734}.Debug|x64.ActiveCfg = Debug|x64 + {A67E36D2-32BE-4D4D-BA2E-8FD59378E734}.Debug|x64.Build.0 = Debug|x64 + {A67E36D2-32BE-4D4D-BA2E-8FD59378E734}.Release|Win32.ActiveCfg = Release|Win32 + {A67E36D2-32BE-4D4D-BA2E-8FD59378E734}.Release|Win32.Build.0 = Release|Win32 + {A67E36D2-32BE-4D4D-BA2E-8FD59378E734}.Release|x64.ActiveCfg = Release|x64 + {A67E36D2-32BE-4D4D-BA2E-8FD59378E734}.Release|x64.Build.0 = Release|x64 + {52E96EC3-125A-4525-BC72-F3C524F24640}.Debug|Win32.ActiveCfg = Debug|Win32 + {52E96EC3-125A-4525-BC72-F3C524F24640}.Debug|Win32.Build.0 = Debug|Win32 + {52E96EC3-125A-4525-BC72-F3C524F24640}.Debug|x64.ActiveCfg = Debug|x64 + {52E96EC3-125A-4525-BC72-F3C524F24640}.Debug|x64.Build.0 = Debug|x64 + {52E96EC3-125A-4525-BC72-F3C524F24640}.Release|Win32.ActiveCfg = Release|Win32 + {52E96EC3-125A-4525-BC72-F3C524F24640}.Release|Win32.Build.0 = Release|Win32 + {52E96EC3-125A-4525-BC72-F3C524F24640}.Release|x64.ActiveCfg = Release|x64 + {52E96EC3-125A-4525-BC72-F3C524F24640}.Release|x64.Build.0 = Release|x64 + {DAC23DBB-630B-46B9-B115-F1449697898A}.Debug|Win32.ActiveCfg = Debug|Win32 + {DAC23DBB-630B-46B9-B115-F1449697898A}.Debug|Win32.Build.0 = Debug|Win32 + {DAC23DBB-630B-46B9-B115-F1449697898A}.Debug|x64.ActiveCfg = Debug|x64 + {DAC23DBB-630B-46B9-B115-F1449697898A}.Debug|x64.Build.0 = Debug|x64 + {DAC23DBB-630B-46B9-B115-F1449697898A}.Release|Win32.ActiveCfg = Release|Win32 + {DAC23DBB-630B-46B9-B115-F1449697898A}.Release|Win32.Build.0 = Release|Win32 + {DAC23DBB-630B-46B9-B115-F1449697898A}.Release|x64.ActiveCfg = Release|x64 + {DAC23DBB-630B-46B9-B115-F1449697898A}.Release|x64.Build.0 = Release|x64 + {C81EF3F9-7849-4506-898C-85D0D564CD6A}.Debug|Win32.ActiveCfg = Debug|Win32 + {C81EF3F9-7849-4506-898C-85D0D564CD6A}.Debug|Win32.Build.0 = Debug|Win32 + {C81EF3F9-7849-4506-898C-85D0D564CD6A}.Debug|x64.ActiveCfg = Debug|x64 + {C81EF3F9-7849-4506-898C-85D0D564CD6A}.Debug|x64.Build.0 = Debug|x64 + {C81EF3F9-7849-4506-898C-85D0D564CD6A}.Release|Win32.ActiveCfg = Release|Win32 + {C81EF3F9-7849-4506-898C-85D0D564CD6A}.Release|Win32.Build.0 = Release|Win32 + {C81EF3F9-7849-4506-898C-85D0D564CD6A}.Release|x64.ActiveCfg = Release|x64 + {C81EF3F9-7849-4506-898C-85D0D564CD6A}.Release|x64.Build.0 = Release|x64 + {D447E13A-97A4-4907-9F61-A9BCCDB91EF7}.Debug|Win32.ActiveCfg = Debug|Win32 + {D447E13A-97A4-4907-9F61-A9BCCDB91EF7}.Debug|Win32.Build.0 = Debug|Win32 + {D447E13A-97A4-4907-9F61-A9BCCDB91EF7}.Debug|x64.ActiveCfg = Debug|x64 + {D447E13A-97A4-4907-9F61-A9BCCDB91EF7}.Debug|x64.Build.0 = Debug|x64 + {D447E13A-97A4-4907-9F61-A9BCCDB91EF7}.Release|Win32.ActiveCfg = Release|Win32 + {D447E13A-97A4-4907-9F61-A9BCCDB91EF7}.Release|Win32.Build.0 = Release|Win32 + {D447E13A-97A4-4907-9F61-A9BCCDB91EF7}.Release|x64.ActiveCfg = Release|x64 + {D447E13A-97A4-4907-9F61-A9BCCDB91EF7}.Release|x64.Build.0 = Release|x64 + {2F374733-FCA8-4CBB-91A0-2B0B34393D86}.Debug|Win32.ActiveCfg = Debug|Win32 + {2F374733-FCA8-4CBB-91A0-2B0B34393D86}.Debug|Win32.Build.0 = Debug|Win32 + {2F374733-FCA8-4CBB-91A0-2B0B34393D86}.Debug|x64.ActiveCfg = Debug|x64 + {2F374733-FCA8-4CBB-91A0-2B0B34393D86}.Release|Win32.ActiveCfg = Release|Win32 + {2F374733-FCA8-4CBB-91A0-2B0B34393D86}.Release|Win32.Build.0 = Release|Win32 + {2F374733-FCA8-4CBB-91A0-2B0B34393D86}.Release|x64.ActiveCfg = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal