mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-06-25 14:50:54 -04:00
Better usage of type traits
Don't need register types for serializationanymore Don't need casting helpers for serialization
This commit is contained in:
parent
ba6f2d7e81
commit
8b774595d7
12 changed files with 145 additions and 279 deletions
|
@ -17,8 +17,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
#include "serialiser/rsserializer.h"
|
||||
|
||||
|
||||
|
@ -38,7 +36,6 @@ struct RsSerializable
|
|||
RsGenericSerializer::SerializeContext& ctx) = 0;
|
||||
};
|
||||
|
||||
|
||||
/** @def RS_SERIAL_PROCESS(I)
|
||||
* Use this macro to register the members of `YourSerializable` for serial
|
||||
* processing inside `YourSerializable::serial_process(j, ctx)`
|
||||
|
@ -47,110 +44,8 @@ struct RsSerializable
|
|||
* specifying the underlying type otherwise the serialization format may differ
|
||||
* in an uncompatible way depending on the compiler/platform.
|
||||
*
|
||||
* If your member is a derivative of RsSerializable in some cases it may be
|
||||
* convenient also to register your item type with
|
||||
* @see RS_REGISTER_SERIALIZABLE_TYPE_DEF(T).
|
||||
*
|
||||
* Inspired by http://stackoverflow.com/a/39345864
|
||||
*/
|
||||
#define RS_SERIAL_PROCESS(I) do { \
|
||||
RsTypeSerializer::serial_process(j, ctx, __priv_to_RS_S_TYPE(I), #I ); \
|
||||
RsTypeSerializer::serial_process(j, ctx, I, #I ); \
|
||||
} while(0)
|
||||
|
||||
|
||||
/** @def RS_REGISTER_SERIALIZABLE_TYPE_DEF(T)
|
||||
* Use this macro into `youritem.cc` only if you need to process members of
|
||||
* subtypes of RsSerializable.
|
||||
*
|
||||
* The usage of this macro is strictly needed only in some cases, for example if
|
||||
* you are registering for serialization a member of a container that contains
|
||||
* items of subclasses of RsSerializable like
|
||||
* `std::map<uint64_t, RsChatMsgItem>`
|
||||
*
|
||||
* @code{.cpp}
|
||||
struct PrivateOugoingMapItem : RsChatItem
|
||||
{
|
||||
PrivateOugoingMapItem() : RsChatItem(RS_PKT_SUBTYPE_OUTGOING_MAP) {}
|
||||
|
||||
void serial_process( RsGenericSerializer::SerializeJob j,
|
||||
RsGenericSerializer::SerializeContext& ctx );
|
||||
|
||||
std::map<uint64_t, RsChatMsgItem> store;
|
||||
};
|
||||
|
||||
RS_REGISTER_SERIALIZABLE_TYPE_DEF(RsChatMsgItem)
|
||||
|
||||
void PrivateOugoingMapItem::serial_process(
|
||||
RsGenericSerializer::SerializeJob j,
|
||||
RsGenericSerializer::SerializeContext& ctx )
|
||||
{
|
||||
RS_SERIAL_PROCESS(store);
|
||||
}
|
||||
* @endcode
|
||||
*/
|
||||
#define RS_REGISTER_SERIALIZABLE_TYPE_DEF(T) template<> /*static*/\
|
||||
void RsTypeSerializer::serial_process<T>( \
|
||||
RsGenericSerializer::SerializeJob j,\
|
||||
RsGenericSerializer::SerializeContext& ctx, T& item,\
|
||||
const std::string& objName ) \
|
||||
{ \
|
||||
RsTypeSerializer::serial_process<RsSerializable>( j, \
|
||||
ctx, static_cast<RsSerializable&>(item), objName ); \
|
||||
}
|
||||
|
||||
|
||||
/** @def RS_REGISTER_SERIALIZABLE_TYPE_DECL(T)
|
||||
* The usage of this macro into your header file may be needed only in case you
|
||||
* needed @see RS_REGISTER_SERIALIZABLE_TYPE_DEF(T) in your definitions file,
|
||||
* but it was not enough and the compiler kept complanining about undefined
|
||||
* references to serialize, deserialize, serial_size, print_data, to_JSON,
|
||||
* from_JSON for your RsSerializable derived type.
|
||||
*
|
||||
* One example of such case is RsIdentityUsage that is declared in
|
||||
* retroshare/rsidentity.h but defined in services/p3idservice.cc, also if
|
||||
* RS_REGISTER_SERIALIZABLE_TYPE_DEF(RsIdentityUsage) was used in p3idservice.cc
|
||||
* for some reason it was not enough for the compiler to see it so
|
||||
* RS_REGISTER_SERIALIZABLE_TYPE_DECL(RsIdentityUsage) has been added in
|
||||
* rsidentity.h too and now the compiler is happy.
|
||||
*/
|
||||
#define RS_REGISTER_SERIALIZABLE_TYPE_DECL(T) template<> /*static*/\
|
||||
void RsTypeSerializer::serial_process<T>( \
|
||||
RsGenericSerializer::SerializeJob j,\
|
||||
RsGenericSerializer::SerializeContext& ctx, T& item,\
|
||||
const std::string& objName );
|
||||
|
||||
|
||||
//============================================================================//
|
||||
// Private type conversion helpers //
|
||||
//============================================================================//
|
||||
|
||||
/**
|
||||
* @brief Privates type conversion helpers for RS_SERIAL_PROCESS.
|
||||
* @private DO NOT use explicitely outside this file.
|
||||
* Used to cast enums and derived type to matching types supported by
|
||||
* RsTypeSerializer::serial_process(...) templated methods.
|
||||
*/
|
||||
template<typename T, typename = typename std::enable_if<std::is_enum<T>::value>::type>
|
||||
inline typename std::underlying_type<T>::type& __priv_to_RS_S_TYPE(T& i)
|
||||
{
|
||||
return reinterpret_cast<typename std::underlying_type<T>::type&>(i);
|
||||
}
|
||||
|
||||
template<typename T, typename = typename std::enable_if<std::is_base_of<RsSerializable, T>::value>::type>
|
||||
inline RsSerializable& __priv_to_RS_S_TYPE(T& i)
|
||||
{
|
||||
return static_cast<RsSerializable&>(i);
|
||||
}
|
||||
|
||||
struct RsTlvItem;
|
||||
template<typename T, typename = typename std::enable_if<std::is_base_of<RsTlvItem, T>::value>::type>
|
||||
inline RsTlvItem& __priv_to_RS_S_TYPE(T& i)
|
||||
{
|
||||
return static_cast<RsTlvItem&>(i);
|
||||
}
|
||||
|
||||
template<typename T, typename = typename std::enable_if<!(std::is_enum<T>::value||std::is_base_of<RsTlvItem, T>::value||std::is_base_of<RsSerializable, T>::value)>::type>
|
||||
inline T& __priv_to_RS_S_TYPE(T& i)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue