 # Boost :

From: Philippe Mori (philippe_mori_at_[hidden])
Date: 2005-03-28 15:51:16

>
> No problem. I think that's the little I could do to show my appreciation
> to the authors of the book.
>
> One thing to mention: Don't hesitate to contribute your own solutions,
> 'improve' on mine, or post comments or question.
>
> I have noticed that some of my solutions are not ideal, but I have left
> them as I wrote them. I also experimented a bit with the formatting of the
> code so some inconsistencies show up.
>

Well for exercice 2-1, I think I have a solution that is a little better
because it detect when C and X are of the same type and this
lead to a reduction of specilizations that are required for replacement
of complex expressions.

The extra boolean parameter automatically detect when a replacment
is possible for arbitrary complex X that match C.

*** I'm not sure how to add this solution to the Wiki page without
making a long answer that have both answer. For me, it seems that
each post should be independant (as in a news group).

/*
To allows complex replacement without too much specialization
we must be able to detect when C and X are of the same type
and immediatly do the replacement. This is why we add an
additional argument with a default value.
*/

//
// Most general possible case : no specialization and C is not the same
type as X.
//
template <class C, class X, class Y, bool = boost::is_same<C, X>::value>
struct replace_type { typedef C type; };

//
// C and X are the same type
//

template <class C, class X, class Y>
struct replace_type<C, X, Y, true> { typedef Y type; };

//
// Specializations that are used only if C and X are not the same type.
//
template <class C, class X, class Y>
struct replace_type<C const, X, Y, false>
{ typedef typename replace_type<C, X, Y>::type const type; };

template <class C, class X, class Y>
struct replace_type<C *, X, Y, false>
{ typedef typename replace_type<C, X, Y>::type * type; };

template <class C, class X, class Y, int n>
struct replace_type<typename C[n], X, Y, false>
{ typedef typename replace_type<C, X, Y>::type type[n]; };

template <class C, class X, class Y>
struct replace_type<C(*)(), X, Y, false>
{ typedef typename replace_type<C, X, Y>::type (*type)(); };

template <class C, class D, class X, class Y>
struct replace_type<C(*)(D), X, Y, false>
{ typedef typename replace_type<C, X, Y>::type (*type)
(typename replace_type<D, X, Y>::type); };

template <class C, class D, class E, class X, class Y>
struct replace_type<C(*)(D, E), X, Y, false>
{ typedef typename replace_type<C, X, Y>::type (*type)
(typename replace_type<D, X, Y>::type,
typename replace_type<E, X, Y>::type); };