|
Boost : |
From: Eric Niebler (eric_at_[hidden])
Date: 2008-03-20 21:01:11
Matt Hurd wrote:
>> On 20/03/2008, Tom Brinkman <reportbase_at_[hidden]> wrote:
>> >> Why would one bother to do this.
>>
>> Good question. Maybe just because they say that you cant.
> That's almost a good enough reason for me:-)
>
> It was raised with a mpl vector snippet in April 2005:
> http://article.gmane.org/gmane.comp.lib.boost.devel/121612
>
> I think it is useful as then you can do all sorts of compile time
> string / packet manipulation for parsing, offset calculations and take
> a whole bunch of run time calcs out of the equation with some elegance
> and ease the maintenance burden. Plenty of first, follows compile
> time parsing you can do from a grammar POV. Interesting foo you could
> do for a lexical parser, regex or other kinds of state machine
> optimisation. Perfect hashing for strings at compile time...
>
> The main problem is you can't do this without a pre-processing stage
> elegantly. There is just no way to support a macro or any other
> succinct form of compile time string without a pre-processing stage.
> It is just clumsy.
Here's a slightly goofy way to do it using multi-character character
constants. I'm pretty sure this is non-portable, but it works with gcc
and msvc.
#include <iostream>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/arithmetic/div.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>
#define MAX_CTSTRING_LENGTH 40
#define MAX_CTSTRING_PARAMS BOOST_PP_DIV(MAX_CTSTRING_LENGTH, 4)
#define CTLENGTH(c) \
((c&0xff000000)?4:(c&0xff0000)?3:(c&0xff00)?2:1)
#define CTAT(c,i) \
((c&(0xff<<((CTLENGTH(c)-i-1)*8)))>>(8*(CTLENGTH(c)-i-1)))
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(MAX_CTSTRING_PARAMS, int i, 0)>
struct ctstring
{
template<int I, bool B = (I < CTLENGTH(i0))>
struct at
{
static char const value = CTAT(i0,I);
};
template<int I>
struct at<I, false>
: ctstring<BOOST_PP_ENUM_SHIFTED_PARAMS(MAX_CTSTRING_PARAMS, i)>
::template at<I-CTLENGTH(i0)>
{};
static char const value[];
};
template<BOOST_PP_ENUM_PARAMS(MAX_CTSTRING_PARAMS, int i)>
char const ctstring<BOOST_PP_ENUM_PARAMS(MAX_CTSTRING_PARAMS, i)>::value[] =
{
#define M0(z, n, data) at<n>::value
BOOST_PP_ENUM(MAX_CTSTRING_LENGTH, M0, ~)
#undef M0
};
// Accept a string as a template parameter!
template<char const *sz>
struct greeting
{
void say_hello() const { std::cout << sz << std::endl; }
};
int main()
{
greeting<ctstring<'Hell','o wo','rld!'>::value> g;
g.say_hello();
return 0;
}
-- Eric Niebler Boost Consulting www.boost-consulting.com
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk