
On Mon, Apr 13, 2009 at 5:45 PM, Noah Roberts <roberts.noah@gmail.com> wrote:
Eric Niebler wrote:
Eric Niebler wrote:
Eric Niebler wrote:
There's another consideration that I've been glossing over. mpl::string isn't *really* random access. Since mpl::string<'a','b','c'> designates the same character sequence as mpl::string<'abc'>, it takes O(N) template instantiations to find the N-th element in the sequence, at least in the current implementation. I'd like to fix that, but I don't know how (yet).
Now this is really bothering me. The right thing to do is replace the current implementation with one in which mpl::string is a front- and back-extensible bidirectional sequence, and give up with the random access pretense. :-(
I've made this change. mpl::string is no longer random access (it never really was). Also, I've changed c_str to be a separate metafunction that works with any forward sequence.
Thanks particularly to Noah Roberts for the good feedback.
No problem.
Now someone just needs to make format<> :P
Although a tongue-in-cheek remark, the notion of a compile-time formatting library somehow appeals to me, if for nothing else for its sheer absurdity ;) Due to the limits of preprocessor stringization when dealing with metaprogramming integers, I suspect it might have its use cases wherever runtime conversion overhead is best avoided. With mpl::string it's trivial to create integer-to-string conversion metafunctions, and it should also not be overly complicated to glue these together into something bigger if so should desired. I whipped up a quick (and not very pretty) compile-time _itoa equivalent as a small proof of concept just for fun (only tested on visual c++ 2008) #include <iostream> #include <boost/mpl/string.hpp> #include <boost/mpl/vector_c.hpp> #include <boost/mpl/at.hpp> #include <boost/mpl/if.hpp> #include <boost/mpl/int.hpp> #include <boost/mpl/bool.hpp> #include <boost/mpl/identity.hpp> #include <boost/mpl/push_back.hpp> namespace mpl = boost::mpl; struct itoa_ct { // radix for _itoa() goes up to 36, but only bother with 16 here typedef mpl::vector_c<char ,'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
radix_t;
template <int Radix, unsigned int Quotient> struct radix_convert { typedef typename mpl::push_back< typename radix_convert<Radix, Quotient / Radix>::type , mpl::char_<mpl::at_c<radix_t, Quotient % Radix>::type::value> >::type type; }; template <int Radix> struct radix_convert<Radix, 0> { typedef mpl::string<> type; }; template <int I, int Radix = 10> struct apply { // All bases != 10 consider I as unsigned typedef typename radix_convert< Radix, static_cast<unsigned int>((Radix == 10 && I < 0) ? -I : I) >::type converted_t; // Prefix with '-' if negative and base 10 typedef typename mpl::if_< mpl::bool_<(Radix == 10 && I < 0)> , mpl::push_front<converted_t, mpl::char_<'-'> > , mpl::identity<converted_t> >::type::type type; }; }; int main(int argc, char* argv[]) { std::cout << mpl::c_str<itoa_ct::apply<12345>::type>::value << "\n"; std::cout << mpl::c_str<itoa_ct::apply<-98765>::type>::value << "\n"; std::cout << mpl::c_str<itoa_ct::apply<2009, 2>::type>::value << "\n"; std::cout << mpl::c_str<itoa_ct::apply<0xb0057, 16>::type>::value << "\n"; std::cout << mpl::c_str<itoa_ct::apply<0xffffffff, 16>::type>::value << "\n"; return 0; } which outputs, as expected: 12345 -98765 11111011001 b0057 ffffffff I'm swamped with thesis-work until June, so I cannot really do much else with this for now, but I just wanted to throw it out there. Any thoughts? :) Regards, Tor Brede Vekterli