Boost logo

Boost Users :

From: Daryle Walker (darylew_at_[hidden])
Date: 2005-11-13 10:40:36


On 11/11/05 4:40 PM, "Robert Ramey" <ramey_at_[hidden]> wrote:

> David Abrahams wrote:
>> "Robert Ramey" <ramey_at_[hidden]> writes:
>>> OK, let me rephrase that. There would be no advantage to doing that
>>> since one could ->
>>>
>>>>> make thier own derivation(s) of one or more archive
>>>>> classes or even a whole new archive class - but that doesn't
>>>>> represent any conflict with the current library.
>
>> A special archive class doesn't help if the interface for serializing
>> arrays isn't a standard part of the archive concept. Everyone who
>> writes a datatype containing an array will need to use that interface
>> in his serialize function.
>
> The archive class concept indicates that the following expression is true
>
> ar << t
>
> for any serializable type t.
>
> The documentation defines a serializable type as:
>
> A type T is Serializable if and only if one of the following is true:
> a.. it is a primitive type.
> In this document, we use the term primitive type to mean types whose data
> is simply saved/loaded to/from an archive with no further processing.
> Arithmetic (including characters), bool, enum and stl::string and
> stl::wstring types are primitive types. Using serialization traits, any user
> type can also be designated as "primitive" so that it is handled in this
> way.
> b.. It is a class type and for all Archive classes, one of the following
> has been declared:
> a.. a class member function serialize
> b.. a global function serialize
> c.. it is a pointer to a Serializable type.
> d.. it is a reference to a Serializable type.
> e.. it is an native C++ Array of Serializable type.
> That is any array is serializable if its elements are serializable. Doesn't
> that cover it?

I take it that member pointers (both data and function) cannot be
serialized, right? I guess I would map each qualifying member to a number
(or string if open-ended) and serialize that number.

I think we need two new archive loading primitives.

1. Array segment. You already have compile-time arrays covered, but I
don't see anything about run-time arrays. (Surprising considering how often
CT-arrays are "dissed" for RT-arrays.) A run-time array is defined by a
pointer to the first element and an element count:

    // I'm just guessing what your base type looks like
    class archive_base
    {
        //...
        template < typename T >
        status_type archive_rtarray( T *a, size_t &c )
        {
            this->archive( c );
            for ( size_t i = c ; i ; --i, ++a )
                this->archive( *a );
            return OK;
        }
        //...
    };

Any class that maintains its own array of elements that doesn't use a smart
container, standard or otherwise, would need this for serialization.

And what if a class uses a non-standard container? We could use an
iterator-based routine:

    class archive_base
    {
        //...
        template < typename T >
        status_type archive_container_save( T const &c )
        {
            typedef typename T::const_iterator iterator;

            iterator const e = c.end();

            for ( iterator b = c.begin() ; e != b ; ++b )
                this->archive_save( *b );
            // You would proably use something kewl
            // from Boost.bind/lambda here instead.

            return OK;
        }

        template < typename T >
        status_type archive_container_load( T &c )
        {
            typedef typename T::size_type size_type;

            size_type s;
            this->archive_load( s );

            typename T::element_type temp;
            for ( size_type i = 0 ; i < s ; ++i )
            {
                this->archive_load( temp );
                c.push_back( temp );
            }

            return OK;
        }
        //...
    }

The routines for the standard containers could call these primitives. The
one for std::vector could use the RT-array primitive.

Finally, a fast archive could be keyed to a type's POD status. (I think we
have a type-trait for that.) We would make a subclass of the binary archive
class that has overrides for POD types. Those types would dump their bytes
directly, even if they're arrays or structures. Obviously we give up
portability for speed. My new RT-array primitive should also be optimized
for POD types. Non-PODs would call their regular coding function, hopefully
getting a speed-up from the individual component speed-ups.

-- 
Daryle Walker
Mac, Internet, and Video Game Junkie
darylew AT hotmail DOT com

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