add mpl::char_ and mpl::string, fixes #2905

[SVN r52208]
This commit is contained in:
Eric Niebler
2009-04-06 06:00:57 +00:00
parent 98008e8e21
commit a96b0e9924
9 changed files with 874 additions and 0 deletions

View File

@@ -71,6 +71,7 @@ Models
* |bool_|
* |int_|
* |long_|
* |char_|
* |integral_c|

View File

@@ -0,0 +1,89 @@
.. Data Types/Numeric//char_ |60
.. 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)
char\_
======
Synopsis
--------
.. parsed-literal::
template<
char N
>
struct char\_
{
// |unspecified|
// ...
};
Description
-----------
An |Integral Constant| wrapper for ``char``.
Header
------
.. parsed-literal::
#include <boost/mpl/char.hpp>
Model of
--------
|Integral Constant|
Parameters
----------
+---------------+-------------------------------+---------------------------+
| Parameter | Requirement | Description |
+===============+===============================+===========================+
| ``N`` | A character constant | A value to wrap. |
+---------------+-------------------------------+---------------------------+
Expression semantics
--------------------
|Semantics disclaimer...| |Integral Constant|.
For arbitrary character constant ``c``:
+-------------------+-----------------------------------------------------------+
| Expression | Semantics |
+===================+===========================================================+
| ``char_<c>`` | An |Integral Constant| ``x`` such that ``x::value == c`` |
| | and ``x::value_type`` is identical to ``char``. |
+-------------------+-----------------------------------------------------------+
Example
-------
.. parsed-literal::
typedef char_<'c'> c;
BOOST_MPL_ASSERT(( is_same< c::value_type, char > ));
BOOST_MPL_ASSERT(( is_same< c::type, c > ));
BOOST_MPL_ASSERT(( is_same< next< c >::type, char_<'d'> > ));
BOOST_MPL_ASSERT(( is_same< prior< c >::type, char_<'b'> > ));
BOOST_MPL_ASSERT_RELATION( (c::value), ==, 'c' );
assert( c() == 'c' );
See also
--------
|Data Types|, |Integral Constant|, |int_|, |size_t|, |integral_c|

View File

@@ -0,0 +1,140 @@
.. Sequences/Classes//string |100
.. 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)
string
======
Description
-----------
``string`` is a |variadic|, `random access`__, `extensible`__ |Integral Sequence Wrapper| of
characters that supports constant-time insertion and removal of elements at both ends, and
linear-time insertion and removal of elements in the middle. The parameters to ``string``
are multi-character literals, giving a somewhat readable syntax for compile-time strings.
``string`` also has a class static null-terminated character array called ``c_str`` that
facilitates interoperability with runtime string processing routines.
__ `Random Access Sequence`_
__ `Extensible Sequence`_
Header
------
+-------------------+-------------------------------------------------------+
| Sequence form | Header |
+===================+=======================================================+
| Variadic | ``#include <boost/mpl/string.hpp>`` |
+-------------------+-------------------------------------------------------+
Model of
--------
* |Integral Sequence Wrapper|
* |Variadic Sequence|
* |Random Access Sequence|
* |Extensible Sequence|
* |Back Extensible Sequence|
* |Front Extensible Sequence|
Expression semantics
--------------------
In the following table, ``s`` is an instance of ``string``, ``pos`` and ``last`` are iterators
into ``s``, ``r`` is a |Forward Sequence| of characters, ``n`` and ``x`` are |Integral Constant|\ s,
and |c1...cn| are arbitrary (multi-)characters.
+---------------------------------------+-----------------------------------------------------------+
| Expression | Semantics |
+=======================================+===========================================================+
| .. parsed-literal:: | ``string`` of characters |c1...cn|; see |
| | |Variadic Sequence|. |
| string<|c1...cn|> | |
+---------------------------------------+-----------------------------------------------------------+
| .. parsed-literal:: | Identical to ``string<``\ |c1...cn|\ ``>``; |
| | see |Variadic Sequence|. |
| string<|c1...cn|>::type | |
+---------------------------------------+-----------------------------------------------------------+
| ``begin<s>::type`` | An iterator pointing to the beginning of ``s``; |
| | see |Random Access Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``end<s>::type`` | An iterator pointing to the end of ``s``; |
| | see |Random Access Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``size<s>::type`` | The size of ``s``; see |Random Access Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``empty<s>::type`` | |true if and only if| the sequence is empty; |
| | see |Random Access Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``front<s>::type`` | The first element in ``s``; see |
| | |Random Access Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``back<s>::type`` | The last element in ``s``; see |
| | |Random Access Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``at<s,n>::type`` | The ``n``\ th element from the beginning of ``s``; see |
| | |Random Access Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``insert<s,pos,x>::type`` | A new ``string`` of following elements: |
| | [``begin<s>::type``, ``pos``), ``x``, |
| | [``pos``, ``end<s>::type``); see |Extensible Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``insert_range<s,pos,r>::type`` | A new ``string`` of following elements: |
| | [``begin<s>::type``, ``pos``), |
| | [``begin<r>::type``, ``end<r>::type``) |
| | [``pos``, ``end<s>::type``); see |Extensible Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``erase<s,pos>::type`` | A new ``string`` of following elements: |
| | [``begin<s>::type``, ``pos``), |
| | [``next<pos>::type``, ``end<s>::type``); see |
| | |Extensible Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``erase<s,pos,last>::type`` | A new ``string`` of following elements: |
| | [``begin<s>::type``, ``pos``), |
| | [``last``, ``end<s>::type``); see |Extensible Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``clear<s>::type`` | An empty ``string``; see |Extensible Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``push_back<s,x>::type`` | A new ``string`` of following elements: |
| | |begin/end<s>|, ``x``; |
| | see |Back Extensible Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``pop_back<s>::type`` | A new ``string`` of following elements: |
| | [``begin<s>::type``, ``prior< end<s>::type >::type``); |
| | see |Back Extensible Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``push_front<s,x>::type`` | A new ``string`` of following elements: |
| | |begin/end<s>|, ``x``; see |Front Extensible Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``pop_front<s>::type`` | A new ``string`` of following elements: |
| | [``next< begin<s>::type >::type``, ``end<s>::type``); |
| | see |Front Extensible Sequence|. |
+---------------------------------------+-----------------------------------------------------------+
| ``s::c_str`` | A null-terminated byte string such that |
| | ``s::c_str[``\ *n*\ ``]`` is |
| | ``at<s,``\ *n*\ ``>::type::value`` for each *n* in |
| | [``0``, ``size<s>::type::value``), and |
| | ``s::c_str[size<s>::type::value]`` is ``'\0'``. |
+---------------------------------------+-----------------------------------------------------------+
Example
-------
.. parsed-literal::
typedef string<'hell','o wo','rld'> hello;
typedef push_back<hello, char_<'!'> >::type hello2;
BOOST_ASSERT(0 == std::strcmp(hello2::c_str, "hello world!"));
See also
--------
|Sequences|, |Variadic Sequence|, |Random Access Sequence|, |Extensible Sequence|, |Integral Sequence Wrapper|, |char_|

View File

@@ -0,0 +1,22 @@
#ifndef BOOST_MPL_CHAR_HPP_INCLUDED
#define BOOST_MPL_CHAR_HPP_INCLUDED
// Copyright Eric Niebler 2008
//
// 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.
// $Source$
// $Date: 2008-06-14 08:41:37 -0700 (Sat, 16 Jun 2008) $
// $Revision: 24874 $
#include <boost/mpl/char_fwd.hpp>
#define AUX_WRAPPER_VALUE_TYPE char
#include <boost/mpl/aux_/integral_wrapper.hpp>
#endif // BOOST_MPL_CHAR_HPP_INCLUDED

View File

@@ -0,0 +1,27 @@
#ifndef BOOST_MPL_CHAR_FWD_HPP_INCLUDED
#define BOOST_MPL_CHAR_FWD_HPP_INCLUDED
// Copyright Eric Niebler 2008
//
// 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.
// $Source$
// $Date: 2008-06-14 08:41:37 -0700 (Sat, 16 Jun 2008) $
// $Revision: 24874 $
#include <boost/mpl/aux_/adl_barrier.hpp>
#include <boost/mpl/aux_/nttp_decl.hpp>
BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_OPEN
template< BOOST_MPL_AUX_NTTP_DECL(char, N) > struct char_;
BOOST_MPL_AUX_ADL_BARRIER_NAMESPACE_CLOSE
BOOST_MPL_AUX_ADL_BARRIER_DECL(char_)
#endif // BOOST_MPL_CHAR_FWD_HPP_INCLUDED

View File

@@ -0,0 +1,396 @@
#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 $
#include <boost/mpl/char.hpp>
#include <boost/mpl/long.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/back_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/repetition/enum.hpp>
#include <boost/preprocessor/punctuation/comma_if.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>
namespace boost { namespace mpl
{
#ifndef BOOST_MPL_STRING_MAX_LENGTH
# define BOOST_MPL_STRING_MAX_LENGTH 32
#endif
#define BOOST_MPL_STRING_MAX_PARAMS BOOST_PP_DIV(BOOST_PP_ADD(BOOST_MPL_STRING_MAX_LENGTH, 3), 4)
#define BOOST_MPL_MULTICHAR_LENGTH(c) (std::size_t)((c>0xffffff)+(c>0xffff)+(c>0xff)+1)
#define BOOST_MPL_MULTICHAR_AT(c,i) (char)(0xff&(c>>(8*(BOOST_MPL_MULTICHAR_LENGTH(c)-(std::size_t)(i)-1))))
struct string_tag;
struct string_iterator_tag;
template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C, 0)>
struct string;
template<typename Sequence, long N>
struct string_iterator;
template<typename Sequence>
struct sequence_tag;
template<typename Tag>
struct size_impl;
template<>
struct size_impl<string_tag>
{
template<typename Sequence>
struct apply
: mpl::size_t<Sequence::size>
{};
};
template<typename Tag>
struct at_impl;
template<>
struct at_impl<string_tag>
{
template<typename Sequence, typename N>
struct apply
: Sequence::template at<N::value>
{};
};
template<typename Tag>
struct begin_impl;
template<>
struct begin_impl<string_tag>
{
template<typename Sequence>
struct apply
{
typedef string_iterator<Sequence, 0> type;
};
};
template<typename Tag>
struct end_impl;
template<>
struct end_impl<string_tag>
{
template<typename Sequence>
struct apply
{
typedef string_iterator<Sequence, Sequence::size> type;
};
};
template<typename Tag>
struct push_back_impl;
template<>
struct push_back_impl<string_tag>
{
template<typename Sequence, typename Value, bool B = (4==BOOST_MPL_MULTICHAR_LENGTH(Sequence::back_))>
struct apply
{
BOOST_MPL_ASSERT_MSG(false, PUSH_BACK_FAILED_MPL_STRING_IS_FULL, (Sequence));
typedef void type;
};
template<typename Value>
struct apply<string<>, Value, false>
{
typedef string<(char)Value::value> type;
};
#define M0(z,n,data) \
template<BOOST_PP_ENUM_PARAMS_Z(z, n, unsigned int C), typename Value> \
struct apply<string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, false> \
{ \
typedef string< \
BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), C) \
BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \
(BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff) \
?BOOST_PP_CAT(C,BOOST_PP_DEC(n)) \
:(BOOST_PP_CAT(C,BOOST_PP_DEC(n))<<8)|(unsigned char)Value::value \
, (BOOST_PP_CAT(C,BOOST_PP_DEC(n))>0xffffff) \
?(char)Value::value \
:0 \
> type; \
};
BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)
#undef M0
template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C), typename Value>
struct apply<string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>
{
typedef string<
BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS), C)
, (BOOST_PP_CAT(C,BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS))<<8)|(unsigned char)Value::value
> type;
};
};
template<typename Tag>
struct push_front_impl;
template<>
struct push_front_impl<string_tag>
{
template<typename Sequence, typename Value, bool B = (4==BOOST_MPL_MULTICHAR_LENGTH(Sequence::front_))>
struct apply
{
BOOST_MPL_ASSERT_MSG(false, PUSH_FRONT_FAILED_MPL_STRING_IS_FULL, (Sequence));
typedef void type;
};
template<typename Value>
struct apply<string<>, Value, false>
{
typedef string<(char)Value::value> type;
};
#define M0(z,n,data) \
template<BOOST_PP_ENUM_PARAMS_Z(z, n, unsigned int C), typename Value> \
struct apply<string<BOOST_PP_ENUM_PARAMS_Z(z, n, C)>, Value, true> \
{ \
typedef string< \
(char)Value::value \
BOOST_PP_ENUM_TRAILING_PARAMS_Z(z, n, C) \
> type; \
};
BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS), M0, ~)
#undef M0
template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C), typename Value>
struct apply<string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>, Value, false>
{
typedef string<
((((unsigned char)Value::value)<<(BOOST_MPL_MULTICHAR_LENGTH(C0)*8))|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<string_tag>
{
template<typename Sequence, typename Pos, typename Range>
struct apply
: copy<
joint_view<
iterator_range<
string_iterator<Sequence, 0>
, Pos
>
, joint_view<
Range
, iterator_range<
Pos
, string_iterator<Sequence, Sequence::size>
>
>
>
, back_inserter<string<> >
>
{};
};
template<typename Tag>
struct insert_impl;
template<>
struct insert_impl<string_tag>
{
template<typename Sequence, typename Pos, typename Value>
struct apply
: insert_range<Sequence, Pos, string<(char)Value::value> >
{};
};
template<typename Tag>
struct erase_impl;
template<>
struct erase_impl<string_tag>
{
template<typename Sequence, typename First, typename Last>
struct apply
: copy<
joint_view<
iterator_range<
string_iterator<Sequence, 0>
, First
>
, iterator_range<
typename if_na<Last, typename next<First>::type>::type
, string_iterator<Sequence, Sequence::size>
>
>
, back_inserter<string<> >
>
{};
};
template<typename Tag>
struct clear_impl;
template<>
struct clear_impl<string_tag>
{
template<typename>
struct apply
{
typedef string<> type;
};
};
template<typename Tag>
struct advance_impl;
template<>
struct advance_impl<string_iterator_tag>
{
template<typename Iterator, typename N>
struct apply
{
typedef string_iterator<
typename Iterator::string_type
, Iterator::index + N::value
> type;
};
};
template<typename Tag>
struct distance_impl;
template<>
struct distance_impl<string_iterator_tag>
{
template<typename First, typename Last>
struct apply
{
typedef mpl::long_<Last::index - First::index> type;
};
};
template<typename Sequence, long N>
struct string_iterator
: Sequence::template at<N>
{
typedef string_iterator_tag tag;
typedef std::random_access_iterator_tag category;
typedef Sequence string_type;
static long const index = N;
typedef string_iterator<Sequence, N+1> next;
typedef string_iterator<Sequence, N-1> prior;
};
template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C)>
struct string
{
/// INTERNAL ONLY
static unsigned int const front_ = C0;
/// INTERNAL ONLY
static unsigned int const back_ = BOOST_PP_CAT(C, BOOST_PP_DEC(BOOST_MPL_STRING_MAX_PARAMS));
/// INTERNAL ONLY
typedef string<BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)> rest_;
typedef string type;
typedef string_tag tag;
static std::size_t const size = BOOST_MPL_MULTICHAR_LENGTH(C0) + rest_::size;
template<long Pos, bool B = (Pos < BOOST_MPL_MULTICHAR_LENGTH(C0))>
struct at
: boost::mpl::char_<BOOST_MPL_MULTICHAR_AT(C0,Pos)>
{};
template<long Pos>
struct at<Pos, false>
: rest_::template at<Pos-BOOST_MPL_MULTICHAR_LENGTH(C0)>
{};
static char const c_str[];
};
template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C)>
char const string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>::c_str[] =
{
#define M0(z, n, data) at<n>::value
BOOST_PP_ENUM(BOOST_MPL_STRING_MAX_LENGTH, M0, ~)
#undef M0
, '\0' // to ensure the string is null-terminated
};
template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C)>
std::size_t const string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>::size;
template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C)>
unsigned int const string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>::front_;
template<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, unsigned int C)>
unsigned int const string<BOOST_PP_ENUM_PARAMS(BOOST_MPL_STRING_MAX_PARAMS, C)>::back_;
template<>
struct string<>
{
/// INTERNAL ONLY
static unsigned int const front_ = 0;
/// INTERNAL ONLY
static unsigned int const back_ = 0;
/// INTERNAL ONLY
typedef string rest_;
typedef string type;
typedef string_tag tag;
static std::size_t const size = 0;
template<unsigned int>
struct at
: boost::mpl::char_<'\0'>
{};
static char const c_str[];
};
char const string<>::c_str[] = {'\0'};
std::size_t const string<>::size;
unsigned int const string<>::front_;
unsigned int const string<>::back_;
}} // namespace boost
#endif // BOOST_MPL_STRING_HPP_INCLUDED

