|
Boost : |
From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2002-06-22 06:33:16
I'll have some fun, too. :)
>From: "Paul Mensonides" <pmenso57_at_[hidden]>
>>From: "Robert Klarer" <klarer_at_[hidden]>
>> I just realized that strings of arbitrary length can be represented
>> portably this way:
>>
>> #include <stdio.h>
>>
>> typedef unsigned long letter;
>>
>> template <letter l1 = 0,
>> letter l2 = 0,
>> letter l3 = 0,
>> letter l4 = 0,
>> letter l5 = 0,
>> letter l6 = 0,
>> letter l7 = 0,
>> letter l8 = 0,
>> letter l9 = 0>
>> struct nine_letter_word {
>> static const char pointer [];
>> };
> Okay. My main point, and not a serious one at that, was that you could
> use a multi-byte character literal to simulate a template argument that is
> a string literal.
Unfortunately, it's rather limited in length. However, as David said, you
may store an arbitrarily long sequence, using a type sequence. It would even
be portable, like the above program.
To give an example using Loki:
--- Start program ---
#include <iostream>
#include "loki/Typelist.h"
////////////////////////////////////////////////////////////////////////////
// String
////////////////////////////////////////////////////////////////////////////
template<char c>
struct Convert
{
typedef Loki::Int2Type<c> Result;
};
template<>
struct Convert<0>
{
typedef Loki::NullType Result;
};
template<char c1 =0,char c2 =0,char c3 =0,char c4 =0,
char c5 =0,char c6 =0,char c7 =0,char c8 =0>
struct String
{
typedef Loki::Typelist<Convert<c1>::Result,
Loki::Typelist<Convert<c2>::Result,
Loki::Typelist<Convert<c3>::Result,
Loki::Typelist<Convert<c4>::Result,
Loki::Typelist<Convert<c5>::Result,
Loki::Typelist<Convert<c6>::Result,
Loki::Typelist<Convert<c7>::Result,
Convert<c8>::Result> > > > > > > Result;
};
////////////////////////////////////////////////////////////////////////////
// insert
////////////////////////////////////////////////////////////////////////////
char str[256];
int index=0;
template<class TList>
void insert()
{
str[index]=TList::Head::value;
++index;
insert<typename TList::Tail>();
}
template<>
void insert<Loki::NullType>()
{
str[index]=0;
}
template<>
void insert<Loki::Typelist<Loki::NullType,Loki::NullType> >()
{
str[index]=0;
}
int main()
{
typedef String<'H','e','l','l','o',',',' '>::Result Str1; // Str1 = "Hello,
"
typedef String<'w','o','r','l','d','!'>::Result Str2; // Str2 = "world!"
typedef Loki::TL::Append<Str1,Str2>::Result Text; // Text = Str1 + Str2
insert<Text>();
std::cout << str << '\n'; // Prints "Hello, world!"
}
--- End program ---
"String" is just to more easily construct the strings - they may be of
arbitrary length, and may be combined to longer strings.
Yeah, this is mostly for fun (or perhaps to be able to compute strings at
compile time. :) ), as you could otherwise pass a string to a template, by
passing a pointer or reference to it, as a template parameter.
It's amazing what the compile time machinery is able to do, even text
processing. Is C++ great, or what? :)
Regards,
Terje
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk