mirror of
https://github.com/USCiLab/cereal.git
synced 2025-10-18 01:45:52 +02:00
Added a MapItem to wrap key/value pairs
This commit is contained in:
@@ -99,7 +99,9 @@ namespace cereal
|
||||
cereal::make_nvp<Archive>(b) );
|
||||
}
|
||||
};
|
||||
@endcode */
|
||||
@endcode
|
||||
|
||||
@internal */
|
||||
template <class T>
|
||||
class NameValuePair : detail::NameValuePairCore
|
||||
{
|
||||
@@ -121,7 +123,8 @@ namespace cereal
|
||||
the value can be both loaded and saved to. If you pass an r-value reference,
|
||||
the NameValuePair will store a copy of it instead of a reference. Thus you should
|
||||
only pass r-values in cases where this makes sense, such as the result of some
|
||||
size() call. In either case, any constness will be stripped away */
|
||||
size() call. In either case, any constness will be stripped away
|
||||
@internal */
|
||||
NameValuePair( char const * n, T && v ) : name(n), value(const_cast<Type>(v)) {}
|
||||
|
||||
char const * name;
|
||||
@@ -129,7 +132,8 @@ namespace cereal
|
||||
};
|
||||
|
||||
//! A specialization of make_nvp<> that simply forwards the value for binary archives
|
||||
/*! @relates NameValuePair */
|
||||
/*! @relates NameValuePair
|
||||
@internal */
|
||||
template<class Archive, class T>
|
||||
typename
|
||||
std::enable_if<std::is_same<Archive, ::cereal::BinaryInputArchive>::value ||
|
||||
@@ -141,7 +145,8 @@ namespace cereal
|
||||
}
|
||||
|
||||
//! A specialization of make_nvp<> that actually creates an nvp for non-binary archives
|
||||
/*! @relates NameValuePair */
|
||||
/*! @relates NameValuePair
|
||||
@internal */
|
||||
template<class Archive, class T>
|
||||
typename
|
||||
std::enable_if<!std::is_same<Archive, ::cereal::BinaryInputArchive>::value &&
|
||||
@@ -157,7 +162,9 @@ namespace cereal
|
||||
//! A wrapper around data that can be serialized in a binary fashion
|
||||
/*! This class is used to demarcate data that can safely be serialized
|
||||
as a binary chunk of data. Individual archives can then choose how
|
||||
best represent this during serialization. */
|
||||
best represent this during serialization.
|
||||
|
||||
@internal */
|
||||
template <class T>
|
||||
struct BinaryData
|
||||
{
|
||||
@@ -195,7 +202,9 @@ namespace cereal
|
||||
they choose to serialize size metadata for containers. For some archive
|
||||
types, the size may be implicitly encoded in the output (e.g. JSON) and
|
||||
not need an explicit entry. Specializing serialize or load/save for
|
||||
your archive and SizeTags allows you to choose what happens */
|
||||
your archive and SizeTags allows you to choose what happens
|
||||
|
||||
@internal */
|
||||
template <class T>
|
||||
class SizeTag
|
||||
{
|
||||
@@ -212,6 +221,69 @@ namespace cereal
|
||||
|
||||
Type size;
|
||||
};
|
||||
|
||||
// ######################################################################
|
||||
//! A wrapper around a key and value for serializing data into maps.
|
||||
/*! This class just provides a grouping of keys and values into a struct for
|
||||
human readable archives. For example, XML archives will use this wrapper
|
||||
to write maps like so:
|
||||
|
||||
@code{.xml}
|
||||
<mymap>
|
||||
<item0>
|
||||
<key>MyFirstKey</key>
|
||||
<value>MyFirstValue</value>
|
||||
</item0>
|
||||
<item1>
|
||||
<key>MySecondKey</key>
|
||||
<value>MySecondValue</value>
|
||||
</item1>
|
||||
</mymap>
|
||||
@endcode
|
||||
|
||||
\sa make_map_item
|
||||
@internal */
|
||||
template <class Key, class Value>
|
||||
struct MapItem
|
||||
{
|
||||
using DecayKey = typename std::decay<Key>::type;
|
||||
using KeyType = typename std::conditional<
|
||||
std::is_rvalue_reference<Key>::value,
|
||||
DecayKey,
|
||||
typename std::add_lvalue_reference<DecayKey>::type>::type;
|
||||
|
||||
using DecayValue = typename std::decay<Value>::type;
|
||||
using ValueType = typename std::conditional<
|
||||
std::is_rvalue_reference<Value>::value,
|
||||
DecayValue,
|
||||
typename std::add_lvalue_reference<DecayValue>::type>::type;
|
||||
|
||||
//! Construct a MapItem from a key and a value
|
||||
/*! @internal */
|
||||
MapItem( Key && key, Value && value ) : key(const_cast<KeyType>(key)), value(const_cast<ValueType>(value)) {}
|
||||
|
||||
KeyType key;
|
||||
ValueType value;
|
||||
|
||||
//! Serialize the MapItem with the NVPs "key" and "value"
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive)
|
||||
{
|
||||
archive( make_nvp<Archive>("key", key),
|
||||
make_nvp<Archive>("value", value) );
|
||||
}
|
||||
};
|
||||
|
||||
//! Create a MapItem so that human readable archives will group keys and values together
|
||||
/*! @internal
|
||||
@relates MapItem */
|
||||
template<class KeyType, class ValueType>
|
||||
MapItem<KeyType, ValueType> make_map_item(KeyType && key, ValueType && value)
|
||||
{
|
||||
return {std::forward<KeyType>(key), std::forward<ValueType>(value)};
|
||||
}
|
||||
|
||||
|
||||
} // namespace cereal
|
||||
|
||||
#endif // CEREAL_DETAILS_HELPERS_HPP_
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <cereal/cereal.hpp>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace cereal
|
||||
{
|
||||
namespace map_detail
|
||||
@@ -40,7 +41,9 @@ namespace cereal
|
||||
ar( make_size_tag( map.size() ) );
|
||||
|
||||
for( const auto & i : map )
|
||||
ar( i.first, i.second );
|
||||
{
|
||||
ar( ::cereal::make_map_item(i.first, i.second) );
|
||||
}
|
||||
}
|
||||
|
||||
template <class Archive, class MapT> inline
|
||||
@@ -57,7 +60,7 @@ namespace cereal
|
||||
typename MapT::key_type key;
|
||||
typename MapT::mapped_type value;
|
||||
|
||||
ar( key, value );
|
||||
ar( ::cereal::make_map_item(key, value) );
|
||||
hint = map.insert(hint, {key, value} );
|
||||
}
|
||||
}
|
||||
|
||||
19
sandbox.cpp
19
sandbox.cpp
@@ -299,9 +299,9 @@ int main()
|
||||
assert(e_in == e_out);
|
||||
|
||||
{
|
||||
//std::stringstream os;
|
||||
std::ofstream os("out.xml");
|
||||
cereal::XMLOutputArchive oar( os );
|
||||
//cereal::XMLOutputArchive oar( std::cout );
|
||||
|
||||
oar( cereal::make_nvp("hello", 5 ) );
|
||||
|
||||
@@ -311,6 +311,15 @@ int main()
|
||||
auto intptr = std::make_shared<int>(99);
|
||||
oar( CEREAL_NVP(intptr) );
|
||||
|
||||
std::map<std::string, int> map1 =
|
||||
{
|
||||
{"one", 1},
|
||||
{"two", 2},
|
||||
{"three", 3}
|
||||
};
|
||||
|
||||
oar( CEREAL_NVP(map1) );
|
||||
|
||||
int x = 3;
|
||||
oar( CEREAL_NVP(x) );
|
||||
oar( 5 );
|
||||
@@ -353,6 +362,14 @@ int main()
|
||||
iar( CEREAL_NVP(intptr) );
|
||||
assert( *intptr == 99 );
|
||||
|
||||
std::map<std::string, int> map1;
|
||||
|
||||
iar( CEREAL_NVP(map1) );
|
||||
assert( map1["one"] == 1 );
|
||||
assert( map1["two"] == 2 );
|
||||
assert( map1["three"] == 3 );
|
||||
|
||||
|
||||
int x;
|
||||
iar( CEREAL_NVP(x) );
|
||||
assert( x == 3 );
|
||||
|
||||
Reference in New Issue
Block a user