Specialized Templates

J

Jim Langston

I am writing some functions desgined to output text to an opengl window. I
wish to support both single byte character and multi-byte characters. This
works rather well and I wind up with:

template <class t>
void jglDrawText( const jglFont& font, t text, jglRGBColor rGBC, const
jglVertex2& position ) {
glColor3f( rGBC.red, rGBC.green, rGBC.blue);
// Position The Text On The Screen
glRasterPos2f(position.x, position.y);
jglPrint(font, text); // Print GL Text To The Screen
}

Where jglPrint has 2 signatures:
GLvoid jglPrint( const jglFont& font, const char *text );
GLvoid jglPrint( const jglFont& font, const wchar_t *text );

jglPrint is not a template because there are sufficient differences between
how to output a normal character .vs. a wide character (I look for
unprintable characters in wide char sets, etc..)

Now, I also want to allow jglPrint to be able to print strings, so I have
void jglDrawText( const jglFont& font, const std::string& text, jglRGBColor
rGBC, const jglVertex2& position );
which simply calls jglDrawText with text.c_str() as a parm for text.
Thinking about it, this also makes for a template as the code is exactly the
same for normal std::string and std::wstring. But now I get into a quandry.
I can't create 2 templates with the same name. Do I have to keep
specializing? Or do I have to come up with some other name for printing
strings? jglPrintString ?

It may be easier to just keep specializing as I add them but I was hoping
there was some pattern I'm missing here.

Regards,

Jim Langston
 
B

Begemoth

Now, I also want to allow jglPrint to be able to print strings, so I have
void jglDrawText( const jglFont& font, const std::string& text, jglRGBColor
rGBC, const jglVertex2& position );
šwhich simply calls jglDrawText with text.c_str() as a parm for text.
Thinking about it, this also makes for a template as the code is exactly the
same for normal std::string and std::wstring. šBut now I get into a quandry.
I can't create 2 templates with the same name. šDo I have to keep
specializing? šOr do I have to come up with some other name for printing
strings? šjglPrintString ?

You can create a template to convert to C string:

template<typename T> struct c_string_cast;

template<>
struct c_string_cast<char*>
{
static char* cast(char* s) { return s; }
};

template<>
struct c_string_cast<std::wstring>
{
static wchar_t* cast(const std::wstring& s) { return s.c_str(); }
};

etc.

The c_string_cast::cast return either char* or wchar_t* depending on
the type of the parameter. Then:

template <class t>
void jglDrawText( const jglFont& font, t text, jglRGBColor rGBC, const
jglVertex2& position )
{
glColor3f( rGBC.red, rGBC.green, rGBC.blue);
// Position The Text On The Screen
glRasterPos2f(position.x, position.y);
jglPrint(font, c_string_cast::cast<t>(text)); // Print GL Text To
The Screen
}
 
Ö

Öö Tiib

I am writing some functions desgined to output text to an opengl window. I
wish to support both single byte character and multi-byte characters. This
works rather well and I wind up with:

template <class t>
void jglDrawText( const jglFont& font, t text, jglRGBColor rGBC, const
jglVertex2& position ) {
glColor3f( rGBC.red, rGBC.green, rGBC.blue);
// Position The Text On The Screen
glRasterPos2f(position.x, position.y);
jglPrint(font, text); // Print GL Text To The Screen
}

Where jglPrint has 2 signatures:
GLvoid jglPrint( const jglFont& font, const char *text );
GLvoid jglPrint( const jglFont& font, const wchar_t *text );

jglPrint is not a template because there are sufficient differences between
how to output a normal character .vs. a wide character (I look for
unprintable characters in wide char sets, etc..)

Now, I also want to allow jglPrint to be able to print strings, so I have
void jglDrawText( const jglFont& font, const std::string& text, jglRGBColor
rGBC, const jglVertex2& position );
which simply calls jglDrawText with text.c_str() as a parm for text.
Thinking about it, this also makes for a template as the code is exactly the
same for normal std::string and std::wstring. But now I get into a quandry.
I can't create 2 templates with the same name. Do I have to keep
specializing? Or do I have to come up with some other name for printing
strings? jglPrintString ?

It may be easier to just keep specializing as I add them but I was hoping
there was some pattern I'm missing here.

Do not two additional overloads for your jglPrint() help?

GLvoid jglPrint( jglFont const& font, std::string const& text );
GLvoid jglPrint( jglFont const& font, std::wstring const& text );

My strategy is to pick only one type from std::string (containing
UTF-8) or std::wstring (containing UTF-uncertain) for all text
objects. I prefer to pick wstring (it does not implicitly construct
from char* that i hate about string). If your code assumes what UTF
wstring contains (why?) then put static assert about it into your
interface header file. Get rid of using anything else (like char* and
wchar_t*) in all your code and function signatures.

Replace or enwrap everything that you can not modify that uses the
types you did not pick. Literals convert immediately to your picked
type, raw binary data (should be rare) pass around as
std::vector<char>. Conversion provides natural opportunity to treat
the alien texts as dirty data and perform necessary checks. Things get
suddenly safer and simpler. As bonus you do not need templates to deal
with the messed up variety of strings available in language. Also you
are better prepared for the devastation that next wave of char8_t*,
char16_t* and char32_t* (and their std::basic_string<> buddies)
invasion into language will cause to your comrades.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top