608 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			608 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
|   | 
 | ||
|  | #ifndef BOOST_MPL_STRING_HPP_INCLUDED
 | ||
|  | #define BOOST_MPL_STRING_HPP_INCLUDED
 | ||
|  | 
 | ||
|  | // 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)
 | ||
|  | //
 | ||
|  | // See http://www.boost.org/libs/mpl for documentation.
 | ||
|  | 
 | ||
|  | // $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/predef/other/endian.h>
 | ||
|  | #include <boost/mpl/limits/string.hpp>
 | ||
|  | #include <boost/mpl/if.hpp>
 | ||
|  | #include <boost/mpl/char.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/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>
 | ||
|  | #include <boost/preprocessor/repetition/enum_trailing_params.hpp>
 | ||
|  | #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
 | ||
|  | 
 | ||
|  | #include <iterator> // for bidirectional_iterator_tag
 | ||
|  | #include <climits>
 | ||
|  | 
 | ||
|  | namespace boost { namespace mpl | ||
|  | { | ||
|  |     #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<CHAR_MIN) ? 4 : ((c>0xffffff)+(c>0xffff)+(c>0xff)+1)) | ||
|  | 
 | ||
|  |     #if BOOST_ENDIAN_LITTLE_BYTE && defined(__SUNPRO_CC)
 | ||
|  | 
 | ||
|  |         #define BOOST_MPL_MULTICHAR_AT(c,i)                                                         \
 | ||
|  |           (char)(0xff&((unsigned)(c)>>(8*(std::size_t)(i)))) | ||
|  | 
 | ||
|  |         #define BOOST_MPL_MULTICHAR_PUSH_BACK(c,i)                                                  \
 | ||
|  |           ((((unsigned char)(i))<<(BOOST_MPL_MULTICHAR_LENGTH(c)*8))|(unsigned)(c)) | ||
|  | 
 | ||
|  |         #define BOOST_MPL_MULTICHAR_PUSH_FRONT(c,i)                                                 \
 | ||
|  |           (((unsigned)(c)<<8)|(unsigned char)(i)) | ||
|  | 
 | ||
|  |         #define BOOST_MPL_MULTICHAR_POP_BACK(c)                                                     \
 | ||
|  |           (((1<<((BOOST_MPL_MULTICHAR_LENGTH(c)-1)*8))-1)&(unsigned)(c)) | ||
|  | 
 | ||
|  |         #define BOOST_MPL_MULTICHAR_POP_FRONT(c)                                                    \
 | ||
|  |           ((unsigned)(c)>>8) | ||
|  | 
 | ||
|  |     #else
 | ||
|  | 
 | ||
|  |         #define BOOST_MPL_MULTICHAR_AT(c,i)                                                         \
 | ||
|  |           (char)(0xff&((unsigned)(c)>>(8*(BOOST_MPL_MULTICHAR_LENGTH(c)-(std::size_t)(i)-1)))) | ||
|  | 
 | ||
|  |         #define BOOST_MPL_MULTICHAR_PUSH_BACK(c,i)                                                  \
 | ||
|  |           (((unsigned)(c)<<8)|(unsigned char)(i)) | ||
|  | 
 | ||
|  |         #define BOOST_MPL_MULTICHAR_PUSH_FRONT(c,i)                                                 \
 | ||
|  |           ((((unsigned char)(i))<<(BOOST_MPL_MULTICHAR_LENGTH(c)*8))|(unsigned)(c)) | ||
|  | 
 | ||
|  |         #define BOOST_MPL_MULTICHAR_POP_BACK(c)                                                     \
 | ||
|  |           ((unsigned)(c)>>8) | ||
|  | 
 | ||
|  |         #define BOOST_MPL_MULTICHAR_POP_FRONT(c)                                                    \
 | ||
|  |           (((1<<((BOOST_MPL_MULTICHAR_LENGTH(c)-1)*8))-1)&(unsigned)(c)) | ||
|  | 
 | ||
|  |     #endif
 | ||
|  | 
 | ||
|  |     struct string_tag; | ||
|  |     struct string_iterator_tag; | ||
|  | 
 | ||
|  |     template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_MPL_STRING_MAX_PARAMS, int C, 0)> | ||
|  |     struct string; | ||
|  | 
 | ||
|  |     template<typename Sequence, int I, int J> | ||
|  |     struct string_iterator; | ||
|  | 
 | ||
|  |     template<typename Sequence> | ||
|  |     struct sequence_tag; | ||
|  | 
 | ||
|  |     template<typename Tag> | ||
|  |     struct size_impl; | ||
|  | 
 | ||
|  |     template<> | ||
|  |     struct size_impl<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename Sequence> | ||
|  |         struct apply; | ||
|  | 
 | ||
|  |         #define M0(z, n, data)                                                                      \
 | ||
|  |         + BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C,n)) | ||
|  | 
 | ||
|  |         #define M1(z, n, data)                                                                      \
 | ||
|  |         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int 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<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename Sequence> | ||
|  |         struct apply | ||
|  |         { | ||
|  |             typedef mpl::string_iterator<Sequence, 0, 0> type; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Tag> | ||
|  |     struct end_impl; | ||
|  | 
 | ||
|  |     template<> | ||
|  |     struct end_impl<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename Sequence> | ||
|  |         struct apply; | ||
|  | 
 | ||
|  |         #define M0(z,n,data)                                                                        \
 | ||
|  |         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int 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<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename Sequence, typename Value, bool B = (4==BOOST_MPL_MULTICHAR_LENGTH(Sequence::back_))> | ||
|  |         struct apply | ||
|  |         { | ||
|  |             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<mpl::string<>, Value, false> | ||
|  |         { | ||
|  |             typedef mpl::string<(char)Value::value> type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         #define M0(z,n,data)                                                                        \
 | ||
|  |         template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C), typename Value>                               \ | ||
|  |         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, false>                    \ | ||
|  |         {                                                                                           \ | ||
|  |             typedef                                                                                 \ | ||
|  |                 mpl::string<                                                                        \ | ||
|  |                     BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), C)                                   \ | ||
|  |                     BOOST_PP_COMMA_IF(BOOST_PP_DEC(n))                                              \ | ||
|  |                     ((unsigned)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)   \ | ||
|  |                   , ((unsigned)BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff)                            \ | ||
|  |                     ?(char)Value::value                                                             \ | ||
|  |                     :0                                                                              \ | ||
|  |                 >                                                                                   \ | ||
|  |             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, int C), typename Value> | ||
|  |         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false> | ||
|  |         { | ||
|  |             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 has_push_back_impl; | ||
|  | 
 | ||
|  |     template<> | ||
|  |     struct has_push_back_impl<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename Sequence> | ||
|  |         struct apply | ||
|  |           : mpl::true_ | ||
|  |         {}; | ||
|  |     }; | ||
|  | 
 | ||
|  |     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, int 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 has_pop_back_impl; | ||
|  | 
 | ||
|  |     template<> | ||
|  |     struct has_pop_back_impl<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename Sequence> | ||
|  |         struct apply | ||
|  |           : mpl::true_ | ||
|  |         {}; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Tag> | ||
|  |     struct push_front_impl; | ||
|  | 
 | ||
|  |     template<> | ||
|  |     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( | ||
|  |                 (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<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, int 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, int C), typename Value> | ||
|  |         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false> | ||
|  |         { | ||
|  |             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 has_push_front_impl; | ||
|  | 
 | ||
|  |     template<> | ||
|  |     struct has_push_front_impl<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename Sequence> | ||
|  |         struct apply | ||
|  |           : mpl::true_ | ||
|  |         {}; | ||
|  |     }; | ||
|  | 
 | ||
|  |     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, int 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_MPL_STRING_MAX_PARAMS, M0, ~) | ||
|  |         #undef M0
 | ||
|  | 
 | ||
|  |         template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C)> | ||
|  |         struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, false> | ||
|  |         { | ||
|  |             typedef | ||
|  |                 mpl::string< | ||
|  |                     BOOST_MPL_MULTICHAR_POP_FRONT(C0) | ||
|  |                   , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C) | ||
|  |                 > | ||
|  |             type; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Tag> | ||
|  |     struct has_pop_front_impl; | ||
|  | 
 | ||
|  |     template<> | ||
|  |     struct has_pop_front_impl<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename Sequence> | ||
|  |         struct apply | ||
|  |           : mpl::true_ | ||
|  |         {}; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Tag> | ||
|  |     struct insert_range_impl; | ||
|  | 
 | ||
|  |     template<> | ||
|  |     struct insert_range_impl<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename Sequence, typename Pos, typename Range> | ||
|  |         struct apply | ||
|  |           : mpl::copy< | ||
|  |                 mpl::joint_view< | ||
|  |                     mpl::iterator_range< | ||
|  |                         mpl::string_iterator<Sequence, 0, 0> | ||
|  |                       , Pos | ||
|  |                     > | ||
|  |                   , mpl::joint_view< | ||
|  |                         Range | ||
|  |                       , mpl::iterator_range< | ||
|  |                             Pos | ||
|  |                           , typename mpl::end<Sequence>::type | ||
|  |                         > | ||
|  |                     > | ||
|  |                 > | ||
|  |               , mpl::back_inserter<mpl::string<> > | ||
|  |             > | ||
|  |         {}; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Tag> | ||
|  |     struct insert_impl; | ||
|  | 
 | ||
|  |     template<> | ||
|  |     struct insert_impl<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename Sequence, typename Pos, typename Value> | ||
|  |         struct apply | ||
|  |           : mpl::insert_range<Sequence, Pos, mpl::string<(char)Value::value> > | ||
|  |         {}; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Tag> | ||
|  |     struct erase_impl; | ||
|  | 
 | ||
|  |     template<> | ||
|  |     struct erase_impl<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename Sequence, typename First, typename Last> | ||
|  |         struct apply | ||
|  |           : mpl::copy< | ||
|  |                 mpl::joint_view< | ||
|  |                     mpl::iterator_range< | ||
|  |                         mpl::string_iterator<Sequence, 0, 0> | ||
|  |                       , First | ||
|  |                     > | ||
|  |                   , mpl::iterator_range< | ||
|  |                         typename mpl::if_na<Last, typename mpl::next<First>::type>::type | ||
|  |                       , typename mpl::end<Sequence>::type | ||
|  |                     > | ||
|  |                 > | ||
|  |               , mpl::back_inserter<mpl::string<> > | ||
|  |             > | ||
|  |         {}; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Tag> | ||
|  |     struct clear_impl; | ||
|  | 
 | ||
|  |     template<> | ||
|  |     struct clear_impl<mpl::string_tag> | ||
|  |     { | ||
|  |         template<typename> | ||
|  |         struct apply | ||
|  |         { | ||
|  |             typedef mpl::string<> type; | ||
|  |         }; | ||
|  |     }; | ||
|  | 
 | ||
|  |     #define M0(z, n, data)                                                                            \
 | ||
|  |     template<BOOST_PP_ENUM_PARAMS_Z(z, BOOST_MPL_STRING_MAX_PARAMS, int C), int J>                    \ | ||
|  |     struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, 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_Z(z, 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_Z(z, BOOST_MPL_STRING_MAX_PARAMS, int C)>                           \ | ||
|  |     struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, 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_Z(z, 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;                       \ | ||
|  |     }; | ||
|  | 
 | ||
|  |     BOOST_PP_REPEAT(BOOST_MPL_STRING_MAX_PARAMS, M0, ~) | ||
|  |     #undef M0
 | ||
|  | 
 | ||
|  |     template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C)> | ||
|  |     struct string | ||
|  |     { | ||
|  |         /// INTERNAL ONLY
 | ||
|  |         enum | ||
|  |         { | ||
|  |             front_  = C0 | ||
|  |           , back_   = BOOST_PP_CAT(C, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS)) | ||
|  |         }; | ||
|  | 
 | ||
|  |         typedef char        value_type; | ||
|  |         typedef string      type; | ||
|  |         typedef string_tag  tag; | ||
|  |     }; | ||
|  | 
 | ||
|  |     namespace aux_ | ||
|  |     { | ||
|  |         template<typename It, typename End> | ||
|  |         struct next_unless | ||
|  |           : mpl::next<It> | ||
|  |         {}; | ||
|  | 
 | ||
|  |         template<typename End> | ||
|  |         struct next_unless<End, End> | ||
|  |         { | ||
|  |             typedef End type; | ||
|  |         }; | ||
|  | 
 | ||
|  |         template<typename It, typename End> | ||
|  |         struct deref_unless | ||
|  |           : mpl::deref<It> | ||
|  |         {}; | ||
|  | 
 | ||
|  |         template<typename End> | ||
|  |         struct deref_unless<End, End> | ||
|  |         { | ||
|  |             typedef mpl::char_<'\0'> type; | ||
|  |         }; | ||
|  |     } | ||
|  | 
 | ||
|  |     template<typename Sequence> | ||
|  |     struct c_str | ||
|  |     { | ||
|  |         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
 | ||
|  | 
 | ||
|  |         typedef c_str type; | ||
|  |         static typename Sequence::value_type const value[BOOST_MPL_LIMIT_STRING_SIZE+1]; | ||
|  |     }; | ||
|  | 
 | ||
|  |     template<typename Sequence> | ||
|  |     typename Sequence::value_type const c_str<Sequence>::value[BOOST_MPL_LIMIT_STRING_SIZE+1] = | ||
|  |     { | ||
|  |         #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' | ||
|  |     }; | ||
|  | 
 | ||
|  | }} // namespace boost
 | ||
|  | 
 | ||
|  | #endif // BOOST_MPL_STRING_HPP_INCLUDED
 |