g++ 4.7.3 compatability fixed

closes #38

Added a preprocessor define CEREAL_OLDER_GCC that exists if using
any GCC 4.7.x or earlier.  If this is defined some type traits change to
our original solution (prior to VS compatible), which is probably what we'd switch
to if VS ever gets around to fully supporting SFINAE and constexpr.

In map and set, as well as in unit tests, use insert instead of emplace for 4.7.x.
This commit is contained in:
Shane Grant
2013-12-22 13:25:06 -08:00
parent 456122cfd0
commit 436a0a275c
7 changed files with 66 additions and 12 deletions

View File

@@ -1,8 +1,8 @@
CPPFLAGS=-std=c++11 -I./include -Wall -Werror -g -Wextra -Wshadow -pedantic CPPFLAGS=-std=c++11 -I./include -Wall -Werror -g -Wextra -Wshadow -pedantic
CXX=g++-4.7 CXX=g++
COVERAGE_OUTPUT=out COVERAGE_OUTPUT=out
all: unittests sandbox performance sandbox_rtti sandbox_json all: unittests sandbox sandbox_vs performance sandbox_rtti sandbox_json
sandbox: sandbox.cpp sandbox: sandbox.cpp
${CXX} sandbox.cpp -o sandbox ${CPPFLAGS} ${CXX} sandbox.cpp -o sandbox ${CPPFLAGS}

View File

@@ -101,6 +101,14 @@ namespace cereal
//! Creates a test for whether a non const member function exists with a version parameter //! Creates a test for whether a non const member function exists with a version parameter
/*! This creates a class derived from std::integral_constant that will be true if /*! 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. */ the type has the proper member function for the given archive. */
#ifdef CEREAL_OLDER_GCC
#define CEREAL_MAKE_HAS_MEMBER_VERSIONED_TEST(name) \
template <class T, class A, class SFINAE = void> \
struct has_member_versioned_##name : no {}; \
template <class T, class A> \
struct has_member_versioned_##name<T, A, \
typename Void< decltype( cereal::access::member_##name( std::declval<A&>(), std::declval<T&>(), 0 ) ) >::type> : yes {}
#else // NOT CEREAL_OLDER_GCC
#define CEREAL_MAKE_HAS_MEMBER_VERSIONED_TEST(name) \ #define CEREAL_MAKE_HAS_MEMBER_VERSIONED_TEST(name) \
namespace detail \ namespace detail \
{ \ { \
@@ -116,6 +124,7 @@ namespace cereal
} /* end namespace detail */ \ } /* end namespace detail */ \
template <class T, class A> \ template <class T, class A> \
struct has_member_versioned_##name : std::integral_constant<bool, detail::has_member_versioned_##name##_impl<T, A>::value> {} struct has_member_versioned_##name : std::integral_constant<bool, detail::has_member_versioned_##name##_impl<T, A>::value> {}
#endif // NOT CEREAL_OLDER_GCC
//! Creates a test for whether a non const non-member function exists with a version parameter //! Creates a test for whether a non const non-member function exists with a version parameter
/*! This creates a class derived from std::integral_constant that will be true if /*! This creates a class derived from std::integral_constant that will be true if
@@ -194,6 +203,21 @@ namespace cereal
template <class T, class A> template <class T, class A>
struct has_member_save_impl struct has_member_save_impl
{ {
#ifdef CEREAL_OLDER_GCC
template <class TT, class AA, class SFINAE = void>
struct test : no {};
template <class TT, class AA>
struct test<TT, AA,
typename Void< decltype( cereal::access::member_save( std::declval<AA&>(), std::declval<TT const &>() ) ) >::type> : yes {};
static const bool value = test<T, A>();
template <class TT, class AA, class SFINAE = void>
struct test2 : no {};
template <class TT, class AA>
struct test2<TT, AA,
typename Void< decltype( cereal::access::member_save_non_const( std::declval<AA&>(), std::declval<typename std::remove_const<TT>::type&>() ) ) >::type> : yes {};
static const bool not_const_type = test2<T, A>();
#else // NOT CEREAL_OLDER_GCC =========================================
template <class TT, class AA> template <class TT, class AA>
static auto test(int) -> decltype( cereal::access::member_save( std::declval<AA&>(), std::declval<TT const &>() ), yes()); static auto test(int) -> decltype( cereal::access::member_save( std::declval<AA&>(), std::declval<TT const &>() ), yes());
template <class, class> template <class, class>
@@ -205,6 +229,7 @@ namespace cereal
template <class, class> template <class, class>
static no test2(...); static no test2(...);
static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value; static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value;
#endif // NOT CEREAL_OLDER_GCC
}; };
} // end namespace detail } // end namespace detail
@@ -224,6 +249,21 @@ namespace cereal
template <class T, class A> template <class T, class A>
struct has_member_versioned_save_impl struct has_member_versioned_save_impl
{ {
#ifdef CEREAL_OLDER_GCC
template <class TT, class AA, class SFINAE = void>
struct test : no {};
template <class TT, class AA>
struct test<TT, AA,
typename Void< decltype( cereal::access::member_save( std::declval<AA&>(), std::declval<TT const &>(), 0 ) ) >::type> : yes {};
static const bool value = test<T, A>();
template <class TT, class AA, class SFINAE = void>
struct test2 : no {};
template <class TT, class AA>
struct test2<TT, AA,
typename Void< decltype( cereal::access::member_save_non_const( std::declval<AA&>(), std::declval<typename std::remove_const<TT>::type&>(), 0 ) ) >::type> : yes {};
static const bool not_const_type = test2<T, A>();
#else // NOT CEREAL_OLDER_GCC =========================================
template <class TT, class AA> template <class TT, class AA>
static auto test(int) -> decltype( cereal::access::member_save( std::declval<AA&>(), std::declval<TT const &>(), 0 ), yes()); static auto test(int) -> decltype( cereal::access::member_save( std::declval<AA&>(), std::declval<TT const &>(), 0 ), yes());
template <class, class> template <class, class>
@@ -235,6 +275,7 @@ namespace cereal
template <class, class> template <class, class>
static no test2(...); static no test2(...);
static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value; static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value;
#endif // NOT_CEREAL_OLDER_GCC
}; };
} // end namespace detail } // end namespace detail

View File

@@ -56,7 +56,7 @@ namespace cereal
//! @internal //! @internal
template<int N, class Variant, class ... Args, class Archive> template<int N, class Variant, class ... Args, class Archive>
typename std::enable_if<N == boost::mpl::size<typename Variant::types>::value, void>::type typename std::enable_if<N == boost::mpl::size<typename Variant::types>::value, void>::type
load_variant(Archive & ar, int target, Variant & variant) load_variant(Archive & /*ar*/, int /*target*/, Variant & /*variant*/)
{ {
throw ::cereal::Exception("Error traversing variant during load"); throw ::cereal::Exception("Error traversing variant during load");
} }

