|
Boost : |
From: Vladimir Prus (ghost_at_[hidden])
Date: 2003-04-21 02:19:00
Robert Ramey wrote:
>>> iv) requirement to have separt save/load code for serialization
>>> functions
>
>>I though about it just recently, and stubmled upon the issue of
>>const-correctness. Probably, separate save/load is OK, since I don't know
>>any good alternative solution.
>
> I was always a fan of "const-correctness" that came with the save/load
> system. Also the save/load system permitted a finer granularity
> such that a program that only read would only have to import
> half the headers and library code. (Same for programs that only
> write archives). However, I was sensitive to the redundance
> of the save/load system and came to appreciate the
> usage of the & operator for both saving an loading - even at
> the cost of const - correctness. (thanks to jens maurers effort)
> After trying out a number of alternatives I came to a solution which
> permits either to be used on a class by class basis.
That's interesting. I wonder if 'const-correctness', here, is just a
theoretical question, or can cause real problems. For example (using
describe-based scheme):
class C {
public:
C() ...
template<class D>
void describe(D& d) const {
d & m_i;
}
const int m_i;
};
If 'describe' is const and read-describer does const_cast internally, this
example has a problem: 'm_i' will be hapily read, although it's really
const. Don't what if there are hidded problem with non-const describe.
>>Can we have a look at it? Probably, putting it to boost-sandbox is good
>>idea. I'm really interested to see how it applies to use case I have at
>>hand.
>
> I don't feel its quite ready for that. Some things are still in the
> experimental
> stage and I'm still weighng alternatives. After these things are settled
> I would better be able to provide explanations for the choices I made.
Ok.
> Please send me your use case. I am very interested in it.
Let me describe it here. I'd like to have code like this
class Event {
public:
double time;
};
class Update_event : public Event {
public:
int Param;
};
[...]
All the classes are very simple. The top-level one will be polymorphic. The
problem is in saving. The existing code uses a structure with union inside
to represent all possible variants. It stores the structure into a memory
buffer which is flushed to disk periodically. The code looks like:
event_data * e = allocateCurrentEvent ( ETUpdate, traceObject, op );
e->U.UD.Param = paramId;
The 'allocateCurrentEvent' call just returns the pointer to the next free
position in the memory buffer. If I were to use serialization library, the
saving would look like:
raw_buffer_archive a;
Update_event ev;
a << static_cast<Update_event*>(&ev);
The problems are
1. *Here* I know the type of stored class. The loading code does not know
the sequence of events, so I need to store polymorphic pointers. But during
saving, I'd like to avoid all the typeid manipluations, for speed. I'm
thinking about something like this:
a.store_polymorphic_pointer_with_known_type<Update_event>(&ev);
In addition, the id to be written into stream should be determined in
constant time. For example, archives in general can use 'type_registry'
to find the id that should be written to stream. The basic one will be
class type_registry {
public:
typedef int id_type;
template<class StaticallyKnownType>
id_type get_id(StaticallyKnownType* t) { ... }
};
and my custom class would look the same, except for additional
specializations:
class static_type_registry {
public:
....;
... get_id ...
};
template<>
inline
static_type_registry::id_type get_id<Update_event>(Update_event*)
{ return 1; }
... the same for all other types.
The exact interface for type registry is not important, actually.
2. The writing itself should be fast --- virtual functions call
is probably too much. If the save/load functions are templates,
this is not hard.
class Update_event {
...
template<class Saver>
void save(Saver& s)
{
s << Param;
}
}
class raw_buffer_arhcive {
public:
raw_buffer_archive& operator<<(int i) {
(int*)m_buffer = i;
....
}
};
> It turns out that ALL the issues raised in the review, including
> those that I dismissed, are being addressed. I didn't really intend
> to do this I had resolved to improve the quality of the implementation
> and leave most of the feature decisions unchanged as I saw them
> as ireconcilable trade offs. I was much surprised to discover that
> improving the implementation made apparent that what I had
> thought were trade offs where in fact artifacts of implementation
> stratagy decisions.
That's interesting!
- Volodya
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk