Boost logo

Boost Users :

Subject: Re: [Boost-users] [mpl]... is there an mpl::string
From: Noah Roberts (roberts.noah_at_[hidden])
Date: 2009-04-08 16:33:44


Eric Niebler wrote:
>>>> Andy Stevenson wrote:
>>>>>
>>>>> I recall some discussion of there being an mpl::string
>>>>> template..... Can't see it in the mpl library. Is it elsewhere?
>
> It has been added to trunk as of revision 52208:
>
> https://svn.boost.org/trac/boost/changeset/52208
>
> No doubt the regression tests will reveal portability problems. Once
> they have been worked out, we can move this to release.
>

Visual Studio 2005 hates it. Perhaps I'm not going about it the right
way? I simply downloaded string.hpp, char.hpp, and char_fwd.hpp and
altered the include paths so that they'd work in an individual project.

Then I wrote the following test code:

#include <iostream>

#include "string.hpp"

template < char const* str >
struct test
{
   static void print() { std::cout << str << std::endl; }
};

int main()
{
   typedef boost::mpl::string<'hell', 'o wo', 'rld!'> str;

   std::cout << str::template at<0>::value << std::endl;

   std::cin.get();
}

1>e:\dev_workspace\experimental\scratch\scratch\main.cpp(15) : error
C2976: 'boost::mpl::string<C0,C1,C2>::at' : too few template arguments
1> with
1> [
1> C0=1751477356,
1> C1=1864398703,
1> C2=1919706145
1> ]

This of course causes problems in c_str.

This code fails for the same reason:

#include <iostream>
#include <boost/type_traits.hpp>

template < typename T >
struct test_inner
{
   template < typename X, bool B = boost::is_same<T,X>::value >
   struct inner
   {
     static bool const value = B;
   };
};

int main()
{
   std::cout << test_inner<int>::template inner<int>::value << std::endl;

   std::cin.get();
}

So, looks like VS can't handle default template arguments in these inner
templates. I changed the implementation of at<>:

     template < typename String, long Pos, bool B = (Pos <
BOOST_MPL_MULTICHAR_LENGTH(String::front_)) >
     struct string_at :
boost::mpl::char_<BOOST_MPL_MULTICHAR_AT(String::front_,Pos)>
     {
     };

     template < typename String, long Pos >
     struct string_at<String, Pos, false>
       : string_at< typename String::rest_, Pos -
BOOST_MPL_MULTICHAR_LENGTH(String::front_)>
     {
     };

     template<>
     struct at_impl<string_tag>
     {
         template<typename Sequence, typename N>
         struct apply
           : string_at<Sequence, N::value>
         {};
     };

And implemented c_str[] in terms of string_at<>:

     template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned
int C)>
     char const string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS,
C)>::c_str[] =
     {
     #define M0(z, n, data)
string_at<string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS,C)>,
n>::value
         BOOST_PP_ENUM(BOOST_MPL_STRING_MAX_LENGTH, M0, ~)
     #undef M0
       , '\0' // to ensure the string is null-terminated
     };

This code compiles with changes in VS 2005:

#include <iostream>
#include <boost/mpl/at.hpp>
#include <boost/mpl/int.hpp>
#include "string.hpp"
int main()
{
   typedef boost::mpl::string<'hell', 'o wo', 'rld!'> str;

   std::cout << boost::mpl::at<str, boost::mpl::int_<0> >::value <<
std::endl;
   std::cout << str::c_str << std::endl;

   std::cin.get();
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net