View File

@@ -44,6 +44,7 @@ compile inherit.cpp ;
compile insert.cpp ;
compile insert_range.cpp ;
run int.cpp ;
run char.cpp ;
run integral_c.cpp : : : <toolset>vacpp:<cxxflags>-qchars=signed ;
compile is_placeholder.cpp ;
compile is_sequence.cpp ;
@@ -90,3 +91,4 @@ compile upper_bound.cpp ;
compile vector.cpp ;
compile vector_c.cpp ;
compile zip_view.cpp ;
run string.cpp ;

24
test/char.cpp Normal file
View File

@@ -0,0 +1,24 @@
// Copyright Eric Niebler 2008
//
// 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: char.cpp 49240 2009-04-01 09:21:07Z eric_niebler $
// $Date: 2009-04-01 02:21:07 -0700 (Wed, 1 Apr 2009) $
// $Revision: 49240 $
#include <boost/mpl/char.hpp>
#include <boost/preprocessor/repeat.hpp>
#include "integral_wrapper_test.hpp"
MPL_TEST_CASE()
{
# define WRAPPER(T, i) char_<i>
BOOST_PP_REPEAT(10, INTEGRAL_WRAPPER_TEST, char)
}

173
test/string.cpp Normal file
View File

@@ -0,0 +1,173 @@
// 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.cpp 49240 2009-04-01 09:21:07Z eric_niebler $
// $Date: 2009-04-01 02:21:07 -0700 (Wed, 1 Apr 2009) $
// $Revision: 49240 $
#include <string>
#include <cstring>
#include <iostream>
#include <boost/mpl/string.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/long.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/empty.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/clear.hpp>
#include <boost/mpl/erase.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/size_t.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/joint_view.hpp>
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/back_inserter.hpp>
#include <boost/mpl/iterator_range.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/detail/lightweight_test.hpp>
namespace mpl = boost::mpl;
// Accept a string as a template parameter!
template<char const *sz>
struct greeting
{
std::string say_hello() const
{
return sz;
}
};
struct push_char
{
push_char(std::string &str)
: str_(&str)
{}
void operator()(char ch) const
{
this->str_->push_back(ch);
}
std::string *str_;
};
void test1()
{
BOOST_TEST(0 == std::strcmp(mpl::string<'Hell','o wo','rld!'>::c_str, "Hello world!"));
BOOST_TEST((12 == mpl::size<mpl::string<'Hell','o wo','rld!'> >::type::value));
BOOST_TEST(('w' == mpl::at_c<mpl::string<'Hell','o wo','rld!'>, 6>::type::value));
// test using a string as a template parameter
greeting<mpl::string<'Hell','o wo','rld!'>::c_str> g;
BOOST_TEST("Hello world!" == g.say_hello());
BOOST_TEST(0 == std::strcmp("", mpl::string<>::c_str));
std::string result;
mpl::for_each<mpl::string<'Hell','o wo','rld!'> >(push_char(result));
BOOST_TEST("Hello world!" == result);
BOOST_MPL_ASSERT((mpl::empty<mpl::string<> >));
BOOST_MPL_ASSERT_NOT((mpl::empty<mpl::string<'hi!'> >));
BOOST_TEST(('h' == mpl::front<mpl::string<'hi!'> >::type()));
BOOST_TEST(('!' == mpl::back<mpl::string<'hi!'> >::type()));
}
// testing push_back
void test2()
{
typedef mpl::push_back<mpl::string<>, mpl::char_<'a'> >::type t1;
BOOST_TEST(0 == std::strcmp("a", t1::c_str));
typedef mpl::push_back<t1, mpl::char_<'b'> >::type t2;
BOOST_TEST(0 == std::strcmp("ab", t2::c_str));
typedef mpl::push_back<t2, mpl::char_<'c'> >::type t3;
BOOST_TEST(0 == std::strcmp("abc", t3::c_str));
BOOST_MPL_ASSERT((boost::is_same<t3, mpl::string<'abc'> >));
typedef mpl::push_back<t3, mpl::char_<'d'> >::type t4;
BOOST_TEST(0 == std::strcmp("abcd", t4::c_str));
typedef mpl::push_back<t4, mpl::char_<'e'> >::type t5;
BOOST_TEST(0 == std::strcmp("abcde", t5::c_str));
BOOST_MPL_ASSERT((boost::is_same<t5, mpl::string<'abcd','e'> >));
typedef mpl::string<'aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaa'> almost_full;
BOOST_TEST(0 == std::strcmp("aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaa", almost_full::c_str));
typedef mpl::push_back<almost_full, mpl::char_<'X'> >::type t6;
BOOST_TEST(0 == std::strcmp("aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaX", t6::c_str));
}
// testing push_front
void test3()
{
typedef mpl::push_front<mpl::string<>, mpl::char_<'a'> >::type t1;
BOOST_TEST(0 == std::strcmp("a", t1::c_str));
typedef mpl::push_front<t1, mpl::char_<'b'> >::type t2;
BOOST_TEST(0 == std::strcmp("ba", t2::c_str));
typedef mpl::push_front<t2, mpl::char_<'c'> >::type t3;
BOOST_TEST(0 == std::strcmp("cba", t3::c_str));
typedef mpl::push_front<t3, mpl::char_<'d'> >::type t4;
BOOST_TEST(0 == std::strcmp("dcba", t4::c_str));
typedef mpl::push_front<t4, mpl::char_<'e'> >::type t5;
BOOST_TEST(0 == std::strcmp("edcba", t5::c_str));
typedef mpl::string<'aaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa','aaaa'> almost_full;
BOOST_TEST(0 == std::strcmp("aaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa", almost_full::c_str));
typedef mpl::push_front<almost_full, mpl::char_<'X'> >::type t6;
BOOST_TEST(0 == std::strcmp("Xaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa" "aaaa", t6::c_str));
}
void test4()
{
// back-inserter with copy
typedef mpl::vector_c<char, 'a','b','c','d','e'> rgc;
typedef mpl::copy<rgc, mpl::back_inserter<mpl::string<> > >::type str;
BOOST_TEST(0 == std::strcmp("abcde", str::c_str));
}
// test insert_range and erase
void test5()
{
typedef mpl::string<'Hell','o wo','rld!'> hello;
typedef mpl::advance_c<mpl::begin<hello>::type, 5>::type where;
typedef mpl::string<' cru','el'> cruel;
typedef mpl::insert_range<hello, where, cruel>::type hello_cruel;
BOOST_TEST(0 == std::strcmp("Hello cruel world!", hello_cruel::c_str));
typedef mpl::erase<hello, mpl::begin<hello>::type, where>::type erased1;
BOOST_TEST(0 == std::strcmp(" world!", erased1::c_str));
}
int main()
{
test1();
test2();
test3();
test4();
test5();
return boost::report_errors();
}