$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r53838 - in branches/release: . boost/mpl boost/mpl/limits libs/mpl/doc/src/refmanual libs/mpl/test
From: eric_at_[hidden]
Date: 2009-06-12 21:03:46
Author: eric_niebler
Date: 2009-06-12 21:03:44 EDT (Fri, 12 Jun 2009)
New Revision: 53838
URL: http://svn.boost.org/trac/boost/changeset/53838
Log:
Merged revisions 52208,52241,52271,52314-52315,52317,52361,52542,52579 via svnmerge from 
https://svn.boost.org/svn/boost/trunk
Added:
   branches/release/boost/mpl/char.hpp
      - copied unchanged from r52208, /trunk/boost/mpl/char.hpp
   branches/release/boost/mpl/char_fwd.hpp
      - copied unchanged from r52208, /trunk/boost/mpl/char_fwd.hpp
   branches/release/boost/mpl/limits/string.hpp
      - copied unchanged from r52317, /trunk/boost/mpl/limits/string.hpp
   branches/release/boost/mpl/string.hpp
      - copied, changed from r52208, /trunk/boost/mpl/string.hpp
   branches/release/libs/mpl/doc/src/refmanual/LIMIT_STRING_SIZE.rst
      - copied unchanged from r52317, /trunk/libs/mpl/doc/src/refmanual/LIMIT_STRING_SIZE.rst
   branches/release/libs/mpl/doc/src/refmanual/c_str.rst
      - copied unchanged from r52315, /trunk/libs/mpl/doc/src/refmanual/c_str.rst
   branches/release/libs/mpl/doc/src/refmanual/char_.rst
      - copied unchanged from r52208, /trunk/libs/mpl/doc/src/refmanual/char_.rst
   branches/release/libs/mpl/doc/src/refmanual/string.rst
      - copied, changed from r52208, /trunk/libs/mpl/doc/src/refmanual/string.rst
   branches/release/libs/mpl/test/char.cpp
      - copied unchanged from r52208, /trunk/libs/mpl/test/char.cpp
   branches/release/libs/mpl/test/string.cpp
      - copied, changed from r52208, /trunk/libs/mpl/test/string.cpp
Properties modified: 
   branches/release/   (props changed)
Text files modified: 
   branches/release/boost/mpl/string.hpp                            |   545 +++++++++++++++++++++++++-------------- 
   branches/release/libs/mpl/doc/src/refmanual/IntegralConstant.rst |     1                                         
   branches/release/libs/mpl/doc/src/refmanual/refmanual.toc        |     1                                         
   branches/release/libs/mpl/doc/src/refmanual/string.rst           |    49 +-                                      
   branches/release/libs/mpl/test/Jamfile.v2                        |     2                                         
   branches/release/libs/mpl/test/string.cpp                        |   476 ++++++++++++++++++++++++++++------      
   6 files changed, 767 insertions(+), 307 deletions(-)
