mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-19 14:11:58 +00:00
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(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
|