forked from boostorg/mpl
* It normally should not be necessary to use the _Z form of the BOOST_PP_ENUM macro, although it is perfectly legal and helpful to do so, but in this case it is necessary as a workaround for a bug in the new VC++ standard conforming preprocessor. The bug manifests itself when testing the TTI library, which internally uses the Boost MPL code. The bug in the new VC++ standard conforming compiler is fixed in the VS2019 preview product, so that fix is sure to find its way to the official VS2019 product sometime soon. In the meantime this "fix" shortens the macro expansion somewhat and, while it should not be necessary, is still helpful. * Fix for appveyor.yml file * Added VS2019 tests, also with new preprocessor. Further MPL Fixes for new preprocessor bug, which are also useful and will speed up preprocessing. * Can't seem to test msvc-10.0 or msvc-11.0 any more with Appveyor * Update description
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_Z(z, BOOST_MPL_STRING_MAX_PARAMS, int C), int J> \
|
|
struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, 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_Z(z, 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_Z(z, BOOST_MPL_STRING_MAX_PARAMS, int C)> \
|
|
struct string_iterator<mpl::string<BOOST_PP_ENUM_PARAMS_Z(z, 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_Z(z, 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
|