Copied: branches/release/boost/mpl/string.hpp (from r52208, /trunk/boost/mpl/string.hpp)
==============================================================================
--- /trunk/boost/mpl/string.hpp	(original)
+++ branches/release/boost/mpl/string.hpp	2009-06-12 21:03:44 EDT (Fri, 12 Jun 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.
@@ -13,22 +13,32 @@
 // $Id: string.hpp 49239 2009-04-01 09:10:26Z eric_niebler $
 // $Date: 2009-04-01 02:10:26 -0700 (Wed, 1 Apr 2009) $
 // $Revision: 49239 $
+//
+// Thanks to:
+//   Dmitry Goncharov for porting this to the Sun compiler
 
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+#include <boost/detail/endian.hpp>
+#include <boost/mpl/limits/string.hpp>
+#include <boost/mpl/if.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/empty.hpp>
 #include <boost/mpl/assert.hpp>
 #include <boost/mpl/size_t.hpp>
+#include <boost/mpl/begin_end.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>
@@ -37,22 +47,58 @@
 
 namespace boost { namespace mpl
 {
-    #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_STRING_MAX_PARAMS                                                             \
+      BOOST_PP_DIV(BOOST_PP_ADD(BOOST_MPL_LIMIT_STRING_SIZE, 3), 4)
+
+    // Low-level bit-twiddling is done by macros. Any implementation-defined behavior of
+    // multi-character literals should be localized to these macros.
+
+    #define BOOST_MPL_MULTICHAR_LENGTH(c)                                                           \
+      (std::size_t)((c>0xffffff)+(c>0xffff)+(c>0xff)+1)
+
+    #if defined(BOOST_LITTLE_ENDIAN) && defined(__SUNPRO_CC)
+
+        #define BOOST_MPL_MULTICHAR_AT(c,i)                                                         \
+          (char)(0xff&(c>>(8*(std::size_t)(i))))
+
+        #define BOOST_MPL_MULTICHAR_PUSH_BACK(c,i)                                                  \
+          ((((unsigned char)(i))<<(BOOST_MPL_MULTICHAR_LENGTH(c)*8))|(c))
+
+        #define BOOST_MPL_MULTICHAR_PUSH_FRONT(c,i)                                                 \
+          (((c)<<8)|(unsigned char)(i))
+
+        #define BOOST_MPL_MULTICHAR_POP_BACK(c)                                                     \
+          (((1<<((BOOST_MPL_MULTICHAR_LENGTH(c)-1)*8))-1)&(c))
+
+        #define BOOST_MPL_MULTICHAR_POP_FRONT(c)                                                    \
+          ((c)>>8)
+
+    #else
+
+        #define BOOST_MPL_MULTICHAR_AT(c,i)                                                         \
+          (char)(0xff&(c>>(8*(BOOST_MPL_MULTICHAR_LENGTH(c)-(std::size_t)(i)-1))))
+
+        #define BOOST_MPL_MULTICHAR_PUSH_BACK(c,i)                                                  \
+          (((c)<<8)|(unsigned char)(i))
+
+        #define BOOST_MPL_MULTICHAR_PUSH_FRONT(c,i)                                                 \
+          ((((unsigned char)(i))<<(BOOST_MPL_MULTICHAR_LENGTH(c)*8))|(c))
+
+        #define BOOST_MPL_MULTICHAR_POP_BACK(c)                                                     \
+          ((c)>>8)
 
-    #define BOOST_MPL_MULTICHAR_LENGTH(c)   (std::size_t)((c>0xffffff)+(c>0xffff)+(c>0xff)+1)
-    #define BOOST_MPL_MULTICHAR_AT(c,i)     (char)(0xff&(c>>(8*(BOOST_MPL_MULTICHAR_LENGTH(c)-(std::size_t)(i)-1))))
+        #define BOOST_MPL_MULTICHAR_POP_FRONT(c)                                                    \
+          (((1<<((BOOST_MPL_MULTICHAR_LENGTH(c)-1)*8))-1)&(c))
+
+    #endif
 
     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, long N>
+    template<typename Sequence, unsigned I, unsigned J>
     struct string_iterator;
 
     template<typename Sequence>
@@ -62,36 +108,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;
         };
     };
 
@@ -99,102 +149,226 @@
     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_LIMIT_STRING_SIZE != 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_MPL_MULTICHAR_PUSH_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(n)), 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, ~)
+        BOOST_PP_REPEAT_FROM_TO(1, 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_MPL_MULTICHAR_PUSH_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS)), 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_MPL_MULTICHAR_POP_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(n)))                   \
+                >                                                                                   \
+            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_LIMIT_STRING_SIZE != 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;
         };
 
+        #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
         template<typename Value>
-        struct apply<string<>, Value, false>
+        struct apply<mpl::string<>, Value, false>
+        {
+            typedef mpl::string<(char)Value::value> type;
+        };
+        #endif
+
+        #define M0(z,n,data)                                                                        \
+        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                                                                                 \
+                mpl::string<                                                                        \
+                    (char)Value::value                                                              \
+                    BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, C)                                        \
+                >                                                                                   \
+            type;                                                                                   \
+        };
+
+        BOOST_PP_REPEAT_FROM_TO(1, BOOST_MPL_STRING_MAX_PARAMS, M0, ~)
+        #undef M0
+
+        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<(char)Value::value> type;
+            typedef
+                mpl::string<
+                    BOOST_MPL_MULTICHAR_PUSH_FRONT(C0, Value::value)
+                  , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)
+                >
+            type0;
+
+            #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
+            typedef
+                typename mpl::if_<
+                    mpl::empty<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> >
+                  , mpl::string<(char)Value::value>
+                  , type0
+                >::type
+            type;
+            #else
+            typedef type0 type;
+            #endif
         };
+    };
+
+    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 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)>                                          \
+        struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, true>                            \
         {                                                                                           \
-            typedef string<                                                                         \
-                (char)Value::value                                                                  \
-                BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, C)                                            \
-            > type;                                                                                 \
+            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, ~)
+        BOOST_PP_REPEAT_FROM_TO(1, 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)>
+        struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, 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<
+                    BOOST_MPL_MULTICHAR_POP_FRONT(C0)
+                  , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)
+                >
+            type;
         };
     };
 
@@ -202,25 +376,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<> >
             >
         {};
     };
@@ -229,11 +403,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> >
         {};
     };
 
@@ -241,22 +415,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<> >
             >
         {};
     };
@@ -265,132 +439,117 @@
     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>   \
+    {                                                                                                 \
+        enum { eomc_ = (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == J + 1) };                   \
+        typedef mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> string;             \
+        typedef std::bidirectional_iterator_tag category;                                             \
+        typedef                                                                                       \
+            mpl::string_iterator<string, n + eomc_, eomc_ ? 0 : J + 1>                                \
+        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>   \
+    {                                                                                                 \
+        enum { eomc_ = (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == 1) };                       \
+        typedef mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> string;             \
+        typedef std::bidirectional_iterator_tag category;                                             \
+        typedef                                                                                       \
+            mpl::string_iterator<string, n + eomc_, !eomc_>                                           \
+        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_<Last::index - First::index> type;
+            front_  = C0
+          , back_   = BOOST_PP_CAT(C, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS))
         };
-    };
 
-    template<typename Sequence, 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 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;
-
-        template<long Pos, bool B = (Pos < BOOST_MPL_MULTICHAR_LENGTH(C0))>
-        struct at
-          : boost::mpl::char_<BOOST_MPL_MULTICHAR_AT(C0,Pos)>
+        template<typename It, typename End>
+        struct next_unless
+          : mpl::next<It>
         {};
 
-        template<long Pos>
-        struct at<Pos, false>
-          : rest_::template at<Pos-BOOST_MPL_MULTICHAR_LENGTH(C0)>
+        template<typename End>
+        struct next_unless<End, End>
+        {
+            typedef End type;
+        };
+
+        template<typename It, typename End>
+        struct deref_unless
+          : mpl::deref<It>
         {};
 
-        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_LIMIT_STRING_SIZE, 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 int>
-        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_LIMIT_STRING_SIZE, 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
Modified: branches/release/libs/mpl/doc/src/refmanual/IntegralConstant.rst
==============================================================================
--- branches/release/libs/mpl/doc/src/refmanual/IntegralConstant.rst	(original)
+++ branches/release/libs/mpl/doc/src/refmanual/IntegralConstant.rst	2009-06-12 21:03:44 EDT (Fri, 12 Jun 2009)
@@ -71,6 +71,7 @@
 * |bool_|
 * |int_|
 * |long_|
+* |char_|
 * |integral_c|
 
 
Modified: branches/release/libs/mpl/doc/src/refmanual/refmanual.toc
==============================================================================
--- branches/release/libs/mpl/doc/src/refmanual/refmanual.toc	(original)
+++ branches/release/libs/mpl/doc/src/refmanual/refmanual.toc	2009-06-12 21:03:44 EDT (Fri, 12 Jun 2009)
@@ -23,6 +23,7 @@
 Metafunctions/Logical Operations
 Metafunctions/Bitwise Operations
 Metafunctions/Trivial
+Metafunctions/String Operations
 Metafunctions/Miscellaneous
 Data Types
 Data Types/Concepts
Copied: branches/release/libs/mpl/doc/src/refmanual/string.rst (from r52208, /trunk/libs/mpl/doc/src/refmanual/string.rst)
==============================================================================
--- /trunk/libs/mpl/doc/src/refmanual/string.rst	(original)
+++ branches/release/libs/mpl/doc/src/refmanual/string.rst	2009-06-12 21:03:44 EDT (Fri, 12 Jun 2009)
@@ -11,14 +11,15 @@
 Description
 -----------
 
-``string`` is a |variadic|, `random access`__, `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``
+``string`` is a |variadic|, `bidirectional`__, `extensible`__ |Integral Sequence Wrapper| of
+characters that supports amortized 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: branches/release/libs/mpl/test/Jamfile.v2
==============================================================================
--- branches/release/libs/mpl/test/Jamfile.v2	(original)
+++ branches/release/libs/mpl/test/Jamfile.v2	2009-06-12 21:03:44 EDT (Fri, 12 Jun 2009)
@@ -44,6 +44,7 @@
 compile insert.cpp ;
 compile insert_range.cpp ;
 run int.cpp ;
+run char.cpp ;
 run integral_c.cpp : : : <toolset>vacpp:<cxxflags>-qchars=signed ;
 compile is_placeholder.cpp ;
 compile is_sequence.cpp ;
@@ -90,3 +91,4 @@
 compile vector.cpp ;
 compile vector_c.cpp ;
 compile zip_view.cpp ;
+run string.cpp ;
Copied: branches/release/libs/mpl/test/string.cpp (from r52208, /trunk/libs/mpl/test/string.cpp)
==============================================================================
--- /trunk/libs/mpl/test/string.cpp	(original)
+++ branches/release/libs/mpl/test/string.cpp	2009-06-12 21:03:44 EDT (Fri, 12 Jun 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'> >));
+    }
+
+    BOOST_MPL_ASSERT((mpl::empty<mpl::string<> >));
+    BOOST_MPL_ASSERT_NOT((mpl::empty<mpl::string<'hi!'> >));
+
+    // 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_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();
 }