| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607 | 
#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(BOOST_MPL_STRING_MAX_PARAMS, int C), int 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, int 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;                       \    };    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
 |