
Re: [Serialization] is_serializable trait? (Chris Fairles)
I also took a stab at making a boostified version:
#include <iostream> #include <boost/type_traits/config.hpp> #include <boost/utility/enable_if.hpp> #include <boost/type_traits/is_fundamental.hpp> #include <boost/type_traits/detail/yes_no_type.hpp> #include <boost/type_traits/detail/bool_trait_def.hpp>
namespace boost { namespace detail {
template <class T> struct has_serialize_mem_fun { typedef void (T::*SerializationFun)(int &, unsigned);
template <SerializationFun> struct A {};
template <class Q> static ::boost::type_traits::yes_type has_serialize_mem_fun_tester(A<&Q::serialize>*);
template <class Q> static ::boost::type_traits::no_type has_serialize_mem_fun_tester(...);
BOOST_STATIC_CONSTANT(bool, value = (sizeof(has_serialize_mem_fun_tester<T>(0)) == sizeof(::boost::type_traits::yes_type)));
}; template <typename T, typename IsFundamental = void> struct is_serializable_impl { BOOST_STATIC_CONSTANT(bool, value = has_serialize_mem_fun<T>::value); };
template <typename T> struct is_serializable_impl<T, typename ::boost::enable_if< ::boost::is_fundamental<T> >::type> { BOOST_STATIC_CONSTANT(bool, value = true); }; }
BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_serializable,T,::boost::detail::is_serializable_impl<T>::value)
}
struct A { template <class Stream> void serialize(Stream & strm, unsigned version) {} };
struct B {};
struct C { void serialize() {} };
int main() { using namespace std; cout << boolalpha << boost::is_serializable<A>::value << '\n' // true << boost::is_serializable<int>::value << '\n' // true << boost::is_serializable<float>::value << '\n' // true << boost::is_serializable<double>::value << '\n' // true << boost::is_serializable<char>::value << '\n' // true << boost::is_serializable<B>::value << '\n' // false << boost::is_serializable<C>::value << '\n' // false << boost::is_serializable<string>::value << endl; //false but should be true }
Needs specializations for standard containers as well but this suits my needs currently. Thoughts?
I tried to implement is_non_intrusively_serializable metafunction, but found no general solution. Although I've impelented it for all types which are instances of some class template. For example, it works correctly for vector<int>, some_class<double, string>, etc. Note that it is possible to create metafunction which determines whether type is instance of class template or not. So, we have the following: - is_intrusivelly_serializable metafunction. - is_class_template_instance metafunction. - is_non_intrusively_serializable metafunction, which currently works only for class template instances. Probably someone can implement the last missing case? That is we need is_non_intrusively_serializable implementation for types, which are not class template instances (int, some_nontemplate_class, etc). Here is is_non_intrusively_serializable restricted to class templates. #include <boost/serialization/serialization.hpp> #include <boost/type_traits/remove_cv.hpp> #include <boost/type_traits/detail/yes_no_type.hpp> #include <boost/preprocessor.hpp> #include <boost/static_assert.hpp> #include <boost/serialization/vector.hpp> namespace detail { struct tag {}; using boost::serialization::serialize; #define BOOST_PP_LOCAL_LIMITS (1, 10) #define BOOST_PP_LOCAL_MACRO(N) \ template < \ class Archive, \ template <BOOST_PP_ENUM_PARAMS(N, class I)> class T, \ BOOST_PP_ENUM_PARAMS(N, class T) \ > \ tag serialize( \ Archive & ar, \ T<BOOST_PP_ENUM_PARAMS(N, T)> &, \ const unsigned \ ); #include BOOST_PP_LOCAL_ITERATE() tag operator,(tag, int); boost::type_traits::no_type check(tag); template <class T> boost::type_traits::yes_type check(T const&); template <class T> struct impl { static typename boost::remove_cv<T>::type & x; static const int & archive; static const unsigned version; static const bool value = sizeof(check((serialize(archive, x, version), 0))) == sizeof(boost::type_traits::yes_type); }; } template <class T> struct is_non_intrusively_serializable : detail::impl<T> {}; template <class T> struct A {}; int main() { BOOST_STATIC_ASSERT( is_non_intrusively_serializable<std::vector<int> >::value); BOOST_STATIC_ASSERT( !is_non_intrusively_serializable<A<int> >::value); } Regards, Roman Perepelitsa Deutsche Bank Moscow +7 (495) 660-74-08 --- This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and delete this e-mail. Any unauthorized copying, disclosure or distribution of the material in this e-mail is strictly forbidden. Please refer to http://www.db.com/en/content/eu_disclosures.htm for additional EU corporate and regulatory disclosures.