2022-05-09 20:28:13 +02:00
// Copyright (c) 2014-2022 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# pragma once
2024-10-18 00:26:30 +04:00
# include <type_traits>
2024-10-23 15:05:46 +04:00
# ifndef DISABLE_PFR_SERIALIZATION_SELFCHECK
2024-10-23 15:01:43 +04:00
# include <boost/pfr.hpp>
2024-10-23 14:47:02 +04:00
# endif
2024-08-12 20:09:22 +02:00
# define BEGIN_BOOST_SERIALIZATION() template <class t_archive> void serialize(t_archive &_arch, const unsigned int ver) {
2022-05-09 20:28:13 +02:00
2023-06-16 20:19:49 +02:00
template < size_t A , size_t B > struct TAssertEquality {
static_assert ( A = = B , " Serialization map is not updated, sizeof() missmatch " ) ;
static constexpr bool _cResult = ( A = = B ) ;
} ;
//experemental feature: self-validated serialization map, needed to not forget add new members to serialization maps
# define BEGIN_BOOST_SERIALIZATION_SV(sz) BEGIN_BOOST_SERIALIZATION() \
static constexpr bool _cIsEqual = TAssertEquality < sz , sizeof ( * this ) > : : _cResult ;
2022-05-09 20:28:13 +02:00
# define BOOST_SERIALIZE(x) _arch & x;
2023-10-31 18:29:57 +01:00
# define BOOST_SERIALIZE_BASE_CLASS(class_type) _arch & static_cast<class_type&>(*this);
2022-05-09 20:28:13 +02:00
2023-08-03 20:01:41 +02:00
# define BOOST_END_VERSION_UNDER(x) \
2023-08-15 16:52:53 +02:00
if ( ver < x ) { return ; }
2023-08-03 20:01:41 +02:00
2022-05-09 20:28:13 +02:00
# define END_BOOST_SERIALIZATION() }
2024-10-18 00:26:30 +04:00
/**********************************************************************************************************************************
This serialization closing macro adds self - validation by checking the total number of fields in the structure using boost : : pfr .
Note : " num_fields " does NOT represent the number of fields included in the serialization . Instead , it indicates the total number
of fields in the structure , some of which might not be included in the serialization for valid reasons . If someone adds new
fields to the structure but forgets to update the serialization map , the compilation will fail . Any update to " num_fields " must
be accompanied by a thorough review of the serialization map to ensure no fields are omitted .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2024-10-23 15:05:46 +04:00
# ifndef DISABLE_PFR_SERIALIZATION_SELFCHECK
2024-10-23 14:47:02 +04:00
# define END_BOOST_SERIALIZATION_TOTAL_FIELDS(num_fields) static_assert(num_fields == boost::pfr::tuple_size<std::remove_reference<decltype(*this)>::type>::value, "Unexpected number of fields!"); }
# else
# define END_BOOST_SERIALIZATION_TOTAL_FIELDS(num_fields) END_BOOST_SERIALIZATION()
# endif
2024-10-18 00:26:30 +04:00
# define BOOST_SERIALIZATION_CURRENT_ARCHIVE_VER(current_version) static const unsigned int current_boost_version_serialization_version = current_version;
# define LOOP_BACK_BOOST_SERIALIZATION_VERSION(type) BOOST_CLASS_VERSION(type, type::current_boost_version_serialization_version);
template < bool IsSaving , typename destination_t >
struct boost_transition_t { } ;
template < typename destination_t >
struct boost_transition_t < true , destination_t >
{
template < typename archive , typename origin_type >
static void chain_serialize ( archive & ar , const origin_type & origin_tx )
{
destination_t dst_tx = AUTO_VAL_INIT ( dst_tx ) ;
transition_convert ( origin_tx , dst_tx ) ;
ar & dst_tx ;
}
} ;
template < typename destination_t >
struct boost_transition_t < false , destination_t >
{
template < typename archive , typename origin_type >
static void chain_serialize ( archive & ar , origin_type & origin_tx )
{
// TODO: consider using move semantic for temporary 'dst_tx'
destination_t dst_tx = AUTO_VAL_INIT ( dst_tx ) ;
ar & dst_tx ;
transition_convert ( dst_tx , origin_tx ) ;
}
} ;
# define BOOST_CHAIN_TRANSITION_VER(obj_version, old_type) if (obj_version == ver) {boost_transition_t<t_archive::is_saving::value, old_type>::chain_serialize(_arch, *this);return;}
# define BOOST_CHAIN_TRANSITION_IF_COND_TRUE(condition, old_type) if (condition) {boost_transition_t<t_archive::is_saving::value, old_type>::chain_serialize(_arch, *this);return;}
2022-05-09 20:28:13 +02:00
/*
example of use :
struct tx_extra_info
{
crypto : : public_key m_tx_pub_key ;
extra_alias_entry m_alias ;
std : : string m_user_data_blob ;
extra_attachment_info m_attachment_info ;
BEGIN_BOOST_SERIALIZATION ( )
BOOST_SERIALIZE ( m_tx_pub_key )
BOOST_SERIALIZE ( m_alias )
if ( ver < xxx ) return ;
BOOST_SERIALIZE ( m_user_data_blob )
BOOST_SERIALIZE ( m_attachment_info )
END_BOOST_SERIALIZATION ( )
} ;
*/