template parameter representation


M

ma740988

Consider:

# include <cstdio>
# include <string>
# include <sstream>
# include <vector>
# include <ctime>
# include <cassert>

template < typename T >
struct some_other_policy {};

template < typename T >
struct no_policy {};

template < typename UnsignedType,
typename default_policy = no_policy < UnsignedType > ,
unsigned base = 0, unsigned offset = 0 >
struct hw_default {
// default implementation....
};

template < typename UnsignedType,
typename default_policy = no_policy < UnsignedType > ,
unsigned base = 0, unsigned offset = 0 >
struct hw_register_struct {
// implementation changes here..
};


template < bool val >
struct static_assert;

template <>
struct static_assert< true > {};

template < typename T >
struct strip_pod_type {};

#define STRIP_POD_TYPE(Int) \
template <> \
struct strip_pod_type< volatile Int > { \
typedef Int type; \
}; \
template <> \
struct strip_pod_type< Int > { \
typedef Int type; \
} \

STRIP_POD_TYPE( char );
STRIP_POD_TYPE( unsigned char );
STRIP_POD_TYPE( signed char );
STRIP_POD_TYPE( unsigned short );
STRIP_POD_TYPE( signed short );
///more

#undef STRIP_POD_TYPE

template < typename Type >
struct traits
{
typedef typename strip_pod_type<Type>::type interface_type;

};

template < typename U, typename en, unsigned long base, unsigned
offset >
struct traits< hw_default <U,en,base,offset > >
{
typedef typename strip_pod_type<U>::type interface_type;

};

template < typename UnsignedType, unsigned low, unsigned high >
class foo
: static_assert< high <= CHAR_BIT *
sizeof( typename traits< UnsignedType >::interface_type ) >
{
typedef typename
traits< UnsignedType >::interface_type interface_type;

typedef UnsignedType host_type;
host_type & host_obj;
public :
foo ( host_type & in )
: host_obj ( in )
{}
//more stuff..
};


typedef hw_default < volatile unsigned short > hw_default_type;

typedef hw_register_struct < volatile unsigned short,
some_other_policy < unsigned short >,
0x500,
0 > hw_register_struct_type;

int main()
{
unsigned short aa ( 0 );
foo < volatile unsigned short, 5, 6 > aa5_6 ( aa );

hw_default_type ab ;
foo < hw_default_type, 5, 6 > ab5_6 ( ab );

//hw_register_struct_type ac ;
//foo < hw_register_struct_type, 5, 6 > ac5_6 ( ac );

}

Apologies in advance if I'm not using the right C++ lingo. How could
i modify source above such that I could use the composite type
hw_register_struct_type? The code today is not extensible because
it's structured around the default - hw_default_type which works for
'most' cases.
 
Ad

Advertisements

A

Alf P. Steinbach

* ma740988:
Consider:

# include <cstdio>
# include <string>
# include <sstream>
# include <vector>
# include <ctime>
# include <cassert>

template < typename T >
struct some_other_policy {};

template < typename T >
struct no_policy {};

template < typename UnsignedType,
typename default_policy = no_policy < UnsignedType > ,
unsigned base = 0, unsigned offset = 0 >
struct hw_default {
// default implementation....
};

template < typename UnsignedType,
typename default_policy = no_policy < UnsignedType > ,
unsigned base = 0, unsigned offset = 0 >
struct hw_register_struct {
// implementation changes here..
};


template < bool val >
struct static_assert;

template <>
struct static_assert< true > {};

template < typename T >
struct strip_pod_type {};

#define STRIP_POD_TYPE(Int) \
template <> \
struct strip_pod_type< volatile Int > { \
typedef Int type; \
}; \
template <> \
struct strip_pod_type< Int > { \
typedef Int type; \
} \

STRIP_POD_TYPE( char );
STRIP_POD_TYPE( unsigned char );
STRIP_POD_TYPE( signed char );
STRIP_POD_TYPE( unsigned short );
STRIP_POD_TYPE( signed short );
///more

#undef STRIP_POD_TYPE

template < typename Type >
struct traits
{
typedef typename strip_pod_type<Type>::type interface_type;

};

template < typename U, typename en, unsigned long base, unsigned
offset >
struct traits< hw_default <U,en,base,offset > >
{
typedef typename strip_pod_type<U>::type interface_type;

};

template < typename UnsignedType, unsigned low, unsigned high >
class foo
: static_assert< high <= CHAR_BIT *
sizeof( typename traits< UnsignedType >::interface_type ) >
{
typedef typename
traits< UnsignedType >::interface_type interface_type;

typedef UnsignedType host_type;
host_type & host_obj;
public :
foo ( host_type & in )
: host_obj ( in )
{}
//more stuff..
};


typedef hw_default < volatile unsigned short > hw_default_type;

typedef hw_register_struct < volatile unsigned short,
some_other_policy < unsigned short >,
0x500,
0 > hw_register_struct_type;

int main()
{
unsigned short aa ( 0 );
foo < volatile unsigned short, 5, 6 > aa5_6 ( aa );

hw_default_type ab ;
foo < hw_default_type, 5, 6 > ab5_6 ( ab );

//hw_register_struct_type ac ;
//foo < hw_register_struct_type, 5, 6 > ac5_6 ( ac );

}

Apologies in advance if I'm not using the right C++ lingo. How could
i modify source above such that I could use the composite type
hw_register_struct_type? The code today is not extensible because
it's structured around the default - hw_default_type which works for
'most' cases.

You haven't shown the use of the type, in particular foo.

But it seems like a case of search and replace.

Some refactoring tools may be able to do that for you, but an editor is probably
easiest.


Cheers & hth.,

- Alf
 
M

ma740988

Greetings Alf,
You haven't shown the use of the type, in particular foo.
Not sure I'm following you.
But it seems like a case of search and replace.

Some refactoring tools may be able to do that for you, but an editor is probably
easiest.

I want a mix of hw_default_type and hw_register_struct_type within the
code. I think I just had a revelation though (this after firing up
thinking in C++ vol 2). perhaps I could derive off the default. ie.

template < typename UnsignedType,
typename default_policy = no_policy < UnsignedType > ,
unsigned base = 0, unsigned offset = 0 >
struct hw_default {
// default implementation....
};

template < typename UnsignedType,
typename use_this_policy,
unsigned base = 0, unsigned offset = 0 >
struct i_dont_want_default :
public hw_default < UnsignedType, altera_reg, base, offset > {
// stuff..
};


Mark
 
M

ma740988

Greetings Alf,
 template < typename UnsignedType,
           typename use_this_policy,
           unsigned base = 0, unsigned offset = 0 >
 struct i_dont_want_default :
   public hw_default < UnsignedType, use_this_policy, base, offset > {
  // stuff..
 };

Mark

So much for that idea. Derivation off hw_default sure didn't work.
Mark
 
A

Alf P. Steinbach

* ma740988:
Greetings Alf,

Not sure I'm following you.

I'm not sure I follow me.

I want a mix of hw_default_type and hw_register_struct_type within the
code. I think I just had a revelation though (this after firing up
thinking in C++ vol 2). perhaps I could derive off the default. ie.

template < typename UnsignedType,
typename default_policy = no_policy < UnsignedType > ,
unsigned base = 0, unsigned offset = 0 >
struct hw_default {
// default implementation....
};

template < typename UnsignedType,
typename use_this_policy,
unsigned base = 0, unsigned offset = 0 >
struct i_dont_want_default :
public hw_default < UnsignedType, altera_reg, base, offset > {
// stuff..
};

If the purpose is to be able to use a single name and easily change the code in
one place to have that name refer to different types, then how about a typedef.


Cheers & hth.,

- Alf
 
M

ma740988

Ad

Advertisements

M

ma740988

If the purpose is to be able to use a single name and easily change the code in
one place to have that name refer to different types, then how about a typedef.

I suspect i should be clear. Sure I could typedef the default, hence

typedef hw_default < volatile unsigned short > hw_default_type1;
typedef hw_default < volatile unsigned char,
some_other_policy < unsigned short >,
0x500,
0 > hw_default_type2;

While hw_default works for 90% of the cases, I'd like to override it.
Hence:

template < typename UnsignedType,
typename default_policy = no_policy < UnsignedType > ,
unsigned base = 0, unsigned offset = 0 >
struct hw_register_struct {
// implementation changes here..
};

typedef hw_register_struct < volatile unsigned char,
some_other_policy < unsigned short >,
0x500,
0 > hw_register_struct_type ;

and use hw_register_struct_type instead.

int main()
{
//OK
unsigned short aa ( 0 );
foo < volatile unsigned short, 5, 6 > aa5_6 ( aa );
//OK
hw_default_type1 ab ;
foo < hw_default_type1, 5, 6 > ab5_6 ( ab );
//OK
hw_default_type2 ac ;
foo < hw_default_type2, 5, 6 > ac5_6 ( ac );
//NOPE - compiler error
hw_register_struct_type aac ;
foo < hw_register_struct_type, 5, 6 > aac5_6 ( aac );

}

Mark
 
Ad

Advertisements

M

ma740988

Greetings Alf,
If the purpose is to be able to use a single name and easily change the code in
one place to have that name refer to different types, then how about a typedef.
I had an inspiration.

Somewhere along the way, I need to revisit at a minimum Modern C++
Design. At times the various policy, Traits, etc classes tend to get
blurred in my mind. In any event, given the desire to use a different
implementation beyond hw_default all the end use needs to do is add a
new trait, so now:

template < typename U, typename en, unsigned long base, unsigned
offset >
struct traits< whatever_else <U,en,base,offset > > //NOTE:
whatever_else here..
{
typedef typename strip_pod_type<U>::type interface_type;

};

template < typename UnsignedType,
typename default_policy = no_policy < UnsignedType > ,
unsigned base = 0, unsigned offset = 0 >
struct whatever_else {
// Add the stuff that needs to be 'different' from hw_default.

};
Carry on from there.
Mark
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top