Edit: /usr/include/boost/mpl/string.hpp (24547B)
#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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include // for bidirectional_iterator_tag
#include
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)((c0xffffff)+(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
struct string;
template
struct string_iterator;
template
struct sequence_tag;
template
struct size_impl;
template<>
struct size_impl
{
template
struct apply;
#define M0(z, n, data) \
+ BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C,n))
#define M1(z, n, data) \
template \
struct apply > \
: 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::apply >
: mpl::size_t<0>
{};
template
struct begin_impl;
template<>
struct begin_impl
{
template
struct apply
{
typedef mpl::string_iterator type;
};
};
template
struct end_impl;
template<>
struct end_impl
{
template
struct apply;
#define M0(z,n,data) \
template \
struct apply > \
{ \
typedef mpl::string_iterator, n, 0> type; \
};
BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)
#undef M0
};
template<>
struct end_impl::apply >
{
typedef mpl::string_iterator, 0, 0> type;
};
template
struct push_back_impl;
template<>
struct push_back_impl
{
template
struct apply
{
BOOST_MPL_ASSERT_MSG(
(BOOST_MPL_LIMIT_STRING_SIZE != mpl::size::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 >
>::type
, Value
>::type
type;
};
template
struct apply, Value, false>
{
typedef mpl::string<(char)Value::value> type;
};
#define M0(z,n,data) \
template \
struct apply, 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
struct apply, 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
struct has_push_back_impl;
template<>
struct has_push_back_impl
{
template
struct apply
: mpl::true_
{};
};
template
struct pop_back_impl;
template<>
struct pop_back_impl
{
template
struct apply;
#define M0(z,n,data) \
template \
struct apply > \
{ \
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
struct has_pop_back_impl;
template<>
struct has_pop_back_impl
{
template
struct apply
: mpl::true_
{};
};
template
struct push_front_impl;
template<>
struct push_front_impl
{
template
struct apply
{
BOOST_MPL_ASSERT_MSG(
(BOOST_MPL_LIMIT_STRING_SIZE != mpl::size::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 >
>::type
, Value
>::type
type;
};
#if !BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
template
struct apply, Value, false>
{
typedef mpl::string<(char)Value::value> type;
};
#endif
#define M0(z,n,data) \
template \
struct apply, 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
struct apply, 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<(char)Value::value>
, type0
>::type
type;
#else
typedef type0 type;
#endif
};
};
template
struct has_push_front_impl;
template<>
struct has_push_front_impl
{
template
struct apply
: mpl::true_
{};
};
template
struct pop_front_impl;
template<>
struct pop_front_impl
{
template
struct apply;
#define M0(z,n,data) \
template \
struct apply, true> \
{ \
BOOST_MPL_ASSERT_MSG((C0 != 0), POP_FRONT_FAILED_MPL_STRING_IS_EMPTY, (mpl::string<>)); \
typedef \
mpl::string \
type; \
};
BOOST_PP_REPEAT_FROM_TO(1, BOOST_MPL_STRING_MAX_PARAMS, M0, ~)
#undef M0
template
struct apply, false>
{
typedef
mpl::string<
BOOST_MPL_MULTICHAR_POP_FRONT(C0)
, BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)
>
type;
};
};
template
struct has_pop_front_impl;
template<>
struct has_pop_front_impl
{
template
struct apply
: mpl::true_
{};
};
template
struct insert_range_impl;
template<>
struct insert_range_impl
{
template
struct apply
: mpl::copy<
mpl::joint_view<
mpl::iterator_range<
mpl::string_iterator
, Pos
>
, mpl::joint_view<
Range
, mpl::iterator_range<
Pos
, typename mpl::end::type
>
>
>
, mpl::back_inserter >
>
{};
};
template
struct insert_impl;
template<>
struct insert_impl
{
template
struct apply
: mpl::insert_range >
{};
};
template
struct erase_impl;
template<>
struct erase_impl
{
template
struct apply
: mpl::copy<
mpl::joint_view<
mpl::iterator_range<
mpl::string_iterator
, First
>
, mpl::iterator_range<
typename mpl::if_na::type>::type
, typename mpl::end::type
>
>
, mpl::back_inserter >
>
{};
};
template
struct clear_impl;
template<>
struct clear_impl
{
template
struct apply
{
typedef mpl::string<> type;
};
};
#define M0(z, n, data) \
template \
struct string_iterator, n, J> \
{ \
enum { eomc_ = (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == J + 1) }; \
typedef mpl::string string; \
typedef std::bidirectional_iterator_tag category; \
typedef \
mpl::string_iterator \
next; \
typedef \
mpl::string_iterator \
prior; \
typedef mpl::char_ type; \
}; \
template \
struct string_iterator, n, 0> \
{ \
enum { eomc_ = (BOOST_MPL_MULTICHAR_LENGTH(BOOST_PP_CAT(C, n)) == 1) }; \
typedef mpl::string string; \
typedef std::bidirectional_iterator_tag category; \
typedef \
mpl::string_iterator \
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_ type; \
};
BOOST_PP_REPEAT(BOOST_MPL_STRING_MAX_PARAMS, M0, ~)
#undef M0
template
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
struct next_unless
: mpl::next
{};
template
struct next_unless
{
typedef End type;
};
template
struct deref_unless
: mpl::deref
{};
template
struct deref_unless
{
typedef mpl::char_<'\0'> type;
};
}
template
struct c_str
{
typedef typename mpl::end::type iend;
typedef typename mpl::begin::type i0;
#define M0(z, n, data) \
typedef \
typename mpl::aux_::next_unless::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::value_type const c_str::value[BOOST_MPL_LIMIT_STRING_SIZE+1] =
{
#define M0(z, n, data) \
mpl::aux_::deref_unless::type::value,
BOOST_PP_REPEAT(BOOST_MPL_LIMIT_STRING_SIZE, M0, ~)
#undef M0
'\0'
};
}} // namespace boost
#endif // BOOST_MPL_STRING_HPP_INCLUDED