> 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.