Skip to content

Commit 6d8bdd8

Browse files
committed
Split lookup and exists check in PolymorphicCasters into two functions.
Fixes a bug related to lookup, see USCiLab#291 Also changed from bool to uint8_t for USCiLab#306 Updated gitignore for MSVC junk
1 parent ac07952 commit 6d8bdd8

File tree

4 files changed

+35
-9
lines changed

4 files changed

+35
-9
lines changed

.gitignore

+5-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
*/Release*
2323
*.log
2424
*.tlog*
25+
*.obj
26+
*.VC.db
27+
*.VC.VC.opendb
28+
*.pdb
2529

2630
# misc files mostly used for testing
2731
out.txt
@@ -42,4 +46,4 @@ out.xml
4246
cereal_version.out
4347
xml_ordering.out
4448
build
45-
/out/
49+
/out/

include/cereal/archives/portable_binary.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ namespace cereal
3939
{
4040
//! Returns true if the current machine is little endian
4141
/*! @ingroup Internal */
42-
inline bool is_little_endian()
42+
inline std::uint8_t is_little_endian()
4343
{
4444
static std::int32_t test = 1;
4545
return *reinterpret_cast<std::int8_t*>( &test ) == 1;
@@ -106,7 +106,7 @@ namespace cereal
106106
{ return portable_binary_detail::is_little_endian() ? Endianness::little : Endianness::big; }
107107

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

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

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

212212
friend class PortableBinaryInputArchive;

include/cereal/details/polymorphic_impl.hpp

+26-4
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,26 @@ namespace cereal
122122
"Make sure you either serialize the base class at some point via cereal::base_class or cereal::virtual_base_class.\n" \
123123
"Alternatively, manually register the association with CEREAL_REGISTER_POLYMORPHIC_RELATION.");
124124

125+
//! Checks if the mapping object that can perform the upcast or downcast
126+
/*! Uses the type index from the base and derived class to find the matching
127+
registered caster. If no matching caster exists, returns false. */
128+
static bool exists( std::type_index const & baseIndex, std::type_index const & derivedIndex )
129+
{
130+
// First phase of lookup - match base type index
131+
auto & baseMap = StaticObject<PolymorphicCasters>::getInstance().map;
132+
auto baseIter = baseMap.find( baseIndex );
133+
if (baseIter == baseMap.end())
134+
return false;
135+
136+
// Second phase - find a match from base to derived
137+
auto & derivedMap = baseIter->second;
138+
auto derivedIter = derivedMap.find( derivedIndex );
139+
if (derivedIter == derivedMap.end())
140+
return false;
141+
142+
return true;
143+
}
144+
125145
//! Gets the mapping object that can perform the upcast or downcast
126146
/*! Uses the type index from the base and derived class to find the matching
127147
registered caster. If no matching caster exists, calls the exception function.
@@ -141,7 +161,7 @@ namespace cereal
141161
auto derivedIter = derivedMap.find( derivedIndex );
142162
if( derivedIter == derivedMap.end() )
143163
exceptionFunc();
144-
164+
145165
return derivedIter->second;
146166
}
147167

@@ -215,9 +235,9 @@ namespace cereal
215235
{
216236
auto checkRelation = [](std::type_index const & baseInfo, std::type_index const & derivedInfo)
217237
{
218-
bool exists = true;
219-
auto const & mapping = PolymorphicCasters::lookup( baseInfo, derivedInfo, [&](){ exists = false; } );
220-
return std::make_pair( exists, exists ? mapping : std::vector<PolymorphicCaster const *>{} );
238+
const bool exists = PolymorphicCasters::exists( baseInfo, derivedInfo );
239+
return std::make_pair( exists, exists ? PolymorphicCasters::lookup( baseInfo, derivedInfo, [](){} ) :
240+
std::vector<PolymorphicCaster const *>{} );
221241
};
222242

223243
for( auto baseIt : baseMap )
@@ -599,6 +619,7 @@ namespace cereal
599619
#endif // _MSC_VER
600620
};
601621

622+
//#if defined(_WINDLL)
602623
// instantiate implementation
603624
template <class Archive, class T>
604625
CEREAL_DLL_EXPORT void polymorphic_serialization_support<Archive,T>::instantiate()
@@ -611,6 +632,7 @@ namespace cereal
611632
std::is_base_of<detail::InputArchiveBase, Archive>::value &&
612633
traits::is_input_serializable<T, Archive>::value>{} );
613634
}
635+
//#endif
614636

615637
//! Begins the binding process of a type to all registered archives
616638
/*! Archives need to be registered prior to this struct being instantiated via

unittests/portable_binary_archive.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ inline void swapBytes( T & t )
7777

7878
// Last parameter exists to keep everything hidden in options
7979
template <class IArchive, class OArchive>
80-
void test_endian_serialization( typename IArchive::Options const & iOptions, typename OArchive::Options const & oOptions, const bool inputLittleEndian )
80+
void test_endian_serialization( typename IArchive::Options const & iOptions, typename OArchive::Options const & oOptions, const std::uint8_t inputLittleEndian )
8181
{
8282
std::random_device rd;
8383
std::mt19937 gen(rd());

0 commit comments

Comments
 (0)