Topic: Argument in favour of template namepaces
Author: Frederick Gotham <fgothamNO@SPAM.com>
Date: Mon, 26 Jun 2006 09:27:15 CST Raw View
Below, I demonstrate re-usable code which prints out the byte-order of an
unsigned integer type. After that, I demonstrate the merit of having some
sort of "template namepace" functionality, as it will simplify code
greatly, and make it much more pleasant to read.
(Yes, I realise that the code will mal-function if the unsigned integer
type contains padding bits)
Here comes the current code which is Standard C++-compliant:
#include <cstddef>
template<class UType>
struct ByteIndexes {
std::size_t indexes[ sizeof(UType) ];
};
#include <climits>
template<class UType>
ByteIndexes<UType> DetermineIndexes(void)
{
UType guinea_pig = 0;
UType byte_number = 1;
do guinea_pig |= byte_number << CHAR_BIT * byte_number;
while ( ++byte_number != sizeof(UType) );
const unsigned char *p =
reinterpret_cast<unsigned char*>(&guinea_pig);
const unsigned char * const p_over =
reinterpret_cast<unsigned char*>(&guinea_pig + 1);
ByteIndexes<UType> bi;
size_t *p_index = bi.indexes;
do *p_index++ = *p++;
while( p != p_over );
return bi;
}
template<class UType>
std::size_t LSBIndexToByteIndex( std::size_t const i )
{
static ByteIndexes<UType> const bi = DetermineIndexes<UType>();
return bi.indexes[i];
}
#include <iostream>
#include <cstdlib>
int main()
{
using std::cout;
using std::size_t;
cout << "============================\n"
"|| Byte Order ||\n"
"============================\n\n"
"LSB: Byte 0 -- Memory Address ";
for( size_t i = 0; ; )
{
cout << LSBIndexToByteIndex<unsigned long>( i++ ) << '\n';
if ( sizeof(unsigned long) == i ) break;
cout <<
( sizeof(unsigned long) == i + 1 ? "MSB: Byte " : " Byte
" )
<< i << " -- Memory Address ";
}
cout << '\n';
std::system("PAUSE");
}
And now here's how the code might look if we had template namespaces:
#include <cstddef>
#include <climits>
template<class UType>
namespace ByteOrder {
struct ByteIndexes {
std::size_t indexes[ sizeof(UType) ];
};
ByteIndexes DetermineIndexes(void)
{
UType guinea_pig = 0;
UType byte_number = 1;
do guinea_pig |= byte_number << CHAR_BIT * byte_number;
while ( ++byte_number != sizeof(UType) );
const unsigned char *p =
reinterpret_cast<unsigned char*>(&guinea_pig);
const unsigned char * const p_over =
reinterpret_cast<unsigned char*>(&guinea_pig + 1);
ByteIndexes bi;
size_t *p_index = bi.indexes;
do *p_index++ = *p++;
while( p != p_over );
return bi;
}
std::size_t LSBIndexToByteIndex( std::size_t const i )
{
static ByteIndexes const bi = DetermineIndexes();
return bi.indexes[i];
}
} /* End of namespace */
#include <iostream>
#include <cstdlib>
int main()
{
using std::cout;
using std::size_t;
cout << "============================\n"
"|| Byte Order ||\n"
"============================\n\n"
"LSB: Byte 0 -- Memory Address ";
using namespace ByteOrder<unsigned long>; /* <--- LOOK AT THIS --- */
for( size_t i = 0; ; )
{
cout << LSBIndexToByteIndex( i++ ) << '\n';
if ( sizeof(unsigned long) == i ) break;
cout <<
( sizeof(unsigned long) == i + 1 ? "MSB: Byte " : " Byte
" )
<< i << " -- Memory Address ";
}
cout << '\n';
std::system("PAUSE");
}
I think it would be great if we were able to do what I've done in the
code immediatly above.
If anyone would like to discuss that actual functionality of the code
(i.e. how I go about getting byte order, etc.), then please take the
discussion to comp.lang.c++... I'll be waiting : )
--
Frederick Gotham
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]