| Thread overview | ||||||
|---|---|---|---|---|---|---|
|
October 27, 2014 Need assistance translating this C++ template | ||||
|---|---|---|---|---|
| ||||
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. | ||||
October 27, 2014 Re: Need assistance translating this C++ template | ||||
|---|---|---|---|---|
| ||||
Posted in reply to John | 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)
| |||
October 27, 2014 Re: Need assistance translating this C++ template | ||||
|---|---|---|---|---|
| ||||
Posted in reply to John | 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 ... */ } } | |||
October 27, 2014 Re: Need assistance translating this C++ template | ||||
|---|---|---|---|---|
| ||||
Posted in reply to anonymous | On Monday, 27 October 2014 at 23:19:42 UTC, anonymous wrote:
> 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 ... */
> }
> }
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.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply