Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r52314 - in trunk: boost/mpl libs/mpl/doc/src/refmanual libs/mpl/test
From: eric_at_[hidden]
Date: 2009-04-11 01:48:53


Author: eric_niebler
Date: 2009-04-11 01:48:51 EDT (Sat, 11 Apr 2009)
New Revision: 52314
URL: http://svn.boost.org/trac/boost/changeset/52314

Log:
mpl::string is a bidirectional sequence, not random access; c_str is a separate metafunction, not a class static
Added:
   trunk/libs/mpl/doc/src/refmanual/c_str.rst (contents, props changed)
Text files modified:
   trunk/boost/mpl/string.hpp | 496 +++++++++++++++++++++++----------------
   trunk/libs/mpl/doc/src/refmanual/refmanual.toc | 1
   trunk/libs/mpl/doc/src/refmanual/string.rst | 45 +--
   trunk/libs/mpl/test/string.cpp | 476 +++++++++++++++++++++++++++++++-------
   4 files changed, 699 insertions(+), 319 deletions(-)

Modified: trunk/boost/mpl/string.hpp
==============================================================================
--- trunk/boost/mpl/string.hpp (original)
+++ trunk/boost/mpl/string.hpp 2009-04-11 01:48:51 EDT (Sat, 11 Apr 2009)
@@ -4,8 +4,8 @@
 
 // Copyright Eric Niebler 2009
 //
-// Distributed under the Boost Software License, Version 1.0.
-// (See accompanying file LICENSE_1_0.txt or copy at
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 //
 // See http://www.boost.org/libs/mpl for documentation.
@@ -14,23 +14,21 @@
 // $Date: 2009-04-01 02:10:26 -0700 (Wed, 1 Apr 2009) $
 // $Revision: 49239 $
 
-#include <boost/config.hpp>
-#include <boost/detail/workaround.hpp>
 #include <boost/mpl/char.hpp>
-#include <boost/mpl/long.hpp>
-#include <boost/mpl/back.hpp>
 #include <boost/mpl/copy.hpp>
+#include <boost/mpl/size.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/mpl/size_t.hpp>
 #include <boost/mpl/joint_view.hpp>
 #include <boost/mpl/insert_range.hpp>
 #include <boost/mpl/back_inserter.hpp>
+#include <boost/mpl/front_inserter.hpp>
 #include <boost/mpl/iterator_range.hpp>
 #include <boost/preprocessor/arithmetic/dec.hpp>
 #include <boost/preprocessor/arithmetic/add.hpp>
 #include <boost/preprocessor/arithmetic/div.hpp>
-#include <boost/preprocessor/repetition/enum.hpp>
 #include <boost/preprocessor/punctuation/comma_if.hpp>
+#include <boost/preprocessor/repetition/repeat.hpp>
 #include <boost/preprocessor/repetition/enum_params.hpp>
 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
 #include <boost/preprocessor/repetition/enum_shifted_params.hpp>
@@ -42,7 +40,7 @@
     #ifndef BOOST_MPL_STRING_MAX_LENGTH
     # define BOOST_MPL_STRING_MAX_LENGTH 32
     #endif
-
+
     #define BOOST_MPL_STRING_MAX_PARAMS BOOST_PP_DIV(BOOST_PP_ADD(BOOST_MPL_STRING_MAX_LENGTH, 3), 4)
 
     #define BOOST_MPL_MULTICHAR_LENGTH(c) (std::size_t)((c>0xffffff)+(c>0xffff)+(c>0xff)+1)
@@ -51,10 +49,10 @@
     struct string_tag;
     struct string_iterator_tag;
 
- template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C, 0)>
+ template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_MPL_STRING_MAX_PARAMS, unsigned C, 0)>
     struct string;
 
- template<typename Sequence, unsigned long N>
+ template<typename Sequence, unsigned I, unsigned J>
     struct string_iterator;
 
     template<typename Sequence>
@@ -64,36 +62,40 @@
     struct size_impl;
 
     template<>
- struct size_impl<string_tag>
+ struct size_impl<mpl::string_tag>
     {
         template<typename Sequence>
- struct apply
- : mpl::size_t<Sequence::size>
- {};
- };
+ struct apply;
 
- template<typename Tag>
- struct at_impl;
+ #define M0(z, n, data) \
+ + BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C,n))
 
- template<>
- struct at_impl<string_tag>
- {
- template<typename Sequence, typename N>
- struct apply
- : Sequence::template at<N::value>
+ #define M1(z, n, data) \
+ template<BOOST_PP_ENUM_PARAMS_Z(z, n, unsigned C)> \
+ struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> > \
+ : mpl::size_t<(0 BOOST_PP_REPEAT_ ## z(n, M0, ~))> \
         {};
+
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M1, ~)
+ #undef M0
+ #undef M1
     };
 
+ template<>
+ struct size_impl<mpl::string_tag>::apply<mpl::string<> >
+ : mpl::size_t<0>
+ {};
+
     template<typename Tag>
     struct begin_impl;
 
     template<>
- struct begin_impl<string_tag>
+ struct begin_impl<mpl::string_tag>
     {
         template<typename Sequence>
         struct apply
         {
- typedef string_iterator<Sequence, 0> type;
+ typedef mpl::string_iterator<Sequence, 0, 0> type;
         };
     };
 
@@ -101,102 +103,212 @@
     struct end_impl;
 
     template<>
- struct end_impl<string_tag>
+ struct end_impl<mpl::string_tag>
     {
         template<typename Sequence>
- struct apply
- {
- typedef string_iterator<Sequence, Sequence::size> type;
+ struct apply;
+
+ #define M0(z,n,data) \
+ template<BOOST_PP_ENUM_PARAMS_Z(z, n, unsigned C)> \
+ struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> > \
+ { \
+ typedef mpl::string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, n, 0> type; \
         };
+
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)
+ #undef M0
+ };
+
+ template<>
+ struct end_impl<mpl::string_tag>::apply<mpl::string<> >
+ {
+ typedef mpl::string_iterator<mpl::string<>, 0, 0> type;
     };
 
     template<typename Tag>
     struct push_back_impl;
 
     template<>
- struct push_back_impl<string_tag>
+ struct push_back_impl<mpl::string_tag>
     {
         template<typename Sequence, typename Value, bool B = (4==BOOST_MPL_MULTICHAR_LENGTH(Sequence::back_))>
         struct apply
         {
- BOOST_MPL_ASSERT_MSG(false, PUSH_BACK_FAILED_MPL_STRING_IS_FULL, (Sequence));
- typedef void type;
+ BOOST_MPL_ASSERT_MSG(
+ (BOOST_MPL_STRING_MAX_LENGTH != mpl::size<Sequence>::type::value)
+ , PUSH_BACK_FAILED_MPL_STRING_IS_FULL
+ , (Sequence)
+ );
+ // If the above assertion didn't fire, then the string is sparse.
+ // Repack the string and retry the push_back
+ typedef
+ typename mpl::push_back<
+ typename mpl::copy<
+ Sequence
+ , mpl::back_inserter<mpl::string<> >
+ >::type
+ , Value
+ >::type
+ type;
         };
 
         template<typename Value>
- struct apply<string<>, Value, false>
+ struct apply<mpl::string<>, Value, false>
         {
- typedef string<(char)Value::value> type;
+ typedef mpl::string<(char)Value::value> type;
         };
 
         #define M0(z,n,data) \
- template<BOOST_PP_ENUM_PARAMS_Z(z, n, unsigned int C), typename Value> \
- struct apply<string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, false> \
+ template<BOOST_PP_ENUM_PARAMS_Z(z, n, unsigned C), typename Value> \
+ struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, false> \
         { \
- typedef string< \
- BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), C) \
- BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \
- (BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff) \
- ?BOOST_PP_CAT(C,BOOST_PP_DEC(n)) \
- :(BOOST_PP_CAT(C,BOOST_PP_DEC(n))<<8)|(unsigned char)Value::value \
- , (BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff) \
- ?(char)Value::value \
- :0 \
- > type; \
+ typedef \
+ mpl::string< \
+ BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), C) \
+ BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \
+ (BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff) \
+ ?BOOST_PP_CAT(C,BOOST_PP_DEC(n)) \
+ :(BOOST_PP_CAT(C,BOOST_PP_DEC(n))<<8)|(unsigned char)Value::value \
+ , (BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff) \
+ ?(char)Value::value \
+ :0 \
+ > \
+ type; \
         };
 
         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)
         #undef M0
 
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C), typename Value>
- struct apply<string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>
+ template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned C), typename Value>
+ struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>
         {
- typedef string<
- BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS), C)
- , (BOOST_PP_CAT(C,BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS))<<8)|(unsigned char)Value::value
- > type;
+ typedef
+ mpl::string<
+ BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS), C)
+ , (BOOST_PP_CAT(C,BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS))<<8)|(unsigned char)Value::value
+ >
+ type;
         };
     };
 
     template<typename Tag>
+ struct pop_back_impl;
+
+ template<>
+ struct pop_back_impl<mpl::string_tag>
+ {
+ template<typename Sequence>
+ struct apply;
+
+ #define M0(z,n,data) \
+ template<BOOST_PP_ENUM_PARAMS_Z(z, n, unsigned C)> \
+ struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> > \
+ { \
+ BOOST_MPL_ASSERT_MSG((C0 != 0), POP_BACK_FAILED_MPL_STRING_IS_EMPTY, (mpl::string<>)); \
+ typedef \
+ mpl::string< \
+ BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), C) \
+ BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \
+ (BOOST_PP_CAT(C,BOOST_PP_DEC(n))>>8) \
+ > \
+ type; \
+ };
+
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)
+ #undef M0
+ };
+
+ template<typename Tag>
     struct push_front_impl;
 
     template<>
- struct push_front_impl<string_tag>
+ struct push_front_impl<mpl::string_tag>
     {
         template<typename Sequence, typename Value, bool B = (4==BOOST_MPL_MULTICHAR_LENGTH(Sequence::front_))>
         struct apply
         {
- BOOST_MPL_ASSERT_MSG(false, PUSH_FRONT_FAILED_MPL_STRING_IS_FULL, (Sequence));
- typedef void type;
+ BOOST_MPL_ASSERT_MSG(
+ (BOOST_MPL_STRING_MAX_LENGTH != mpl::size<Sequence>::type::value)
+ , PUSH_FRONT_FAILED_MPL_STRING_IS_FULL
+ , (Sequence)
+ );
+ // If the above assertion didn't fire, then the string is sparse.
+ // Repack the string and retry the push_front.
+ typedef
+ typename mpl::push_front<
+ typename mpl::reverse_copy<
+ Sequence
+ , mpl::front_inserter<string<> >
+ >::type
+ , Value
+ >::type
+ type;
         };
 
         template<typename Value>
- struct apply<string<>, Value, false>
+ struct apply<mpl::string<>, Value, false>
         {
- typedef string<(char)Value::value> type;
+ typedef mpl::string<(char)Value::value> type;
         };
 
         #define M0(z,n,data) \
- template<BOOST_PP_ENUM_PARAMS_Z(z, n, unsigned int C), typename Value> \
- struct apply<string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, true> \
+ template<BOOST_PP_ENUM_PARAMS_Z(z, n, unsigned C), typename Value> \
+ struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, true> \
         { \
- typedef string< \
- (char)Value::value \
- BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, C) \
- > type; \
+ typedef \
+ mpl::string< \
+ (char)Value::value \
+ BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, C) \
+ > \
+ type; \
         };
 
         BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)
         #undef M0
 
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C), typename Value>
- struct apply<string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>
+ template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned C), typename Value>
+ struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>
         {
- typedef string<
- ((((unsigned char)Value::value)<<(BOOST_MPL_MULTICHAR_LENGTH(C0)*8))|C0)
- , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)
- > type;
+ typedef
+ mpl::string<
+ ((((unsigned char)Value::value)<<(BOOST_MPL_MULTICHAR_LENGTH(C0)*8))|C0)
+ , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)
+ >
+ type;
+ };
+ };
+
+ template<typename Tag>
+ struct pop_front_impl;
+
+ template<>
+ struct pop_front_impl<mpl::string_tag>
+ {
+ template<typename Sequence, bool B = (1==BOOST_MPL_MULTICHAR_LENGTH(Sequence::front_))>
+ struct apply;
+
+ #define M0(z,n,data) \
+ template<BOOST_PP_ENUM_PARAMS_Z(z, n, unsigned C)> \
+ struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, true> \
+ { \
+ BOOST_MPL_ASSERT_MSG((C0 != 0), POP_FRONT_FAILED_MPL_STRING_IS_EMPTY, (mpl::string<>)); \
+ typedef \
+ mpl::string<BOOST_PP_ENUM_SHIFTED_PARAMS_Z(z, n, C)> \
+ type; \
+ };
+
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)
+ #undef M0
+
+ template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned C)>
+ struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, false>
+ {
+ typedef
+ mpl::string<
+ (((1<<((BOOST_MPL_MULTICHAR_LENGTH(C0)-1)*8))-1)&C0)
+ , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)
+ >
+ type;
         };
     };
 
@@ -204,25 +316,25 @@
     struct insert_range_impl;
 
     template<>
- struct insert_range_impl<string_tag>
+ struct insert_range_impl<mpl::string_tag>
     {
         template<typename Sequence, typename Pos, typename Range>
         struct apply
- : copy<
- joint_view<
- iterator_range<
- string_iterator<Sequence, 0>
+ : mpl::copy<
+ mpl::joint_view<
+ mpl::iterator_range<
+ mpl::string_iterator<Sequence, 0, 0>
                       , Pos
>
- , joint_view<
+ , mpl::joint_view<
                         Range
- , iterator_range<
+ , mpl::iterator_range<
                             Pos
- , string_iterator<Sequence, Sequence::size>
+ , typename mpl::end<Sequence>::type
>
>
>
- , back_inserter<string<> >
+ , mpl::back_inserter<mpl::string<> >
>
         {};
     };
@@ -231,11 +343,11 @@
     struct insert_impl;
 
     template<>
- struct insert_impl<string_tag>
+ struct insert_impl<mpl::string_tag>
     {
         template<typename Sequence, typename Pos, typename Value>
         struct apply
- : insert_range<Sequence, Pos, string<(char)Value::value> >
+ : mpl::insert_range<Sequence, Pos, mpl::string<(char)Value::value> >
         {};
     };
 
@@ -243,22 +355,22 @@
     struct erase_impl;
 
     template<>
- struct erase_impl<string_tag>
+ struct erase_impl<mpl::string_tag>
     {
         template<typename Sequence, typename First, typename Last>
         struct apply
- : copy<
- joint_view<
- iterator_range<
- string_iterator<Sequence, 0>
+ : mpl::copy<
+ mpl::joint_view<
+ mpl::iterator_range<
+ mpl::string_iterator<Sequence, 0, 0>
                       , First
>
- , iterator_range<
- typename if_na<Last, typename next<First>::type>::type
- , string_iterator<Sequence, Sequence::size>
+ , mpl::iterator_range<
+ typename mpl::if_na<Last, typename mpl::next<First>::type>::type
+ , typename mpl::end<Sequence>::type
>
>
- , back_inserter<string<> >
+ , mpl::back_inserter<mpl::string<> >
>
         {};
     };
@@ -267,153 +379,123 @@
     struct clear_impl;
 
     template<>
- struct clear_impl<string_tag>
+ struct clear_impl<mpl::string_tag>
     {
         template<typename>
         struct apply
         {
- typedef string<> type;
+ typedef mpl::string<> type;
         };
     };
 
- template<typename Tag>
- struct advance_impl;
-
- template<>
- struct advance_impl<string_iterator_tag>
- {
- template<typename Iterator, typename N>
- struct apply
- {
- typedef string_iterator<
- typename Iterator::string_type
- , Iterator::index + N::value
- > type;
- };
+ #define M0(z, n, data) \
+ template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned C), unsigned J> \
+ struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, n, J> \
+ { \
+ typedef mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> string; \
+ typedef std::bidirectional_iterator_tag category; \
+ typedef \
+ typename mpl::if_c< \
+ (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == J + 1) \
+ , mpl::string_iterator<string, n + 1, 0> \
+ , mpl::string_iterator<string, n, J + 1> \
+ >::type \
+ next; \
+ typedef \
+ mpl::string_iterator<string, n, J-1> \
+ prior; \
+ typedef mpl::char_<BOOST_MPL_MULTICHAR_AT(BOOST_PP_CAT(C, n), J)> type; \
+ }; \
+ template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned C)> \
+ struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, n, 0> \
+ { \
+ typedef mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> string; \
+ typedef std::bidirectional_iterator_tag category; \
+ typedef \
+ typename mpl::if_c< \
+ (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == 1) \
+ , mpl::string_iterator<string, n + 1, 0> \
+ , mpl::string_iterator<string, n, 1> \
+ >::type \
+ next; \
+ typedef \
+ mpl::string_iterator< \
+ string \
+ , n - 1 \
+ , BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, BOOST_PP_DEC(n))) - 1 \
+ > \
+ prior; \
+ typedef mpl::char_<BOOST_MPL_MULTICHAR_AT(BOOST_PP_CAT(C, n), 0)> type; \
     };
 
- template<typename Tag>
- struct distance_impl;
+ BOOST_PP_REPEAT(BOOST_MPL_STRING_MAX_PARAMS, M0, ~)
+ #undef M0
 
- template<>
- struct distance_impl<string_iterator_tag>
+ template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned C)>
+ struct string
     {
- template<typename First, typename Last>
- struct apply
+ /// INTERNAL ONLY
+ enum
         {
- typedef mpl::long_<(long)Last::index - (long)First::index> type;
+ front_ = C0
+ , back_ = BOOST_PP_CAT(C, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS))
         };
- };
 
- template<typename Sequence, unsigned long N>
- struct string_iterator
- : Sequence::template at<N>
- {
- typedef string_iterator_tag tag;
- typedef std::random_access_iterator_tag category;
- typedef Sequence string_type;
- static unsigned long const index = N;
- typedef string_iterator<Sequence, N+1> next;
- typedef string_iterator<Sequence, N-1> prior;
+ typedef string type;
+ typedef string_tag tag;
     };
 
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C)>
- struct string
+ namespace aux_
     {
- /// INTERNAL ONLY
- static unsigned int const front_ = C0;
- /// INTERNAL ONLY
- static unsigned int const back_ = BOOST_PP_CAT(C, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS));
- /// INTERNAL ONLY
- typedef string<BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> rest_;
-
- typedef string type;
-
- typedef string_tag tag;
-
- static std::size_t const size = BOOST_MPL_MULTICHAR_LENGTH(C0) + rest_::size;
-
- #if BOOST_WORKAROUND(BOOST_MSVC, <= 1400)
- private:
- /// INTERNAL ONLY
- template<unsigned long Pos, bool B>
- struct at_impl
- : boost::mpl::char_<BOOST_MPL_MULTICHAR_AT(C0,Pos)>
+ template<typename It, typename End>
+ struct next_unless
+ : mpl::next<It>
         {};
 
- /// INTERNAL ONLY
- template<unsigned long Pos>
- struct at_impl<Pos, false>
- : rest_::template at<Pos-BOOST_MPL_MULTICHAR_LENGTH(C0)>
- {};
-
- public:
- template<unsigned long Pos>
- struct at
- : at_impl<Pos, (Pos < BOOST_MPL_MULTICHAR_LENGTH(C0))>
- {};
- #else
- template<unsigned long Pos, bool B = (Pos < BOOST_MPL_MULTICHAR_LENGTH(C0))>
- struct at
- : boost::mpl::char_<BOOST_MPL_MULTICHAR_AT(C0,Pos)>
- {};
+ template<typename End>
+ struct next_unless<End, End>
+ {
+ typedef End type;
+ };
 
- template<unsigned long Pos>
- struct at<Pos, false>
- : rest_::template at<Pos-BOOST_MPL_MULTICHAR_LENGTH(C0)>
+ template<typename It, typename End>
+ struct deref_unless
+ : mpl::deref<It>
         {};
- #endif
 
- static char const c_str[];
- };
+ template<typename End>
+ struct deref_unless<End, End>
+ {
+ typedef mpl::char_<'\0'> type;
+ };
+ }
 
- 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[] =
+ template<typename Sequence>
+ struct c_str
     {
- #define M0(z, n, data) at<n>::value
- BOOST_PP_ENUM(BOOST_MPL_STRING_MAX_LENGTH, M0, ~)
- #undef M0
- , '\0' // to ensure the string is null-terminated
- };
-
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C)>
- std::size_t const string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>::size;
-
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C)>
- unsigned int const string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>::front_;
+ typedef typename mpl::end<Sequence>::type iend;
+ typedef typename mpl::begin<Sequence>::type i0;
+ #define M0(z, n, data) \
+ typedef \
+ typename mpl::aux_::next_unless<BOOST_PP_CAT(i, n), iend>::type \
+ BOOST_PP_CAT(i, BOOST_PP_INC(n));
+ BOOST_PP_REPEAT(BOOST_MPL_STRING_MAX_LENGTH, M0, ~)
+ #undef M0
 
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C)>
- unsigned int const string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>::back_;
+ typedef c_str type;
+ static char const value[];
+ };
 
- template<>
- struct string<>
+ template<typename Sequence>
+ char const c_str<Sequence>::value[] =
     {
- /// INTERNAL ONLY
- static unsigned int const front_ = 0;
- /// INTERNAL ONLY
- static unsigned int const back_ = 0;
- /// INTERNAL ONLY
- typedef string rest_;
-
- typedef string type;
-
- typedef string_tag tag;
-
- static std::size_t const size = 0;
-
- template<unsigned long>
- struct at
- : boost::mpl::char_<'\0'>
- {};
-
- static char const c_str[];
+ #define M0(z, n, data) \
+ mpl::aux_::deref_unless<BOOST_PP_CAT(i, n), iend>::type::value,
+ BOOST_PP_REPEAT(BOOST_MPL_STRING_MAX_LENGTH, M0, ~)
+ #undef M0
+ '\0'
     };
 
- char const string<>::c_str[] = {'\0'};
- std::size_t const string<>::size;
- unsigned int const string<>::front_;
- unsigned int const string<>::back_;
-
 }} // namespace boost
 
 #endif // BOOST_MPL_STRING_HPP_INCLUDED

Added: trunk/libs/mpl/doc/src/refmanual/c_str.rst
==============================================================================
--- (empty file)
+++ trunk/libs/mpl/doc/src/refmanual/c_str.rst 2009-04-11 01:48:51 EDT (Sat, 11 Apr 2009)
@@ -0,0 +1,108 @@
+.. Metafunctions/String Operations//c_str |10
+
+.. Copyright Eric Niebler 2009.
+.. Distributed under the Boost
+.. Software License, Version 1.0. (See accompanying
+.. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+c_str
+=====
+
+Synopsis
+--------
+
+.. parsed-literal::
+
+ template<
+ typename Sequence
+ >
+ struct c_str
+ {
+ typedef |unspecified| type;
+ static char const value[];
+ };
+
+
+Description
+-----------
+
+``c_str`` converts the |Forward Sequence| of |Integral Constant|\ s ``Sequence``
+into a null-terminated byte string containing an equivalent sequence.
+
+
+Header
+------
+
+.. parsed-literal::
+
+ #include <boost/mpl/string.hpp>
+
+
+Model of
+--------
+
+|Metafunction|
+
+
+Parameters
+----------
+
++---------------+---------------------------+-----------------------------------------------+
+| Parameter | Requirement | Description |
++===============+===========================+===============================================+
+| ``Sequence`` | |Forward Sequence| of | A sequence to be converted into a |
+| | |Integral Constant|\ s | null-terminated byte string. |
++---------------+---------------------------+-----------------------------------------------+
+
+
+Expression semantics
+--------------------
+
+.. compound::
+ :class: expression-semantics
+
+ For any |Forward Sequence| of |Integral Constant|\ s ``s``,
+
+ .. parsed-literal::
+
+ c_str<s>::value;
+
+ :Return type:
+ A null-terminated byte string.
+
+ :Precondition:
+ ``size<s>::value <= BOOST_MPL_STRING_MAX_LENGTH``.
+
+ :Semantics:
+ Equivalent to
+
+ .. parsed-literal::
+
+ char const value[] = {
+ at<s, 0>::type::value
+ , ...
+ , at<s, size<s>::value-1>::type::value
+ , '\\0'
+ };
+
+Complexity
+----------
+
++-------------------------------+-----------------------------------+
+| Sequence archetype | Complexity |
++===============================+===================================+
+| |Forward Sequence| | Linear. |
++-------------------------------+-----------------------------------+
+
+Example
+-------
+
+.. parsed-literal::
+
+ typedef vector_c<char,'h','e','l','l','o'> hello;
+ assert( 0 == std::strcmp( c_str<hello>::value, "hello" ) );
+
+See also
+--------
+
+|Forward Sequence|, |Integral Constant|, |string|

Modified: trunk/libs/mpl/doc/src/refmanual/refmanual.toc
==============================================================================
--- trunk/libs/mpl/doc/src/refmanual/refmanual.toc (original)
+++ trunk/libs/mpl/doc/src/refmanual/refmanual.toc 2009-04-11 01:48:51 EDT (Sat, 11 Apr 2009)
@@ -23,6 +23,7 @@
 Metafunctions/Logical Operations
 Metafunctions/Bitwise Operations
 Metafunctions/Trivial
+Metafunctions/String Operations
 Metafunctions/Miscellaneous
 Data Types
 Data Types/Concepts

Modified: trunk/libs/mpl/doc/src/refmanual/string.rst
==============================================================================
--- trunk/libs/mpl/doc/src/refmanual/string.rst (original)
+++ trunk/libs/mpl/doc/src/refmanual/string.rst 2009-04-11 01:48:51 EDT (Sat, 11 Apr 2009)
@@ -11,14 +11,15 @@
 Description
 -----------
 
-``string`` is a |variadic|, `random access`__, `extensible`__ |Integral Sequence Wrapper| of
+``string`` is a |variadic|, `bidirectional`__, `extensible`__ |Integral Sequence Wrapper| of
 characters that supports constant-time insertion and removal of elements at both ends, and
 linear-time insertion and removal of elements in the middle. The parameters to ``string``
 are multi-character literals, giving a somewhat readable syntax for compile-time strings.
-``string`` also has a class static null-terminated character array called ``c_str`` that
-facilitates interoperability with runtime string processing routines.
+``string`` can also be an argument to the ``c_str`` metafunction, which generates a
+null-terminated character array that facilitates interoperability with runtime string
+processing routines.
 
-__ `Random Access Sequence`_
+__ `Bidirectional Sequence`_
 __ `Extensible Sequence`_
 
 Header
@@ -35,12 +36,11 @@
 
 * |Integral Sequence Wrapper|
 * |Variadic Sequence|
-* |Random Access Sequence|
+* |Bidirectional Sequence|
 * |Extensible Sequence|
 * |Back Extensible Sequence|
 * |Front Extensible Sequence|
 
-
 Expression semantics
 --------------------
 
@@ -60,24 +60,21 @@
 | string<|c1...cn|>::type | |
 +---------------------------------------+-----------------------------------------------------------+
 | ``begin<s>::type`` | An iterator pointing to the beginning of ``s``; |
-| | see |Random Access Sequence|. |
+| | see |Bidirectional Sequence|. |
 +---------------------------------------+-----------------------------------------------------------+
 | ``end<s>::type`` | An iterator pointing to the end of ``s``; |
-| | see |Random Access Sequence|. |
+| | see |Bidirectional Sequence|. |
 +---------------------------------------+-----------------------------------------------------------+
-| ``size<s>::type`` | The size of ``s``; see |Random Access Sequence|. |
+| ``size<s>::type`` | The size of ``s``; see |Bidirectional Sequence|. |
 +---------------------------------------+-----------------------------------------------------------+
 | ``empty<s>::type`` | |true if and only if| the sequence is empty; |
-| | see |Random Access Sequence|. |
+| | see |Bidirectional Sequence|. |
 +---------------------------------------+-----------------------------------------------------------+
 | ``front<s>::type`` | The first element in ``s``; see |
-| | |Random Access Sequence|. |
+| | |Bidirectional Sequence|. |
 +---------------------------------------+-----------------------------------------------------------+
 | ``back<s>::type`` | The last element in ``s``; see |
-| | |Random Access Sequence|. |
-+---------------------------------------+-----------------------------------------------------------+
-| ``at<s,n>::type`` | The ``n``\ th element from the beginning of ``s``; see |
-| | |Random Access Sequence|. |
+| | |Bidirectional Sequence|. |
 +---------------------------------------+-----------------------------------------------------------+
 | ``insert<s,pos,x>::type`` | A new ``string`` of following elements: |
 | | [``begin<s>::type``, ``pos``), ``x``, |
@@ -114,11 +111,10 @@
 | | [``next< begin<s>::type >::type``, ``end<s>::type``); |
 | | see |Front Extensible Sequence|. |
 +---------------------------------------+-----------------------------------------------------------+
-| ``s::c_str`` | A null-terminated byte string such that |
-| | ``s::c_str[``\ *n*\ ``]`` is |
-| | ``at<s,``\ *n*\ ``>::type::value`` for each *n* in |
-| | [``0``, ``size<s>::type::value``), and |
-| | ``s::c_str[size<s>::type::value]`` is ``'\0'``. |
+| ``c_str<s>::value`` | A null-terminated byte string such that |
+| | ``c_str<s>::value[``\ *n*\ ``]`` is equal to the *n*\ -th |
+| | character in ``s``, and |
+| | ``c_str<s>::value[size<s>::type::value]`` is ``'\0'``. |
 +---------------------------------------+-----------------------------------------------------------+
 
 
@@ -127,14 +123,13 @@
 
 .. parsed-literal::
    
- typedef string<'hell','o wo','rld'> hello;
- typedef push_back<hello, char_<'!'> >::type hello2;
+ typedef mpl::string<'hell','o wo','rld'> hello;
+ typedef mpl::push_back<hello, mpl::char_<'!'> >::type hello2;
 
- BOOST_ASSERT(0 == std::strcmp(hello2::c_str, "hello world!"));
+ BOOST_ASSERT(0 == std::strcmp(mpl::c_str<hello2>::value, "hello world!"));
 
 
 See also
 --------
 
-|Sequences|, |Variadic Sequence|, |Random Access Sequence|, |Extensible Sequence|, |Integral Sequence Wrapper|, |char_|
-
+|Sequences|, |Variadic Sequence|, |Bidirectional Sequence|, |Extensible Sequence|, |Integral Sequence Wrapper|, |char_|, |c_str|

Modified: trunk/libs/mpl/test/string.cpp
==============================================================================
--- trunk/libs/mpl/test/string.cpp (original)
+++ trunk/libs/mpl/test/string.cpp 2009-04-11 01:48:51 EDT (Sat, 11 Apr 2009)
@@ -17,27 +17,21 @@
 
 #include <boost/mpl/string.hpp>
 
-#include <boost/mpl/at.hpp>
-#include <boost/mpl/long.hpp>
 #include <boost/mpl/back.hpp>
-#include <boost/mpl/copy.hpp>
-#include <boost/mpl/size.hpp>
 #include <boost/mpl/empty.hpp>
 #include <boost/mpl/front.hpp>
-#include <boost/mpl/clear.hpp>
 #include <boost/mpl/erase.hpp>
 #include <boost/mpl/insert.hpp>
-#include <boost/mpl/assert.hpp>
-#include <boost/mpl/size_t.hpp>
+#include <boost/mpl/advance.hpp>
 #include <boost/mpl/for_each.hpp>
 #include <boost/mpl/vector_c.hpp>
+#include <boost/mpl/pop_back.hpp>
+#include <boost/mpl/pop_front.hpp>
 #include <boost/mpl/push_back.hpp>
-#include <boost/mpl/joint_view.hpp>
-#include <boost/mpl/insert_range.hpp>
-#include <boost/mpl/back_inserter.hpp>
-#include <boost/mpl/iterator_range.hpp>
+#include <boost/mpl/push_front.hpp>
 #include <boost/type_traits/is_same.hpp>
 #include <boost/detail/lightweight_test.hpp>
+
 namespace mpl = boost::mpl;
 
 // Accept a string as a template parameter!
@@ -64,110 +58,418 @@
     std::string *str_;
 };
 
-void test1()
+int main()
 {
- BOOST_TEST(0 == std::strcmp(mpl::string<'Hell','o wo','rld!'>::c_str, "Hello world!"));
- BOOST_TEST((12 == mpl::size<mpl::string<'Hell','o wo','rld!'> >::type::value));
- BOOST_TEST(('w' == mpl::at_c<mpl::string<'Hell','o wo','rld!'>, 6>::type::value));
+ // Test mpl::size of strings
+ {
+ typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'> almost_full;
+ typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> full;
 
- // test using a string as a template parameter
- greeting<mpl::string<'Hell','o wo','rld!'>::c_str> g;
- BOOST_TEST("Hello world!" == g.say_hello());
+ BOOST_MPL_ASSERT_RELATION(0, ==, (mpl::size<mpl::string<> >::value));
+ BOOST_MPL_ASSERT_RELATION(1, ==, (mpl::size<mpl::string<'a'> >::value));
+ BOOST_MPL_ASSERT_RELATION(2, ==, (mpl::size<mpl::string<'ab'> >::value));
+ BOOST_MPL_ASSERT_RELATION(2, ==, (mpl::size<mpl::string<'a','b'> >::value));
+ BOOST_MPL_ASSERT_RELATION(4, ==, (mpl::size<mpl::string<'abcd'> >::value));
+ BOOST_MPL_ASSERT_RELATION(5, ==, (mpl::size<mpl::string<'abcd','e'> >::value));
+ BOOST_MPL_ASSERT_RELATION(31, ==, (mpl::size<almost_full>::value));
+ BOOST_MPL_ASSERT_RELATION(32, ==, (mpl::size<full>::value));
+ }
 
- BOOST_TEST(0 == std::strcmp("", mpl::string<>::c_str));
+ // Test mpl::begin and mpl::end with strings
+ {
+ typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'> almost_full;
+ typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> full;
 
- std::string result;
- mpl::for_each<mpl::string<'Hell','o wo','rld!'> >(push_char(result));
- BOOST_TEST("Hello world!" == result);
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::begin<mpl::string<> >::type
+ , mpl::end<mpl::string<> >::type
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::begin<mpl::string<'a'> >::type
+ , mpl::string_iterator<mpl::string<'a'>, 0, 0>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::end<mpl::string<'a'> >::type
+ , mpl::string_iterator<mpl::string<'a'>, 1, 0>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::begin<almost_full>::type
+ , mpl::string_iterator<almost_full, 0, 0>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::end<almost_full>::type
+ , mpl::string_iterator<almost_full, 8, 0>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::begin<full>::type
+ , mpl::string_iterator<full, 0, 0>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::end<full>::type
+ , mpl::string_iterator<full, 8, 0>
+ >
+ ));
+ }
 
- BOOST_MPL_ASSERT((mpl::empty<mpl::string<> >));
- BOOST_MPL_ASSERT_NOT((mpl::empty<mpl::string<'hi!'> >));
+ // testing push_back
+ {
+ typedef mpl::push_back<mpl::string<>, mpl::char_<'a'> >::type t1;
+ BOOST_MPL_ASSERT((boost::is_same<t1, mpl::string<'a'> >));
 
- BOOST_TEST(('h' == mpl::front<mpl::string<'hi!'> >::type()));
- BOOST_TEST(('!' == mpl::back<mpl::string<'hi!'> >::type()));
-}
+ typedef mpl::push_back<t1, mpl::char_<'b'> >::type t2;
+ BOOST_MPL_ASSERT((boost::is_same<t2, mpl::string<'ab'> >));
 
-// testing push_back
-void test2()
-{
- typedef mpl::push_back<mpl::string<>, mpl::char_<'a'> >::type t1;
- BOOST_TEST(0 == std::strcmp("a", t1::c_str));
+ typedef mpl::push_back<t2, mpl::char_<'c'> >::type t3;
+ BOOST_MPL_ASSERT((boost::is_same<t3, mpl::string<'abc'> >));
+
+ typedef mpl::push_back<t3, mpl::char_<'d'> >::type t4;
+ BOOST_MPL_ASSERT((boost::is_same<t4, mpl::string<'abcd'> >));
 
- typedef mpl::push_back<t1, mpl::char_<'b'> >::type t2;
- BOOST_TEST(0 == std::strcmp("ab", t2::c_str));
+ typedef mpl::push_back<t4, mpl::char_<'e'> >::type t5;
+ BOOST_MPL_ASSERT((boost::is_same<t5, mpl::string<'abcd','e'> >));
 
- typedef mpl::push_back<t2, mpl::char_<'c'> >::type t3;
- BOOST_TEST(0 == std::strcmp("abc", t3::c_str));
- BOOST_MPL_ASSERT((boost::is_same<t3, mpl::string<'abc'> >));
+ typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'> almost_full;
+ typedef mpl::push_back<almost_full, mpl::char_<'X'> >::type t6;
+ BOOST_MPL_ASSERT((boost::is_same<t6, mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaX'> >));
+ }
 
- typedef mpl::push_back<t3, mpl::char_<'d'> >::type t4;
- BOOST_TEST(0 == std::strcmp("abcd", t4::c_str));
+ // Test mpl::next
+ {
+ typedef mpl::string<'a','bc','def','ghij'> s;
 
- typedef mpl::push_back<t4, mpl::char_<'e'> >::type t5;
- BOOST_TEST(0 == std::strcmp("abcde", t5::c_str));
- BOOST_MPL_ASSERT((boost::is_same<t5, mpl::string<'abcd','e'> >));
+ typedef mpl::begin<s>::type i0;
+ BOOST_MPL_ASSERT((boost::is_same<i0, mpl::string_iterator<s,0,0> >));
 
- typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'> almost_full;
- BOOST_TEST(0 == std::strcmp("aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaa", almost_full::c_str));
+ typedef mpl::next<i0>::type i1;
+ BOOST_MPL_ASSERT((boost::is_same<i1, mpl::string_iterator<s,1,0> >));
 
- typedef mpl::push_back<almost_full, mpl::char_<'X'> >::type t6;
- BOOST_TEST(0 == std::strcmp("aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaX", t6::c_str));
-}
+ typedef mpl::next<i1>::type i2;
+ BOOST_MPL_ASSERT((boost::is_same<i2, mpl::string_iterator<s,1,1> >));
 
-// testing push_front
-void test3()
-{
- typedef mpl::push_front<mpl::string<>, mpl::char_<'a'> >::type t1;
- BOOST_TEST(0 == std::strcmp("a", t1::c_str));
+ typedef mpl::next<i2>::type i3;
+ BOOST_MPL_ASSERT((boost::is_same<i3, mpl::string_iterator<s,2,0> >));
 
- typedef mpl::push_front<t1, mpl::char_<'b'> >::type t2;
- BOOST_TEST(0 == std::strcmp("ba", t2::c_str));
+ typedef mpl::next<i3>::type i4;
+ BOOST_MPL_ASSERT((boost::is_same<i4, mpl::string_iterator<s,2,1> >));
 
- typedef mpl::push_front<t2, mpl::char_<'c'> >::type t3;
- BOOST_TEST(0 == std::strcmp("cba", t3::c_str));
+ typedef mpl::next<i4>::type i5;
+ BOOST_MPL_ASSERT((boost::is_same<i5, mpl::string_iterator<s,2,2> >));
 
- typedef mpl::push_front<t3, mpl::char_<'d'> >::type t4;
- BOOST_TEST(0 == std::strcmp("dcba", t4::c_str));
+ typedef mpl::next<i5>::type i6;
+ BOOST_MPL_ASSERT((boost::is_same<i6, mpl::string_iterator<s,3,0> >));
 
- typedef mpl::push_front<t4, mpl::char_<'e'> >::type t5;
- BOOST_TEST(0 == std::strcmp("edcba", t5::c_str));
+ typedef mpl::next<i6>::type i7;
+ BOOST_MPL_ASSERT((boost::is_same<i7, mpl::string_iterator<s,3,1> >));
 
- typedef mpl::string<'aaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> almost_full;
- BOOST_TEST(0 == std::strcmp("aaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa", almost_full::c_str));
+ typedef mpl::next<i7>::type i8;
+ BOOST_MPL_ASSERT((boost::is_same<i8, mpl::string_iterator<s,3,2> >));
 
- typedef mpl::push_front<almost_full, mpl::char_<'X'> >::type t6;
- BOOST_TEST(0 == std::strcmp("Xaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa", t6::c_str));
-}
+ typedef mpl::next<i8>::type i9;
+ BOOST_MPL_ASSERT((boost::is_same<i9, mpl::string_iterator<s,3,3> >));
+
+ typedef mpl::next<i9>::type i10;
+ BOOST_MPL_ASSERT((boost::is_same<i10, mpl::string_iterator<s,4,0> >));
+
+ BOOST_MPL_ASSERT((boost::is_same<i10, mpl::end<s>::type>));
+ }
+
+ // Test mpl::prior
+ {
+ typedef mpl::string<'a','bc','def','ghij'> s;
+
+ typedef mpl::end<s>::type i10;
+ BOOST_MPL_ASSERT((boost::is_same<i10, mpl::string_iterator<s,4,0> >));
+
+ typedef mpl::prior<i10>::type i9;
+ BOOST_MPL_ASSERT((boost::is_same<i9, mpl::string_iterator<s,3,3> >));
+
+ typedef mpl::prior<i9>::type i8;
+ BOOST_MPL_ASSERT((boost::is_same<i8, mpl::string_iterator<s,3,2> >));
+
+ typedef mpl::prior<i8>::type i7;
+ BOOST_MPL_ASSERT((boost::is_same<i7, mpl::string_iterator<s,3,1> >));
+
+ typedef mpl::prior<i7>::type i6;
+ BOOST_MPL_ASSERT((boost::is_same<i6, mpl::string_iterator<s,3,0> >));
+
+ typedef mpl::prior<i6>::type i5;
+ BOOST_MPL_ASSERT((boost::is_same<i5, mpl::string_iterator<s,2,2> >));
+
+ typedef mpl::prior<i5>::type i4;
+ BOOST_MPL_ASSERT((boost::is_same<i4, mpl::string_iterator<s,2,1> >));
+
+ typedef mpl::prior<i4>::type i3;
+ BOOST_MPL_ASSERT((boost::is_same<i3, mpl::string_iterator<s,2,0> >));
+
+ typedef mpl::prior<i3>::type i2;
+ BOOST_MPL_ASSERT((boost::is_same<i2, mpl::string_iterator<s,1,1> >));
+
+ typedef mpl::prior<i2>::type i1;
+ BOOST_MPL_ASSERT((boost::is_same<i1, mpl::string_iterator<s,1,0> >));
+
+ typedef mpl::prior<i1>::type i0;
+ BOOST_MPL_ASSERT((boost::is_same<i0, mpl::string_iterator<s,0,0> >));
+
+ BOOST_MPL_ASSERT((boost::is_same<i0, mpl::begin<s>::type>));
+ }
+
+ // Test mpl::deref
+ {
+ typedef mpl::string<'a','bc','def','ghij'> s;
+
+ typedef mpl::begin<s>::type i0;
+ BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i0>::type, mpl::char_<'a'> >));
+
+ typedef mpl::next<i0>::type i1;
+ BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i1>::type, mpl::char_<'b'> >));
+
+ typedef mpl::next<i1>::type i2;
+ BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i2>::type, mpl::char_<'c'> >));
+
+ typedef mpl::next<i2>::type i3;
+ BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i3>::type, mpl::char_<'d'> >));
+
+ typedef mpl::next<i3>::type i4;
+ BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i4>::type, mpl::char_<'e'> >));
+
+ typedef mpl::next<i4>::type i5;
+ BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i5>::type, mpl::char_<'f'> >));
+
+ typedef mpl::next<i5>::type i6;
+ BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i6>::type, mpl::char_<'g'> >));
+
+ typedef mpl::next<i6>::type i7;
+ BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i7>::type, mpl::char_<'h'> >));
+
+ typedef mpl::next<i7>::type i8;
+ BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i8>::type, mpl::char_<'i'> >));
+
+ typedef mpl::next<i8>::type i9;
+ BOOST_MPL_ASSERT((boost::is_same<mpl::deref<i9>::type, mpl::char_<'j'> >));
+ }
+
+ // testing push_back
+ {
+ typedef mpl::push_back<mpl::string<>, mpl::char_<'a'> >::type t1;
+ BOOST_MPL_ASSERT((boost::is_same<t1, mpl::string<'a'> >));
+
+ typedef mpl::push_back<t1, mpl::char_<'b'> >::type t2;
+ BOOST_MPL_ASSERT((boost::is_same<t2, mpl::string<'ab'> >));
+
+ typedef mpl::push_back<t2, mpl::char_<'c'> >::type t3;
+ BOOST_MPL_ASSERT((boost::is_same<t3, mpl::string<'abc'> >));
+
+ typedef mpl::push_back<t3, mpl::char_<'d'> >::type t4;
+ BOOST_MPL_ASSERT((boost::is_same<t4, mpl::string<'abcd'> >));
+
+ typedef mpl::push_back<t4, mpl::char_<'e'> >::type t5;
+ BOOST_MPL_ASSERT((boost::is_same<t5, mpl::string<'abcd','e'> >));
+
+ typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'> almost_full;
+ typedef mpl::push_back<almost_full, mpl::char_<'X'> >::type t6;
+ BOOST_MPL_ASSERT((boost::is_same<t6, mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaX'> >));
+
+ typedef mpl::string<'a','a','a','a','a','a','a','aaaa'> must_repack;
+ typedef mpl::push_back<must_repack, mpl::char_<'X'> >::type t7;
+ BOOST_MPL_ASSERT((boost::is_same<t7, mpl::string<'aaaa','aaaa','aaaX'> >));
+ }
+
+ // testing push_front
+ {
+ typedef mpl::push_front<mpl::string<>, mpl::char_<'a'> >::type t1;
+ BOOST_MPL_ASSERT((boost::is_same<t1, mpl::string<'a'> >));
+
+ typedef mpl::push_front<t1, mpl::char_<'b'> >::type t2;
+ BOOST_MPL_ASSERT((boost::is_same<t2, mpl::string<'ba'> >));
+
+ typedef mpl::push_front<t2, mpl::char_<'c'> >::type t3;
+ BOOST_MPL_ASSERT((boost::is_same<t3, mpl::string<'cba'> >));
+
+ typedef mpl::push_front<t3, mpl::char_<'d'> >::type t4;
+ BOOST_MPL_ASSERT((boost::is_same<t4, mpl::string<'dcba'> >));
+
+ typedef mpl::push_front<t4, mpl::char_<'e'> >::type t5;
+ BOOST_MPL_ASSERT((boost::is_same<t5, mpl::string<'e','dcba'> >));
+
+ typedef mpl::string<'aaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> almost_full;
+ typedef mpl::push_front<almost_full, mpl::char_<'X'> >::type t6;
+ BOOST_MPL_ASSERT((boost::is_same<t6, mpl::string<'Xaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> >));
+
+ typedef mpl::string<'aaaa','a','a','a','a','a','a','a'> must_repack;
+ typedef mpl::push_front<must_repack, mpl::char_<'X'> >::type t7;
+ BOOST_MPL_ASSERT((boost::is_same<t7, mpl::string<'Xaaa','aaaa','aaaa'> >));
+ }
+
+ // Test c_str<>
+ BOOST_TEST(0 == std::strcmp(
+ mpl::c_str<mpl::string<> >::value
+ , ""
+ ));
+
+ BOOST_TEST(0 == std::strcmp(
+ mpl::c_str<mpl::string<'Hell','o wo','rld!'> >::value
+ , "Hell" "o wo" "rld!"
+ ));
+
+ BOOST_TEST(0 == std::strcmp(
+ mpl::c_str<mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaX'> >::value
+ , "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaX"
+ ));
+
+ // test using a string as a template parameter
+ greeting<mpl::c_str<mpl::string<'Hell','o wo','rld!'> >::value> g;
+ BOOST_TEST("Hello world!" == g.say_hello());
+
+ std::string result;
+ mpl::for_each<mpl::string<'Hell','o wo','rld!'> >(push_char(result));
+ BOOST_TEST("Hello world!" == result);
+
+ BOOST_MPL_ASSERT((mpl::empty<mpl::string<> >));
+ BOOST_MPL_ASSERT_NOT((mpl::empty<mpl::string<'hi!'> >));
+
+ BOOST_TEST(('h' == mpl::front<mpl::string<'hi!'> >::type()));
+ BOOST_TEST(('!' == mpl::back<mpl::string<'hi!'> >::type()));
 
-void test4()
-{
     // back-inserter with copy
     typedef mpl::vector_c<char, 'a','b','c','d','e'> rgc;
+ BOOST_TEST(0 == std::strcmp("abcde", mpl::c_str<rgc>::value));
     typedef mpl::copy<rgc, mpl::back_inserter<mpl::string<> > >::type str;
- BOOST_TEST(0 == std::strcmp("abcde", str::c_str));
-}
+ BOOST_TEST(0 == std::strcmp("abcde", mpl::c_str<str>::value));
 
-// test insert_range and erase
-void test5()
-{
- typedef mpl::string<'Hell','o wo','rld!'> hello;
- typedef mpl::advance_c<mpl::begin<hello>::type, 5>::type where;
- typedef mpl::string<' cru','el'> cruel;
- typedef mpl::insert_range<hello, where, cruel>::type hello_cruel;
- BOOST_TEST(0 == std::strcmp("Hello cruel world!", hello_cruel::c_str));
+ // test insert_range and erase
+ {
+ typedef mpl::string<'Hell','o wo','rld!'> hello;
+ typedef mpl::advance_c<mpl::begin<hello>::type, 5>::type where;
+ typedef mpl::string<' cru','el'> cruel;
+ typedef mpl::insert_range<hello, where, cruel>::type hello_cruel;
+ BOOST_TEST(0 == std::strcmp("Hello cruel world!", mpl::c_str<hello_cruel>::value));
 
- typedef mpl::erase<hello, mpl::begin<hello>::type, where>::type erased1;
- BOOST_TEST(0 == std::strcmp(" world!", erased1::c_str));
-}
+ typedef mpl::erase<hello, mpl::begin<hello>::type, where>::type erased1;
+ BOOST_TEST(0 == std::strcmp(" world!", mpl::c_str<erased1>::value));
+ }
 
+ // test pop_front
+ {
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_front<mpl::string<'a'> >::type
+ , mpl::string<>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_front<mpl::string<'ab'> >::type
+ , mpl::string<'b'>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_front<mpl::string<'abc'> >::type
+ , mpl::string<'bc'>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_front<mpl::string<'abcd'> >::type
+ , mpl::string<'bcd'>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_front<mpl::string<'abcd','e'> >::type
+ , mpl::string<'bcd','e'>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_front<mpl::string<'d','e'> >::type
+ , mpl::string<'e'>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_front<mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> >::type
+ , mpl::string<'aaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'>
+ >
+ ));
+ }
 
-int main()
-{
- test1();
- test2();
- test3();
- test4();
- test5();
+ // test pop_back
+ {
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_back<mpl::string<'a'> >::type
+ , mpl::string<>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_back<mpl::string<'ab'> >::type
+ , mpl::string<'a'>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_back<mpl::string<'abc'> >::type
+ , mpl::string<'ab'>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_back<mpl::string<'abcd'> >::type
+ , mpl::string<'abc'>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_back<mpl::string<'abcd','e'> >::type
+ , mpl::string<'abcd'>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_back<mpl::string<'d','e'> >::type
+ , mpl::string<'d'>
+ >
+ ));
+
+ BOOST_MPL_ASSERT((
+ boost::is_same<
+ mpl::pop_back<mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> >::type
+ , mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'>
+ >
+ ));
+ }
 
     return boost::report_errors();
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk