Re: a hardware address constant as class template argument
Am 15.06.2014 21:34, schrieb Johannes Sixt:
To program a micro controller (AVR), I would like to define a class template
that I would like to use in this way in my code:
typedef HWRegister<&TIMSK0> TimerFlags;
The system header files define TIMSK0 like so:
#define TIMSK0 (*(volatile unsigned char*)110)
As you see, the address is a constant, and I thought it should be possible
to find a template definition that takes the constant as template argument.
I started with this definition:
template<volatile uint8_t& ADDR> struct HWRegister {};
but the compiler (gcc) reports:
port.h:6:27: error: template argument 1 is invalid
typedef HWRegister<&TIMSK0> TimerFlags;
^
Well, you declared the template parameter to be a reference but provided
a pointer-value. Try HWRegister<TIMSK0> (without the ampersand).
But I'm not sure, if what you intended to do is actually possible. There
might be some restrictions w.r.t. what pointers and references as
non-type template parameters can refer to. IIRC they can only refer to
things with external linkage. But TIMSKO does not have any linkage at
all. So, &TIMSKO being a compile-time constant is probably not enough to
please the template machinery.
I finally ended up using a macro:
template<uintptr_t ADDR> struct HWRegister {};
#define TypdefHWRegister(hwreg, name) \
typedef \
HWRegister< \
reinterpret_cast<unsigned>( \
&const_cast<unsigned char &>(hwreg) \
) \
> name
that is used like this:
TypdefHWRegister(TIMSK0, TimerFlags);
but I don't like this syntax. Is there some template magic that can extract
the address constant from TIMSK0? I'm not married to the particular usage
pattern cited at the top of this post, but it should be equally "simple".
I guess you're stuck with the reinterpret/unsigned approach. At least I
don't see another way.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]