# CPPTM Answers - Exercise A-0

BOOST WIKI | RecentChanges | Preferences | Page List | Links List

Difference (from prior major revision) (no other diffs)

Changed: 77,84c77,92
 #define TINY_size(z, n, unused) \ template \ struct tiny_size< \ BOOST_PP_ENUM_PARAMS(n, T) \ BOOST_PP_COMMA_IF(n) \ BOOST_PP_ENUM( \ BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_identity, none) \ > : boost::mpl::int_ \
 #define TINY_size(z, n, unused) \\ template \\ struct tiny_size< \\ BOOST_PP_ENUM_PARAMS(n, T) \\ BOOST_PP_COMMA_IF(n) \\ BOOST_PP_ENUM( \\ BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_identity, none) \\ > : boost::mpl::int_ \\

Changed: 117,120c125,132
 #define TINY_at(z,n,unused)\ templatestruct tiny_at\ {\ typedef typename BOOST_PP_CAT(Tiny::t,n) type; \
 #define TINY_at(z,n,unused)\\ templatestruct tiny_at\\ {\\ typedef typename BOOST_PP_CAT(Tiny::t,n) type; \\

//by pierric
``` #include <boost/preprocessor/repetition.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
```

``` #include <boost/mpl/at.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/iterator_tags.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
```

``` namespace mpl = boost::mpl;
```

``` struct tiny_tag{};
struct none{};
```

``` #define TINY_MAX_SIZE 3
```

``` #define TINY_member(z, n, unused) typedef BOOST_PP_CAT(T,n) BOOST_PP_CAT(t,n);
#define TINY_params(z, n, unused) class BOOST_PP_CAT(T,n)=none
template<BOOST_PP_ENUM(TINY_MAX_SIZE, TINY_params, ~)>
struct tiny
{
typedef tiny_tag tag;
typedef tiny type;
BOOST_PP_REPEAT(TINY_MAX_SIZE, TINY_member,~)
};
#undef TINY_member
#undef TINY_params
```

``` template<class Tiny,class Pos>
struct tiny_iterator
{
typedef mpl::random_access_iterator_tag category;
};
```

``` namespace boost{ namespace mpl {
```

```	template<class Tiny,class Pos>
struct next<tiny_iterator<Tiny,Pos> >
{
typedef tiny_iterator
<
Tiny,
typename boost::mpl::next<Pos>::type
>	type;
};
template<class Tiny,class Pos>
struct prior<tiny_iterator<Tiny,Pos> >
{
typedef tiny_iterator
<
Tiny,
typename boost::mpl::prior<Pos>::type
>	type;
};
```

```	template<>
struct begin_impl<tiny_tag>
{
template<class Tiny>
struct apply
{
typedef tiny_iterator<Tiny,int_<0> > type;
};
};
```

```	template<BOOST_PP_ENUM_PARAMS(TINY_MAX_SIZE, class T)>
struct tiny_size : boost::mpl::int_<TINY_MAX_SIZE>
{};
#define TINY_identity(z,n,data) data
#define TINY_size(z, n, unused) \
template<BOOST_PP_ENUM_PARAMS(n, class T)> \
struct tiny_size< \
BOOST_PP_ENUM_PARAMS(n, T) \
BOOST_PP_COMMA_IF(n) \
BOOST_PP_ENUM( \
BOOST_PP_SUB(TINY_MAX_SIZE,n), TINY_identity, none) \
> : boost::mpl::int_<n>	 \
{};
```

```	BOOST_PP_REPEAT(TINY_MAX_SIZE, TINY_size, ~)
#undef TINY_size
#undef TINY_identity
```

```	template<>
struct end_impl<tiny_tag>
{
template<class Tiny>
struct apply
{
typedef tiny_iterator
<
Tiny,
typename tiny_size<
BOOST_PP_ENUM_PARAMS(TINY_MAX_SIZE, typename Tiny::t)
>::type
> type;
};
};
```

```	template<>
struct size_impl<tiny_tag>
{
template<class Tiny>
struct apply :
tiny_size<BOOST_PP_ENUM_PARAMS(TINY_MAX_SIZE, typename Tiny::t)>
{};
};
```

```	template<class Tiny,int pos> struct tiny_at;
#define TINY_at(z,n,unused)\
template<class Tiny>struct tiny_at<Tiny, n>\
{\
typedef typename BOOST_PP_CAT(Tiny::t,n) type;	\
};
BOOST_PP_REPEAT(TINY_MAX_SIZE, TINY_at, ~)
#undef TINY_at
```

```	template<>
struct at_impl< tiny_tag >
{
template<class Tiny,class Pos>
struct apply : tiny_at<Tiny,Pos::value>
{};
};
```

```	template<class Tiny,class Pos>
struct deref< tiny_iterator<Tiny,Pos> > : at<Tiny,Pos>
{};
}}
```

``` int main(int argc,char** argv)
{
typedef tiny<>			t0;
typedef tiny<int>		t1;
typedef tiny<int,int>		t2;
typedef tiny<int,int,int>	t3;
```

```	typedef mpl::begin<t3>::type	b_it;
BOOST_STATIC_ASSERT((boost::is_same<mpl::deref<b_it>::type,int>::value));
typedef mpl::next<b_it>::type	b_1;
BOOST_STATIC_ASSERT((boost::is_same<mpl::deref<b_1>::type ,int>::value));
typedef mpl::next<b_1>::type	b_2;
BOOST_STATIC_ASSERT((boost::is_same<mpl::deref<b_2>::type ,int>::value));
```

```	BOOST_STATIC_ASSERT( 0 == mpl::size<t0>::value );
BOOST_STATIC_ASSERT( 1 == mpl::size<t1>::value );
BOOST_STATIC_ASSERT( 2 == mpl::size<t2>::value );
BOOST_STATIC_ASSERT( 3 == mpl::size<t3>::value );
}
```

BOOST WIKI | RecentChanges | Preferences | Page List | Links List