Re: pure virtual template...
On Oct 29, 2:54 pm, mathieu <mathieu.malate...@gmail.com> wrote:
On 28 oct, 10:56, James Kanze <james.ka...@gmail.com> wrote:
On Oct 27, 8:47 pm, mathieu <mathieu.malate...@gmail.com> wrote:
On 26 oct, 23:40, dvi...@gmail.com wrote:
My objects can be serialized either in big endian or little endian.
Depending on what?
So
the design is :
struct Object
{
...
void Read<Swapper>(ostream &os) { ... }
void Write<Swapper>(ostream &os) { ... }
}
Where swapper is either a no-op or actually do a byte-swap. So
template at the class level would not make much sense.
I'm not sure I understand this at all. Why would you want to
swap anything. You have two output formats. If the choice is
runtime, you have to include the implementation of both in your
code. If the choice is compile time, you include one or the
other at link time. In both cases, it's pretty transparent to
the user; in the first case, you use the strategy pattern, and
the user has to specify the strategy once up front, and in the
second, it's totally transparent, since the decision is made
when you link.
And of course, you never "swap" anything. You simply write the
data in the target format.
That is correct I have 'two' implementations (only different by one
operation: byte swapping).
But why would you ever "swap" bytes? You write big endian, or
you write little endian. Or you write some other format---in
all cases, you have a *value* (int, whatever) which must be
output in a specified format. You convert the value to the
format, and that's it.
Thus my Object O can be written in little or big endian.
Therefore the 'endian' template parameter cannot be at the
class level (as suggested by previous poster).
Since code is cross platform, and choice is done at run-time (user
cannot know ahead of time which format he is reading) I simply pass a
'swapper' template parameter that will decide depending on file format
and architecture how to read words.
If the choice is run-time, you can't use templates. I'd go with
the strategy pattern. Something like:
class Writer
{
public:
virtual ~Writer() {}
virtual void write( std::ostream& dest, int value ) const =
0 ;
// and so on for each type.
}
class BEWriter : public Writer
{
public:
virtual void write( std::ostream& dest, int value ) const
{
uint32_t tmp = value ;
dest.put( (tmp >> 24) & 0xFF ) ;
dest.put( (tmp >> 16) & 0xFF ) ;
dest.put( (tmp >> 8) & 0xFF ) ;
dest.put( (tmp ) & 0xFF ) ;
}
// and so on for each type...
} ;
class LEWriter : public Writer
{
public:
virtual void write( std::ostream& dest, int value ) const
{
uint32_t tmp = value ;
dest.put( (tmp ) & 0xFF ) ;
dest.put( (tmp >> 8) & 0xFF ) ;
dest.put( (tmp >> 16) & 0xFF ) ;
dest.put( (tmp >> 24) & 0xFF ) ;
}
// and so on for each type...
} ;
You then initialize a Writer* in your output class to whichever
one is relevant, and output through it. You can even change on
the fly---first 10 integers in big endian, next 10 in little,
etc.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34