O_o
You have some strangely tight binding to class implementations for reading/writing.
Have you considered parametric polymorphisms or using the iterator pattern?
Soma
Example (parametric polymorphism):
Code:
template <class T>
void outputBit(T & bitWriter, uint bit) {
bitWriter.outputBit(bit);
}
// ...
template <class T>
void expGolombEncode(uint x, T &bitWriter) {
++x;
int l = 0;
for (uint xx = x; xx > 1; xx>>=1)
++l;
for (int i=0; i<l; ++i)
outputBit(bitWriter, 0);
for (int i=l; i>=0; --i)
outputBit(bitWriter, (x >> i) & 1);
}
// ...
Allowing (me, or any other, as a client to only add) a new interface to an existing object:
Code:
void
outputBit
(
Bitstream & fOut // a class I've already written
, uint fBit
)
{
fOut.append(fBit);
}
Instead of (forcing mew to make) a wrapper:
Code:
class Wrapper
{
Wrapper
(
Bitstream & fStream
):
mStream(fStream)
{
}
// ...
void ouputBit
(
uint fBit
)
{
mStream.append(fBit);
}
// ...
};
Example (iterator):
Code:
template <class T>
void expGolombEncode(uint x, T bitWriter) {
++x;
int l = 0;
for (uint xx = x; xx > 1; xx>>=1)
++l;
for (int i=0; i<l; ++i, ++bitWriter)
*bitWriter = 0;
for (int i=l; i>=0; --i, ++bitWriter)
*bitWriter = (x >> i) & 1;
}
// ...
Allowing (me or any other client) to create a new inserter or transform an existing iterator:
Code:
// ...
template
<
typename FInserter
>
class BitInserter
{
BitInserter
(
FInserter fInserter
);
// ...
BitInserter & operator * ();
BitInserter & operator =
(
uint fBitValue
);
BitInserter & operator ++();
BitInserter & operator ++(int);
// ...
typename std::iterator_traits<FType>::value_type mString; // temporary storage
uint mUsed; // storage used
FInserter mInserter; // target
// ...
};
// ...
Granting:
Code:
std::vector<unsigned long> s;
expGolombEncode(/*whatever*/, BitInserter(back_inserter(s)));