
Matt Hurd wrote:
On 20/03/2008, Tom Brinkman <reportbase@gmail.com> 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