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
CXX=g++-4.7
CXX=g++
COVERAGE_OUTPUT=out
all: unittests sandbox performance sandbox_rtti sandbox_json
all: unittests sandbox sandbox_vs performance sandbox_rtti sandbox_json
sandbox: sandbox.cpp
${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
/*! 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. */
#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) \
namespace detail \
{ \
@ -116,6 +124,7 @@ namespace cereal
} /* end namespace detail */ \
template <class T, class A> \
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
/*! 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>
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>
static auto test(int) -> decltype( cereal::access::member_save( std::declval<AA&>(), std::declval<TT const &>() ), yes());
template <class, class>
@ -205,6 +229,7 @@ namespace cereal
template <class, class>
static no test2(...);
static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value;
#endif // NOT CEREAL_OLDER_GCC
};
} // end namespace detail
@ -224,6 +249,21 @@ namespace cereal
template <class T, class A>
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>
static auto test(int) -> decltype( cereal::access::member_save( std::declval<AA&>(), std::declval<TT const &>(), 0 ), yes());
template <class, class>
@ -235,6 +275,7 @@ namespace cereal
template <class, class>
static no test2(...);
static const bool not_const_type = std::is_same<decltype(test2<T, A>(0)), yes>::value;
#endif // NOT_CEREAL_OLDER_GCC
};
} // end namespace detail

View File

@ -56,7 +56,7 @@ namespace cereal
//! @internal
template<int N, class Variant, class ... Args, class Archive>
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");
}

View File

@ -65,7 +65,11 @@ namespace cereal
typename MapT::mapped_type 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 ) );
#endif // NOT CEREAL_OLDER_GCC
}
}
}

View File

@ -62,7 +62,11 @@ namespace cereal
typename SetT::key_type 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 ) );
#endif // NOT CEREAL_OLDER_GCC
}
}
}

View File

@ -45,40 +45,40 @@ struct Archive {};
struct Test
{
template <class Archive>
void serialzize( Archive & ar )
void serialzize( Archive & )
{
std::cout << "hey there" << std::endl;
}
template <class Archive>
void save( Archive & ar ) const
void save( Archive & ) const
{
std::cout << "saved by the bell" << std::endl;
}
template <class Archive>
void load( Archive & ar )
void load( Archive & )
{
std::cout << "locked and loaded" << std::endl;
}
template <class Archive>
static Test * load_and_allocate( Archive & ar )
static Test * load_and_allocate( Archive & )
{
return new Test();
}
};
template <class Archive>
void serialize( Archive & ar, Test & t )
void serialize( Archive &, Test & )
{ }
template <class Archive>
void load( Archive & ar, Test & t )
void load( Archive &, Test & )
{ }
template <class Archive>
void save( Archive & ar, Test const & t )
void save( Archive &, Test const & )
{ }
namespace cereal
@ -87,7 +87,7 @@ namespace cereal
struct LoadAndAllocate<Test>
{
template <class Archive>
static Test * load_and_allocate( Archive & ar )
static Test * load_and_allocate( Archive & )
{
return new Test();
}
@ -104,7 +104,7 @@ struct B : A
void foo() {}
template <class Archive>
void serialize( Archive & ar )
void serialize( Archive & )
{
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)
{
#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_sharedptrMap.emplace( random_value<int>(gen), std::make_shared<int>( random_value<int>(gen) ) );
#endif // NOT CEREAL_OLDER_GCC
}
std::ostringstream os;