123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- #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
|