-\r
-#ifndef BOOST_MPL_STRING_HPP_INCLUDED\r
-#define BOOST_MPL_STRING_HPP_INCLUDED\r
-\r
-// Copyright Eric Niebler 2009\r
-//\r
-// Distributed under the Boost Software License, Version 1.0.\r
-// (See accompanying file LICENSE_1_0.txt or copy at\r
-// http://www.boost.org/LICENSE_1_0.txt)\r
-//\r
-// See http://www.boost.org/libs/mpl for documentation.\r
-\r
-// $Id: string.hpp 49239 2009-04-01 09:10:26Z eric_niebler $\r
-// $Date: 2009-04-01 02:10:26 -0700 (Wed, 1 Apr 2009) $\r
-// $Revision: 49239 $\r
-//\r
-// Thanks to:\r
-// Dmitry Goncharov for porting this to the Sun compiler\r
-\r
-#include <boost/config.hpp>\r
-#include <boost/detail/workaround.hpp>\r
-#include <boost/detail/endian.hpp>\r
-#include <boost/mpl/limits/string.hpp>\r
-#include <boost/mpl/if.hpp>\r
-#include <boost/mpl/char.hpp>\r
-#include <boost/mpl/copy.hpp>\r
-#include <boost/mpl/size.hpp>\r
-#include <boost/mpl/empty.hpp>\r
-#include <boost/mpl/assert.hpp>\r
-#include <boost/mpl/size_t.hpp>\r
-#include <boost/mpl/begin_end.hpp>\r
-#include <boost/mpl/joint_view.hpp>\r
-#include <boost/mpl/insert_range.hpp>\r
-#include <boost/mpl/back_inserter.hpp>\r
-#include <boost/mpl/front_inserter.hpp>\r
-#include <boost/mpl/iterator_range.hpp>\r
-#include <boost/preprocessor/arithmetic/dec.hpp>\r
-#include <boost/preprocessor/arithmetic/add.hpp>\r
-#include <boost/preprocessor/arithmetic/div.hpp>\r
-#include <boost/preprocessor/punctuation/comma_if.hpp>\r
-#include <boost/preprocessor/repetition/repeat.hpp>\r
-#include <boost/preprocessor/repetition/enum_params.hpp>\r
-#include <boost/preprocessor/repetition/repeat_from_to.hpp>\r
-#include <boost/preprocessor/repetition/enum_shifted_params.hpp>\r
-#include <boost/preprocessor/repetition/enum_trailing_params.hpp>\r
-#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>\r
-\r
-#include <iterator> // for bidirectional_iterator_tag\r
-#include <climits>\r
-\r
-namespace boost { namespace mpl\r
-{\r
- #define BOOST_MPL_STRING_MAX_PARAMS \\r
- BOOST_PP_DIV(BOOST_PP_ADD(BOOST_MPL_LIMIT_STRING_SIZE, 3), 4)\r
-\r
- // Low-level bit-twiddling is done by macros. Any implementation-defined behavior of\r
- // multi-character literals should be localized to these macros.\r
-\r
- #define BOOST_MPL_MULTICHAR_LENGTH(c) \\r
- (std::size_t)((c<CHAR_MIN) ? 4 : ((c>0xffffff)+(c>0xffff)+(c>0xff)+1))\r
-\r
- #if defined(BOOST_LITTLE_ENDIAN) && defined(__SUNPRO_CC)\r
-\r
- #define BOOST_MPL_MULTICHAR_AT(c,i) \\r
- (char)(0xff&((unsigned)(c)>>(8*(std::size_t)(i))))\r
-\r
- #define BOOST_MPL_MULTICHAR_PUSH_BACK(c,i) \\r
- ((((unsigned char)(i))<<(BOOST_MPL_MULTICHAR_LENGTH(c)*8))|(unsigned)(c))\r
-\r
- #define BOOST_MPL_MULTICHAR_PUSH_FRONT(c,i) \\r
- (((unsigned)(c)<<8)|(unsigned char)(i))\r
-\r
- #define BOOST_MPL_MULTICHAR_POP_BACK(c) \\r
- (((1<<((BOOST_MPL_MULTICHAR_LENGTH(c)-1)*8))-1)&(unsigned)(c))\r
-\r
- #define BOOST_MPL_MULTICHAR_POP_FRONT(c) \\r
- ((unsigned)(c)>>8)\r
-\r
- #else\r
-\r
- #define BOOST_MPL_MULTICHAR_AT(c,i) \\r
- (char)(0xff&((unsigned)(c)>>(8*(BOOST_MPL_MULTICHAR_LENGTH(c)-(std::size_t)(i)-1))))\r
-\r
- #define BOOST_MPL_MULTICHAR_PUSH_BACK(c,i) \\r
- (((unsigned)(c)<<8)|(unsigned char)(i))\r
-\r
- #define BOOST_MPL_MULTICHAR_PUSH_FRONT(c,i) \\r
- ((((unsigned char)(i))<<(BOOST_MPL_MULTICHAR_LENGTH(c)*8))|(unsigned)(c))\r
-\r
- #define BOOST_MPL_MULTICHAR_POP_BACK(c) \\r
- ((unsigned)(c)>>8)\r
-\r
- #define BOOST_MPL_MULTICHAR_POP_FRONT(c) \\r
- (((1<<((BOOST_MPL_MULTICHAR_LENGTH(c)-1)*8))-1)&(unsigned)(c))\r
-\r
- #endif\r
-\r
- struct string_tag;\r
- struct string_iterator_tag;\r
-\r
- template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_MPL_STRING_MAX_PARAMS, int C, 0)>\r
- struct string;\r
-\r
- template<typename Sequence, int I, int J>\r
- struct string_iterator;\r
-\r
- template<typename Sequence>\r
- struct sequence_tag;\r
-\r
- template<typename Tag>\r
- struct size_impl;\r
-\r
- template<>\r
- struct size_impl<mpl::string_tag>\r
- {\r
- template<typename Sequence>\r
- struct apply;\r
-\r
- #define M0(z, n, data) \\r
- + BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C,n))\r
-\r
- #define M1(z, n, data) \\r
- template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)> \\r
- struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> > \\r
- : mpl::size_t<(0 BOOST_PP_REPEAT_ ## z(n, M0, ~))> \\r
- {};\r
-\r
- BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M1, ~)\r
- #undef M0\r
- #undef M1\r
- };\r
-\r
- template<>\r
- struct size_impl<mpl::string_tag>::apply<mpl::string<> >\r
- : mpl::size_t<0>\r
- {};\r
-\r
- template<typename Tag>\r
- struct begin_impl;\r
-\r
- template<>\r
- struct begin_impl<mpl::string_tag>\r
- {\r
- template<typename Sequence>\r
- struct apply\r
- {\r
- typedef mpl::string_iterator<Sequence, 0, 0> type;\r
- };\r
- };\r
-\r
- template<typename Tag>\r
- struct end_impl;\r
-\r
- template<>\r
- struct end_impl<mpl::string_tag>\r
- {\r
- template<typename Sequence>\r
- struct apply;\r
-\r
- #define M0(z,n,data) \\r
- template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)> \\r
- struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> > \\r
- { \\r
- typedef mpl::string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, n, 0> type; \\r
- };\r
-\r
- BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)\r
- #undef M0\r
- };\r
-\r
- template<>\r
- struct end_impl<mpl::string_tag>::apply<mpl::string<> >\r
- {\r
- typedef mpl::string_iterator<mpl::string<>, 0, 0> type;\r
- };\r
-\r
- template<typename Tag>\r
- struct push_back_impl;\r
-\r
- template<>\r
- struct push_back_impl<mpl::string_tag>\r
- {\r
- template<typename Sequence, typename Value, bool B = (4==BOOST_MPL_MULTICHAR_LENGTH(Sequence::back_))>\r
- struct apply\r
- {\r
- BOOST_MPL_ASSERT_MSG(\r
- (BOOST_MPL_LIMIT_STRING_SIZE != mpl::size<Sequence>::type::value)\r
- , PUSH_BACK_FAILED_MPL_STRING_IS_FULL\r
- , (Sequence)\r
- );\r
- // If the above assertion didn't fire, then the string is sparse.\r
- // Repack the string and retry the push_back\r
- typedef\r
- typename mpl::push_back<\r
- typename mpl::copy<\r
- Sequence\r
- , mpl::back_inserter<mpl::string<> >\r
- >::type\r
- , Value\r
- >::type\r
- type;\r
- };\r
-\r
- template<typename Value>\r
- struct apply<mpl::string<>, Value, false>\r
- {\r
- typedef mpl::string<(char)Value::value> type;\r
- };\r
-\r
- #define M0(z,n,data) \\r
- template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C), typename Value> \\r
- struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, false> \\r
- { \\r
- typedef \\r
- mpl::string< \\r
- BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), C) \\r
- BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \\r
- ((unsigned)BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff) \\r
- ?BOOST_PP_CAT(C,BOOST_PP_DEC(n)) \\r
- :BOOST_MPL_MULTICHAR_PUSH_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(n)), Value::value) \\r
- , ((unsigned)BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff) \\r
- ?(char)Value::value \\r
- :0 \\r
- > \\r
- type; \\r
- };\r
-\r
- BOOST_PP_REPEAT_FROM_TO(1, BOOST_MPL_STRING_MAX_PARAMS, M0, ~)\r
- #undef M0\r
-\r
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C), typename Value>\r
- struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>\r
- {\r
- typedef\r
- mpl::string<\r
- BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS), C)\r
- , BOOST_MPL_MULTICHAR_PUSH_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS)), Value::value)\r
- >\r
- type;\r
- };\r
- };\r
-\r
- template<typename Tag>\r
- struct pop_back_impl;\r
-\r
- template<>\r
- struct pop_back_impl<mpl::string_tag>\r
- {\r
- template<typename Sequence>\r
- struct apply;\r
-\r
- #define M0(z,n,data) \\r
- template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)> \\r
- struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)> > \\r
- { \\r
- BOOST_MPL_ASSERT_MSG((C0 != 0), POP_BACK_FAILED_MPL_STRING_IS_EMPTY, (mpl::string<>)); \\r
- typedef \\r
- mpl::string< \\r
- BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), C) \\r
- BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \\r
- BOOST_MPL_MULTICHAR_POP_BACK(BOOST_PP_CAT(C,BOOST_PP_DEC(n))) \\r
- > \\r
- type; \\r
- };\r
-\r
- BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)\r
- #undef M0\r
- };\r
-\r
- template<typename Tag>\r
- struct push_front_impl;\r
-\r
- template<>\r
- struct push_front_impl<mpl::string_tag>\r
- {\r
- template<typename Sequence, typename Value, bool B = (4==BOOST_MPL_MULTICHAR_LENGTH(Sequence::front_))>\r
- struct apply\r
- {\r
- BOOST_MPL_ASSERT_MSG(\r
- (BOOST_MPL_LIMIT_STRING_SIZE != mpl::size<Sequence>::type::value)\r
- , PUSH_FRONT_FAILED_MPL_STRING_IS_FULL\r
- , (Sequence)\r
- );\r
- // If the above assertion didn't fire, then the string is sparse.\r
- // Repack the string and retry the push_front.\r
- typedef\r
- typename mpl::push_front<\r
- typename mpl::reverse_copy<\r
- Sequence\r
- , mpl::front_inserter<string<> >\r
- >::type\r
- , Value\r
- >::type\r
- type;\r
- };\r
-\r
- #if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))\r
- template<typename Value>\r
- struct apply<mpl::string<>, Value, false>\r
- {\r
- typedef mpl::string<(char)Value::value> type;\r
- };\r
- #endif\r
-\r
- #define M0(z,n,data) \\r
- template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C), typename Value> \\r
- struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, true> \\r
- { \\r
- typedef \\r
- mpl::string< \\r
- (char)Value::value \\r
- BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, C) \\r
- > \\r
- type; \\r
- };\r
-\r
- BOOST_PP_REPEAT_FROM_TO(1, BOOST_MPL_STRING_MAX_PARAMS, M0, ~)\r
- #undef M0\r
-\r
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C), typename Value>\r
- struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>\r
- {\r
- typedef\r
- mpl::string<\r
- BOOST_MPL_MULTICHAR_PUSH_FRONT(C0, Value::value)\r
- , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)\r
- >\r
- type0;\r
-\r
- #if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))\r
- typedef\r
- typename mpl::if_<\r
- mpl::empty<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> >\r
- , mpl::string<(char)Value::value>\r
- , type0\r
- >::type\r
- type;\r
- #else\r
- typedef type0 type;\r
- #endif\r
- };\r
- };\r
-\r
- template<typename Tag>\r
- struct pop_front_impl;\r
-\r
- template<>\r
- struct pop_front_impl<mpl::string_tag>\r
- {\r
- template<typename Sequence, bool B = (1==BOOST_MPL_MULTICHAR_LENGTH(Sequence::front_))>\r
- struct apply;\r
-\r
- #define M0(z,n,data) \\r
- template<BOOST_PP_ENUM_PARAMS_Z(z, n, int C)> \\r
- struct apply<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, true> \\r
- { \\r
- BOOST_MPL_ASSERT_MSG((C0 != 0), POP_FRONT_FAILED_MPL_STRING_IS_EMPTY, (mpl::string<>)); \\r
- typedef \\r
- mpl::string<BOOST_PP_ENUM_SHIFTED_PARAMS_Z(z, n, C)> \\r
- type; \\r
- };\r
-\r
- BOOST_PP_REPEAT_FROM_TO(1, BOOST_MPL_STRING_MAX_PARAMS, M0, ~)\r
- #undef M0\r
-\r
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C)>\r
- struct apply<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, false>\r
- {\r
- typedef\r
- mpl::string<\r
- BOOST_MPL_MULTICHAR_POP_FRONT(C0)\r
- , BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)\r
- >\r
- type;\r
- };\r
- };\r
-\r
- template<typename Tag>\r
- struct insert_range_impl;\r
-\r
- template<>\r
- struct insert_range_impl<mpl::string_tag>\r
- {\r
- template<typename Sequence, typename Pos, typename Range>\r
- struct apply\r
- : mpl::copy<\r
- mpl::joint_view<\r
- mpl::iterator_range<\r
- mpl::string_iterator<Sequence, 0, 0>\r
- , Pos\r
- >\r
- , mpl::joint_view<\r
- Range\r
- , mpl::iterator_range<\r
- Pos\r
- , typename mpl::end<Sequence>::type\r
- >\r
- >\r
- >\r
- , mpl::back_inserter<mpl::string<> >\r
- >\r
- {};\r
- };\r
-\r
- template<typename Tag>\r
- struct insert_impl;\r
-\r
- template<>\r
- struct insert_impl<mpl::string_tag>\r
- {\r
- template<typename Sequence, typename Pos, typename Value>\r
- struct apply\r
- : mpl::insert_range<Sequence, Pos, mpl::string<(char)Value::value> >\r
- {};\r
- };\r
-\r
- template<typename Tag>\r
- struct erase_impl;\r
-\r
- template<>\r
- struct erase_impl<mpl::string_tag>\r
- {\r
- template<typename Sequence, typename First, typename Last>\r
- struct apply\r
- : mpl::copy<\r
- mpl::joint_view<\r
- mpl::iterator_range<\r
- mpl::string_iterator<Sequence, 0, 0>\r
- , First\r
- >\r
- , mpl::iterator_range<\r
- typename mpl::if_na<Last, typename mpl::next<First>::type>::type\r
- , typename mpl::end<Sequence>::type\r
- >\r
- >\r
- , mpl::back_inserter<mpl::string<> >\r
- >\r
- {};\r
- };\r
-\r
- template<typename Tag>\r
- struct clear_impl;\r
-\r
- template<>\r
- struct clear_impl<mpl::string_tag>\r
- {\r
- template<typename>\r
- struct apply\r
- {\r
- typedef mpl::string<> type;\r
- };\r
- };\r
-\r
- #define M0(z, n, data) \\r
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C), int J> \\r
- struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, n, J> \\r
- { \\r
- enum { eomc_ = (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == J + 1) }; \\r
- typedef mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> string; \\r
- typedef std::bidirectional_iterator_tag category; \\r
- typedef \\r
- mpl::string_iterator<string, n + eomc_, eomc_ ? 0 : J + 1> \\r
- next; \\r
- typedef \\r
- mpl::string_iterator<string, n, J - 1> \\r
- prior; \\r
- typedef mpl::char_<BOOST_MPL_MULTICHAR_AT(BOOST_PP_CAT(C, n), J)> type; \\r
- }; \\r
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C)> \\r
- struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, n, 0> \\r
- { \\r
- enum { eomc_ = (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == 1) }; \\r
- typedef mpl::string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> string; \\r
- typedef std::bidirectional_iterator_tag category; \\r
- typedef \\r
- mpl::string_iterator<string, n + eomc_, !eomc_> \\r
- next; \\r
- typedef \\r
- mpl::string_iterator< \\r
- string \\r
- , n - 1 \\r
- , BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, BOOST_PP_DEC(n))) - 1 \\r
- > \\r
- prior; \\r
- typedef mpl::char_<BOOST_MPL_MULTICHAR_AT(BOOST_PP_CAT(C, n), 0)> type; \\r
- };\r
-\r
- BOOST_PP_REPEAT(BOOST_MPL_STRING_MAX_PARAMS, M0, ~)\r
- #undef M0\r
-\r
- template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, int C)>\r
- struct string\r
- {\r
- /// INTERNAL ONLY\r
- enum\r
- {\r
- front_ = C0\r
- , back_ = BOOST_PP_CAT(C, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS))\r
- };\r
-\r
- typedef char value_type;\r
- typedef string type;\r
- typedef string_tag tag;\r
- };\r
-\r
- namespace aux_\r
- {\r
- template<typename It, typename End>\r
- struct next_unless\r
- : mpl::next<It>\r
- {};\r
-\r
- template<typename End>\r
- struct next_unless<End, End>\r
- {\r
- typedef End type;\r
- };\r
-\r
- template<typename It, typename End>\r
- struct deref_unless\r
- : mpl::deref<It>\r
- {};\r
-\r
- template<typename End>\r
- struct deref_unless<End, End>\r
- {\r
- typedef mpl::char_<'\0'> type;\r
- };\r
- }\r
-\r
- template<typename Sequence>\r
- struct c_str\r
- {\r
- typedef typename mpl::end<Sequence>::type iend;\r
- typedef typename mpl::begin<Sequence>::type i0;\r
- #define M0(z, n, data) \\r
- typedef \\r
- typename mpl::aux_::next_unless<BOOST_PP_CAT(i, n), iend>::type \\r
- BOOST_PP_CAT(i, BOOST_PP_INC(n));\r
- BOOST_PP_REPEAT(BOOST_MPL_LIMIT_STRING_SIZE, M0, ~)\r
- #undef M0\r
-\r
- typedef c_str type;\r
- static typename Sequence::value_type const value[BOOST_MPL_LIMIT_STRING_SIZE+1];\r
- };\r
-\r
- template<typename Sequence>\r
- typename Sequence::value_type const c_str<Sequence>::value[BOOST_MPL_LIMIT_STRING_SIZE+1] =\r
- {\r
- #define M0(z, n, data) \\r
- mpl::aux_::deref_unless<BOOST_PP_CAT(i, n), iend>::type::value,\r
- BOOST_PP_REPEAT(BOOST_MPL_LIMIT_STRING_SIZE, M0, ~)\r
- #undef M0\r
- '\0'\r
- };\r
-\r
-}} // namespace boost\r
-\r
-#endif // BOOST_MPL_STRING_HPP_INCLUDED\r
+
+#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/detail/endian.hpp>
+#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 defined(BOOST_LITTLE_ENDIAN) && 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 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 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 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 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