J
Jocke P
Hi,
I'm trying to define a file reader class which is endian-aware.
My problem is that descendants should select at creation time which
endianness to use, and the base class has all file reading methods,
which I think should be declared as templates:
template<class T> size_t FileReader::read_n(T* tptr, size_t ncount);
But now I'm confused how to set up the byte swapping. Whether to swap
should be configured by a descendant at construction time, depending on
file byte-order.
Here's the intended implementation of the read_n method:
template<class T> filesize_t FileReader::read_n(T* tptr, size_t ncount)
{
size_t n = readRaw(tptr, ncount * sizeof(T));
// Swapper functional should be defined as LITTLEend or BIGend
// depending on file byte-order.
// These in turn are #defined as ByteSwap or DoNothing
// depending on native byte-order.
std::transform(tptr, tptr + ncount, tptr, Swapper);
return n;
}
How could descendants select the swapper functional?
The read() method cannot be virtual since virtual methods cannot be templates.
For the same reason the transform call couldn't be replaced by a
virtual method.
I could of course do something through-and-through dynamic, like adding
an enum or bool member set by descendant, and switch on it in the read methods:
template<class T> filesize_t FileReader::read_n(T* buffer, size_t ncount)
{
filesize_t nbytes = readRawN(buffer, ncount * sizeof(T));
if (_endian == MyLittleEnum)
std::transform(buffer, buffer + ncount, buffer, LITTLEend);
else // (_endian == MyBigEnum)
std::transform(buffer, buffer + ncount, buffer, BIGend);
return nbytes;
}
But this seems silly since endianness is known at descendant creation time.
Isn't there some better alternative?
I wouldn't like to make template of the file reader base class,
since most of its code is not endian dependent, and on my favourite
Defective Compiler I think it would prevent descendants to have template
methods (since partial templ specialization is not accepted).
(PS. I seem to run into very similar problem with templates all the time,
so it would be grand with some entries on template syntax in the FAQ Lite,
though obviously I couldn't offer to write them...)
Thanx for any input,
Jocke
I'm trying to define a file reader class which is endian-aware.
My problem is that descendants should select at creation time which
endianness to use, and the base class has all file reading methods,
which I think should be declared as templates:
template<class T> size_t FileReader::read_n(T* tptr, size_t ncount);
But now I'm confused how to set up the byte swapping. Whether to swap
should be configured by a descendant at construction time, depending on
file byte-order.
Here's the intended implementation of the read_n method:
template<class T> filesize_t FileReader::read_n(T* tptr, size_t ncount)
{
size_t n = readRaw(tptr, ncount * sizeof(T));
// Swapper functional should be defined as LITTLEend or BIGend
// depending on file byte-order.
// These in turn are #defined as ByteSwap or DoNothing
// depending on native byte-order.
std::transform(tptr, tptr + ncount, tptr, Swapper);
return n;
}
How could descendants select the swapper functional?
The read() method cannot be virtual since virtual methods cannot be templates.
For the same reason the transform call couldn't be replaced by a
virtual method.
I could of course do something through-and-through dynamic, like adding
an enum or bool member set by descendant, and switch on it in the read methods:
template<class T> filesize_t FileReader::read_n(T* buffer, size_t ncount)
{
filesize_t nbytes = readRawN(buffer, ncount * sizeof(T));
if (_endian == MyLittleEnum)
std::transform(buffer, buffer + ncount, buffer, LITTLEend);
else // (_endian == MyBigEnum)
std::transform(buffer, buffer + ncount, buffer, BIGend);
return nbytes;
}
But this seems silly since endianness is known at descendant creation time.
Isn't there some better alternative?
I wouldn't like to make template of the file reader base class,
since most of its code is not endian dependent, and on my favourite
Defective Compiler I think it would prevent descendants to have template
methods (since partial templ specialization is not accepted).
(PS. I seem to run into very similar problem with templates all the time,
so it would be grand with some entries on template syntax in the FAQ Lite,
though obviously I couldn't offer to write them...)
Thanx for any input,
Jocke