using opAssign or having my own assign function

Reiner Pope some at address.com
Tue Sep 4 23:46:02 PDT 2007


Martin d Anjou wrote:
> Hi,
> 
> I am trying to build a data type where a key characteristic is that the 
> data holding capacity is fixed and never changing, and the declaration 
> looks like this:
> 
> auto a = BitVector(4);   // "a" can hold unsigned numbers from 0 to 15
> auto b = BitVector(10);  // 10 bits of data
> auto c = BitVector(79);  // etc.
> 
> Say I now want to add b and c, and store the result in a, while 
> preserving the property that "a" has to have a capacity of 4 bits only. 
> Adding and truncating the upper bits to fit in "a" is the easy part. The 
> problematic part is stating that the result of the addition goes to 
> variable "a".
> 
> I was first tempted to simply say "a=b+c", but b+c will return a new 
> instance of BitVector, scrap the original "a", and loose the holding 
> capacity of "a". I thought of overloading opAssign(), but I can't do 
> "BitVector opAssign(BitVector other) { ... }".
> 
> So I came to the conclusion the least non-intuitive thing to do would be 
> "a.assign(b+c)", which preserves the storage capacity declared for 
> variable "a", and does not create a new instance for "a".
> 
> Question: Is there a better way to do this?
> 
> Question: Is there a chance opAssign could be used for this kind of 
> thing at all in the future?
> 
> Thanks,
> Martin

If the size of your BitVector is fixed at compile-time, then you can 
integrate this into the type (by making the size a template parameter). 
In that case, BitVectors of different size are different types, making 
opAssign work (since you're assigning something of a different type). 
The following is working code:

---

import std.stdio;

int max(int a, int b) { return (a > b) ? a : b; }

struct BitVector(int len)
{
     alias typeof(*this) BV;

     static BV opCall() {
         BV result;
         return result;
     }

     BV opAssign(int len2)(BitVector!(len2) other)
     {
         writefln("Assigning vector of size %s to one of size %s", len2, 
len);
         return *this;
     }

     BitVector!(max(len, len2)) opAdd(int len2)(BitVector!(len2) other)
     {
         writefln("Adding a vector of size %s to one of size %s", len2, 
len);
         return BitVector!(max(len, len2))();
     }
}

void main()
{
     auto a = BitVector!(4)();
     auto b = BitVector!(10)();
     auto c = BitVector!(79)();
     writefln("A");
     a = b + c;
     writefln("B");
     c = b + c;
}

---

The output is

A
Adding a vector of size 79 to one of size 10
Assigning vector of size 79 to one of size 4
B
Adding a vector of size 79 to one of size 10

---


If, on the other hand, the size can't be made part of the type, then 
this doesn't work. Bill's expression templates are a solution that also 
currently work. However, I think a cleaner solution is the future 
"opCopy" mentioned in WalterAndrei.pdf -- you'll have to wait for it, 
though.


     -- Reiner



More information about the Digitalmars-d mailing list