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) );
|
cereal::make_nvp<Archive>(b) );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@endcode */
|
@endcode
|
||||||
|
|
||||||
|
@internal */
|
||||||
template <class T>
|
template <class T>
|
||||||
class NameValuePair : detail::NameValuePairCore
|
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 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
|
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
|
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)) {}
|
NameValuePair( char const * n, T && v ) : name(n), value(const_cast<Type>(v)) {}
|
||||||
|
|
||||||
char const * name;
|
char const * name;
|
||||||
@@ -129,7 +132,8 @@ namespace cereal
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! A specialization of make_nvp<> that simply forwards the value for binary archives
|
//! A specialization of make_nvp<> that simply forwards the value for binary archives
|
||||||
/*! @relates NameValuePair */
|
/*! @relates NameValuePair
|
||||||
|
@internal */
|
||||||
template<class Archive, class T>
|
template<class Archive, class T>
|
||||||
typename
|
typename
|
||||||
std::enable_if<std::is_same<Archive, ::cereal::BinaryInputArchive>::value ||
|
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
|
//! A specialization of make_nvp<> that actually creates an nvp for non-binary archives
|
||||||
/*! @relates NameValuePair */
|
/*! @relates NameValuePair
|
||||||
|
@internal */
|
||||||
template<class Archive, class T>
|
template<class Archive, class T>
|
||||||
typename
|
typename
|
||||||
std::enable_if<!std::is_same<Archive, ::cereal::BinaryInputArchive>::value &&
|
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
|
//! A wrapper around data that can be serialized in a binary fashion
|
||||||
/*! This class is used to demarcate data that can safely be serialized
|
/*! This class is used to demarcate data that can safely be serialized
|
||||||
as a binary chunk of data. Individual archives can then choose how
|
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>
|
template <class T>
|
||||||
struct BinaryData
|
struct BinaryData
|
||||||
{
|
{
|
||||||
@@ -195,7 +202,9 @@ namespace cereal
|
|||||||
they choose to serialize size metadata for containers. For some archive
|
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
|
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
|
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>
|
template <class T>
|
||||||
class SizeTag
|
class SizeTag
|
||||||
{
|
{
|
||||||
@@ -212,6 +221,69 @@ namespace cereal
|
|||||||
|
|
||||||
Type size;
|
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
|
} // namespace cereal
|
||||||
|
|
||||||
#endif // CEREAL_DETAILS_HELPERS_HPP_
|
#endif // CEREAL_DETAILS_HELPERS_HPP_
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#include <cereal/cereal.hpp>
|
#include <cereal/cereal.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
|
||||||
namespace cereal
|
namespace cereal
|
||||||
{
|
{
|
||||||
namespace map_detail
|
namespace map_detail
|
||||||
@@ -40,7 +41,9 @@ namespace cereal
|
|||||||
ar( make_size_tag( map.size() ) );
|
ar( make_size_tag( map.size() ) );
|
||||||
|
|
||||||
for( const auto & i : map )
|
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
|
template <class Archive, class MapT> inline
|
||||||
@@ -57,7 +60,7 @@ namespace cereal
|
|||||||
typename MapT::key_type key;
|
typename MapT::key_type key;
|
||||||
typename MapT::mapped_type value;
|
typename MapT::mapped_type value;
|
||||||
|
|
||||||
ar( key, value );
|
ar( ::cereal::make_map_item(key, value) );
|
||||||
hint = map.insert(hint, {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);
|
assert(e_in == e_out);
|
||||||
|
|
||||||
{
|
{
|
||||||
//std::stringstream os;
|
|
||||||
std::ofstream os("out.xml");
|
std::ofstream os("out.xml");
|
||||||
cereal::XMLOutputArchive oar( os );
|
cereal::XMLOutputArchive oar( os );
|
||||||
|
//cereal::XMLOutputArchive oar( std::cout );
|
||||||
|
|
||||||
oar( cereal::make_nvp("hello", 5 ) );
|
oar( cereal::make_nvp("hello", 5 ) );
|
||||||
|
|
||||||
@@ -311,6 +311,15 @@ int main()
|
|||||||
auto intptr = std::make_shared<int>(99);
|
auto intptr = std::make_shared<int>(99);
|
||||||
oar( CEREAL_NVP(intptr) );
|
oar( CEREAL_NVP(intptr) );
|
||||||
|
|
||||||
|
std::map<std::string, int> map1 =
|
||||||
|
{
|
||||||
|
{"one", 1},
|
||||||
|
{"two", 2},
|
||||||
|
{"three", 3}
|
||||||
|
};
|
||||||
|
|
||||||
|
oar( CEREAL_NVP(map1) );
|
||||||
|
|
||||||
int x = 3;
|
int x = 3;
|
||||||
oar( CEREAL_NVP(x) );
|
oar( CEREAL_NVP(x) );
|
||||||
oar( 5 );
|
oar( 5 );
|
||||||
@@ -353,6 +362,14 @@ int main()
|
|||||||
iar( CEREAL_NVP(intptr) );
|
iar( CEREAL_NVP(intptr) );
|
||||||
assert( *intptr == 99 );
|
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;
|
int x;
|
||||||
iar( CEREAL_NVP(x) );
|
iar( CEREAL_NVP(x) );
|
||||||
assert( x == 3 );
|
assert( x == 3 );
|
||||||
|
|||||||
Reference in New Issue
Block a user