Boost logo

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