Skip to content

Commit

Permalink
Split lookup and exists check in PolymorphicCasters into two functions.
Browse files Browse the repository at this point in the history
Fixes a bug related to lookup, see #291

Also changed from bool to uint8_t for #306

Updated gitignore for MSVC junk
  • Loading branch information
AzothAmmo committed Jun 29, 2016
1 parent ac07952 commit 6d8bdd8
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 9 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
*/Release*
*.log
*.tlog*
*.obj
*.VC.db
*.VC.VC.opendb
*.pdb

# misc files mostly used for testing
out.txt
Expand All @@ -42,4 +46,4 @@ out.xml
cereal_version.out
xml_ordering.out
build
/out/
/out/
6 changes: 3 additions & 3 deletions include/cereal/archives/portable_binary.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace cereal
{
//! Returns true if the current machine is little endian
/*! @ingroup Internal */
inline bool is_little_endian()
inline std::uint8_t is_little_endian()
{
static std::int32_t test = 1;
return *reinterpret_cast<std::int8_t*>( &test ) == 1;
Expand Down Expand Up @@ -106,7 +106,7 @@ namespace cereal
{ return portable_binary_detail::is_little_endian() ? Endianness::little : Endianness::big; }

//! Checks if Options is set for little endian
inline bool is_little_endian() const
inline std::uint8_t is_little_endian() const
{ return itsOutputEndianness == Endianness::little; }

friend class PortableBinaryOutputArchive;
Expand Down Expand Up @@ -206,7 +206,7 @@ namespace cereal
{ return portable_binary_detail::is_little_endian() ? Endianness::little : Endianness::big; }

//! Checks if Options is set for little endian
inline bool is_little_endian() const
inline std::uint8_t is_little_endian() const
{ return itsInputEndianness == Endianness::little; }

friend class PortableBinaryInputArchive;
Expand Down
30 changes: 26 additions & 4 deletions include/cereal/details/polymorphic_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,26 @@ namespace cereal
"Make sure you either serialize the base class at some point via cereal::base_class or cereal::virtual_base_class.\n" \
"Alternatively, manually register the association with CEREAL_REGISTER_POLYMORPHIC_RELATION.");

//! Checks if the mapping object that can perform the upcast or downcast
/*! Uses the type index from the base and derived class to find the matching
registered caster. If no matching caster exists, returns false. */
static bool exists( std::type_index const & baseIndex, std::type_index const & derivedIndex )
{
// First phase of lookup - match base type index
auto & baseMap = StaticObject<PolymorphicCasters>::getInstance().map;
auto baseIter = baseMap.find( baseIndex );
if (baseIter == baseMap.end())
return false;

// Second phase - find a match from base to derived
auto & derivedMap = baseIter->second;
auto derivedIter = derivedMap.find( derivedIndex );
if (derivedIter == derivedMap.end())
return false;

return true;
}

//! Gets the mapping object that can perform the upcast or downcast
/*! Uses the type index from the base and derived class to find the matching
registered caster. If no matching caster exists, calls the exception function.
Expand All @@ -141,7 +161,7 @@ namespace cereal
auto derivedIter = derivedMap.find( derivedIndex );
if( derivedIter == derivedMap.end() )
exceptionFunc();

return derivedIter->second;
}

Expand Down Expand Up @@ -215,9 +235,9 @@ namespace cereal
{
auto checkRelation = [](std::type_index const & baseInfo, std::type_index const & derivedInfo)
{
bool exists = true;
auto const & mapping = PolymorphicCasters::lookup( baseInfo, derivedInfo, [&](){ exists = false; } );
return std::make_pair( exists, exists ? mapping : std::vector<PolymorphicCaster const *>{} );
const bool exists = PolymorphicCasters::exists( baseInfo, derivedInfo );
return std::make_pair( exists, exists ? PolymorphicCasters::lookup( baseInfo, derivedInfo, [](){} ) :
std::vector<PolymorphicCaster const *>{} );
};

for( auto baseIt : baseMap )
Expand Down Expand Up @@ -599,6 +619,7 @@ namespace cereal
#endif // _MSC_VER
};

//#if defined(_WINDLL)
// instantiate implementation
template <class Archive, class T>
CEREAL_DLL_EXPORT void polymorphic_serialization_support<Archive,T>::instantiate()
Expand All @@ -611,6 +632,7 @@ namespace cereal
std::is_base_of<detail::InputArchiveBase, Archive>::value &&
traits::is_input_serializable<T, Archive>::value>{} );
}
//#endif

//! Begins the binding process of a type to all registered archives
/*! Archives need to be registered prior to this struct being instantiated via
Expand Down
2 changes: 1 addition & 1 deletion unittests/portable_binary_archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ inline void swapBytes( T & t )

// Last parameter exists to keep everything hidden in options
template <class IArchive, class OArchive>
void test_endian_serialization( typename IArchive::Options const & iOptions, typename OArchive::Options const & oOptions, const bool inputLittleEndian )
void test_endian_serialization( typename IArchive::Options const & iOptions, typename OArchive::Options const & oOptions, const std::uint8_t inputLittleEndian )
{
std::random_device rd;
std::mt19937 gen(rd());
Expand Down

0 comments on commit 6d8bdd8

Please sign in to comment.