Boost logo

Boost Users :

From: Roman Perepelitsa (roman.perepelitsa_at_[hidden])
Date: 2007-07-24 03:23:28


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


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net