View File

@@ -65,7 +65,11 @@ namespace cereal
typename MapT::mapped_type value; typename MapT::mapped_type value;
ar( make_map_item(key, value) ); ar( make_map_item(key, value) );
#ifdef CEREAL_OLDER_GCC
hint = map.insert( hint, std::make_pair(std::move(key), std::move(value)) );
#else // NOT CEREAL_OLDER_GCC
hint = map.emplace_hint( hint, std::move( key ), std::move( value ) ); hint = map.emplace_hint( hint, std::move( key ), std::move( value ) );
#endif // NOT CEREAL_OLDER_GCC
} }
} }
} }

View File

@@ -62,7 +62,11 @@ namespace cereal
typename SetT::key_type key; typename SetT::key_type key;
ar( key ); ar( key );
#ifdef CEREAL_OLDER_GCC
hint = set.insert( hint, std::move( key ) );
#else // NOT CEREAL_OLDER_GCC
hint = set.emplace_hint( hint, std::move( key ) ); hint = set.emplace_hint( hint, std::move( key ) );
#endif // NOT CEREAL_OLDER_GCC
} }
} }
} }

View File

@@ -45,40 +45,40 @@ struct Archive {};
struct Test struct Test
{ {
template <class Archive> template <class Archive>
void serialzize( Archive & ar ) void serialzize( Archive & )
{ {
std::cout << "hey there" << std::endl; std::cout << "hey there" << std::endl;
} }
template <class Archive> template <class Archive>
void save( Archive & ar ) const void save( Archive & ) const
{ {
std::cout << "saved by the bell" << std::endl; std::cout << "saved by the bell" << std::endl;
} }
template <class Archive> template <class Archive>
void load( Archive & ar ) void load( Archive & )
{ {
std::cout << "locked and loaded" << std::endl; std::cout << "locked and loaded" << std::endl;
} }
template <class Archive> template <class Archive>
static Test * load_and_allocate( Archive & ar ) static Test * load_and_allocate( Archive & )
{ {
return new Test(); return new Test();
} }
}; };
template <class Archive> template <class Archive>
void serialize( Archive & ar, Test & t ) void serialize( Archive &, Test & )
{ } { }
template <class Archive> template <class Archive>
void load( Archive & ar, Test & t ) void load( Archive &, Test & )
{ } { }
template <class Archive> template <class Archive>
void save( Archive & ar, Test const & t ) void save( Archive &, Test const & )
{ } { }
namespace cereal namespace cereal
@@ -87,7 +87,7 @@ namespace cereal
struct LoadAndAllocate<Test> struct LoadAndAllocate<Test>
{ {
template <class Archive> template <class Archive>
static Test * load_and_allocate( Archive & ar ) static Test * load_and_allocate( Archive & )
{ {
return new Test(); return new Test();
} }
@@ -104,7 +104,7 @@ struct B : A
void foo() {} void foo() {}
template <class Archive> template <class Archive>
void serialize( Archive & ar ) void serialize( Archive & )
{ {
std::cout << "i'm in your b" << std::endl; std::cout << "i'm in your b" << std::endl;
} }

View File

@@ -811,8 +811,13 @@ void test_map_memory()
for(int j=0; j<100; ++j) for(int j=0; j<100; ++j)
{ {
#ifdef CEREAL_OLDER_GCC
o_uniqueptrMap.insert( std::make_pair(random_value<int>(gen), std::unique_ptr<int>( new int( random_value<int>(gen) ) )) );
o_sharedptrMap.insert( std::make_pair(random_value<int>(gen), std::make_shared<int>( random_value<int>(gen) )) );
#else // NOT CEREAL_OLDER_GCC
o_uniqueptrMap.emplace( random_value<int>(gen), std::unique_ptr<int>( new int( random_value<int>(gen) ) ) ); o_uniqueptrMap.emplace( random_value<int>(gen), std::unique_ptr<int>( new int( random_value<int>(gen) ) ) );
o_sharedptrMap.emplace( random_value<int>(gen), std::make_shared<int>( random_value<int>(gen) ) ); o_sharedptrMap.emplace( random_value<int>(gen), std::make_shared<int>( random_value<int>(gen) ) );
#endif // NOT CEREAL_OLDER_GCC
} }
std::ostringstream os; std::ostringstream os;