$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
From: Hamish Mackenzie (boost_at_[hidden])
Date: 2001-11-26 10:17:16
On Mon, 2001-11-26 at 12:29, Peter Dimov wrote:
> Agreed. We already had this discussion on the list before but I'd like to
> revisit it:
>
> class nil;
I think it will be useful to differentiate between an empty type list
and a nil type. For instance, you can append items to an empty list but
appending to a nil type should probably be an error.
How about type_list::nil?
> Have you considered using std::pair as the 'dot pair' type? It doesn't
> really matter which template is used as long as it has two type parameters -
> it doesn't even need a definition. std::pair is handy since it automatically
> maps a value list (a tuple) to a typelist.
It would mean that in order to tell a pair from a tuple you would have
to use a template class that checks for the empty list type at the end
of the list.
So if we are going to do it I would prefer
template< Head, Tail >
class type_list : private boost::compressed_pair< Head, Rest >
{
typedef compressed_pair< Head, Tail > base;
public:
typedef typename base::first_type head_type;
typedef typename base::second_type tail_type;
typedef typename base::first_param_type head_param_type;
typedef typename base::second_param_type tail_param_type;
typedef typename base::first_reference head_reference;
typedef typename base::second_reference tail_refenece;
typedef typename base::first_const_reference head_const_refence;
typedef typename base::second_const_reference tail_const_refence;
type_list() : base() {}
type_list(head_param_type x, tail_param_type y) : base(x, y) {}
head_reference head() { return base::first(); }
head_const_reference head() const { return base::first(); }
tail_reference tail() { return base::second(); }
tail_const_reference tail() const { return base::second(); }
void swap( type_list & y ) { base::swap( y ); }
class nil{};
};
This would simplify using tuples and I can't think of a good argument
not to do it. It would however, mean that tuples and type_lists would be
forever linked. Can anyone think of a reason we might want more than
one tuple type?
The alternative would be
template< class TypeList >
class tuple;
template< class Head, class TypeList >
class tuple< type_list< Head, TypeList > >
: private pair< Head, TypeList >
{
...
};
Adding storage to type_list would not break this approach, so if we
changed our minds later on it would be no big deal (touch wood).
> Why did you reject the make_typelist<...>::type approach?
template< class X >
class foo;
class a;
class b;
class c;
class foo< typename make_typelist< a, b, c >::type >
{
};
typedef foo< typename make_typelist< a, b, c >::type > x;
As I understand it this is not possible with the existing standard and
is unlikely to every work. The compiler would have to try all possible
instaniations of make_typelist to find one that matches.
On another note how about adding
template< class Head >
type_list< Head, type_list::nil > operator << (
const type_list::nil &t, const Head &h )
{
return type_list< Head, type_list::nil >( h, t );
}
template< class Head, class H2, class Tail >
type_list< Head, type_list< H2, Tail > > operator << (
const type_list< H2, Tail > &t, const Head &h )
{
return type_list< Head, type_list< H2, Tail > >( h, t );
}
template< class Head, class Tail >
Tail operator >> ( const type_list< Head, Tail > &t, Head &h )
{ // Is there a better way to make this exception safe?
struct assign_if_not_cancelled
{
bool cancelled_;
Head &dest_;
const Head &source_;
assign_if_not_cancelled( Head &d, const Head &s )
: cancelled_( false ), dest_( d ), source_( s ) (
{
}
~assign_if_not_cancelled()
{
if( !cancelled_ )
{
dest_ = source_;
}
}
} x( h, t.head() );
try
{
return t.tail();
}
catch( ... )
{
x.cancelled_ = true;
throw;
}
}
This could be used as follows
template< class TypeList >
void f( TypeList t )
{
int a;
double b;
char *c;
t >> c >> b >> a;
}
...
f( TYPELIST_0 << 1 << 2.0 << "Test" );
Like streams but LIFO rather than FIFO. We could change it to be FIFO if
that makes more sense.
Hamish