digitalmars.D.learn - Need assistance translating this C++ template
- John (47/47) Oct 27 2014 Howdy,
- Justin Whear (3/4) Oct 27 2014 Without looking at the rest of your code, looks like this line needs to ...
- anonymous (42/55) Oct 27 2014 [...]
- John (4/62) Oct 27 2014 Much appreciated! I saw I didn't even make it a struct shortly
Howdy,
I stumbled across a tiny NES emulator written in C++
(http://bisqwit.iki.fi/jutut/kuvat/programming_examples/nesemu1/nesemu1.cc)
that I feel compelled to make even tinier with some D magic. I am
having trouble with a nested template in the code.
The C++ code:
// Bitfield utilities
template<unsigned bitno, unsigned nbits=1, typename T=u8>
struct RegBit
{
T data;
enum { mask = (1u << nbits) - 1u };
template<typename T2>
RegBit& operator=(T2 val)
{
data = (data & ~(mask << bitno)) | ((nbits > 1 ? val &
mask : !!val) << bitno);
return *this;
}
operator unsigned() const { return (data >> bitno) & mask; }
RegBit& operator++ () { return *this = *this + 1; }
unsigned operator++ (int) { unsigned r = *this; ++*this;
return r; }
};
My D implementation thus far:
// To avoid type confusion...
alias u8 = uint_least8_t;
alias u32 = uint_least32_t;
template RegBit(uint bitno, uint nbits = 1, T = u8) {
T data;
enum { mask = (1u << nbits) - 1u }
// FIXME: Nested template frustration here... HELP
void opAssign(T2 val)
{
data = (data & ~(mask << bitno)) | ((nbits > 1 ? val &
mask : !!val) << bitno);
return *this;
}
auto opCall() { return (data >> bitno) & mask; }
ref RegBit opUnary(string s)() if (s == "++") { return *this
= *this + 1; }
ref RegBit opUnary(string s)(int) if (s== "++") { uint r =
*this; ++*this; return r; }
}
Any push in the right direction would be greatly appreciated. I'm
just trying to get a D implementation up and running before I
start making this smaller and more intuitive.
Oct 27 2014
On Mon, 27 Oct 2014 22:43:22 +0000, John wrote:
void opAssign(T2 val)
Without looking at the rest of your code, looks like this line needs to be
void opAssign(T2)(T2 val)
Oct 27 2014
On Monday, 27 October 2014 at 22:43:23 UTC, John wrote:The C++ code: // Bitfield utilities template<unsigned bitno, unsigned nbits=1, typename T=u8> struct RegBit {[...]template<typename T2> RegBit& operator=(T2 val)[...]}; My D implementation thus far:[...]template RegBit(uint bitno, uint nbits = 1, T = u8) {You're missing the struct here. Add some (template) parameters to a struct, and it becomes a struct template: struct RegBit(uint bitno, uint nbits = 1, T = u8) [...]// FIXME: Nested template frustration here... HELP void opAssign(T2 val)Similarly, add another set of (template) parameters to a function/method, before the runtime parameters, and it becomes a function/method template: void opAssign(T2)(T2 val) [...]}Those "slap another set of parameters on, and it's a template" syntaxes, are sugar for the longer "eponymous member" variant: struct Foo(T) {} is equivalent to template Foo(T) { struct Foo /* same name as the template */ { /* ... */ } } Works with structs, classes, functions, etc. So if you wanted to spell the templates out, it would look like this: template RegBit(uint bitno, uint nbits = 1, T = u8) { struct RegBit { /* ... other members of RegBit ... */ template opAssign(T2) { void opAssign(T2 val) { /* ... implementation of opAssign ... */ } } /* ... other members of RegBit ... */ } }
Oct 27 2014
On Monday, 27 October 2014 at 23:19:42 UTC, anonymous wrote:On Monday, 27 October 2014 at 22:43:23 UTC, John wrote:Much appreciated! I saw I didn't even make it a struct shortly after posting, time to take a nap and restrain the caffeine intake. And thanks for the missing parameter, Justin.The C++ code: // Bitfield utilities template<unsigned bitno, unsigned nbits=1, typename T=u8> struct RegBit {[...]template<typename T2> RegBit& operator=(T2 val)[...]}; My D implementation thus far:[...]template RegBit(uint bitno, uint nbits = 1, T = u8) {You're missing the struct here. Add some (template) parameters to a struct, and it becomes a struct template: struct RegBit(uint bitno, uint nbits = 1, T = u8) [...]// FIXME: Nested template frustration here... HELP void opAssign(T2 val)Similarly, add another set of (template) parameters to a function/method, before the runtime parameters, and it becomes a function/method template: void opAssign(T2)(T2 val) [...]}Those "slap another set of parameters on, and it's a template" syntaxes, are sugar for the longer "eponymous member" variant: struct Foo(T) {} is equivalent to template Foo(T) { struct Foo /* same name as the template */ { /* ... */ } } Works with structs, classes, functions, etc. So if you wanted to spell the templates out, it would look like this: template RegBit(uint bitno, uint nbits = 1, T = u8) { struct RegBit { /* ... other members of RegBit ... */ template opAssign(T2) { void opAssign(T2 val) { /* ... implementation of opAssign ... */ } } /* ... other members of RegBit ... */ } }
Oct 27 2014









Justin Whear <justin economicmodeling.com> 