|
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