<div>Or, we can only implement a WELL-DEFINED subset of property: no [] support.</div><div> - I looked at ATL headers, those properties are all defined without [].</div><div> - My work is financially supported by GEMS8(<a href="http://wwwm.gems8.com">http://wwwm.gems8.com</a>), which only use property without [].</div>
<div> - Any property usage involving [] seems totally "undefined". I guess there are only god-know-what rules defined by VC developers, and they'are not intended for real-world use.</div><div>Is this suggestion ok?</div>
<div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Dec 17, 2012 at 10:51 PM, <a href="mailto:endlessroad1991@gmail.com">endlessroad1991@gmail.com</a> <span dir="ltr"><<a href="mailto:endlessroad1991@gmail.com" target="_blank">endlessroad1991@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>Here's a try to summarize implementation detail about __decpspec(property):</div><div>1. Add a MSPropertyDecl, because:</div>
<div>    - Property can be private, as long as getter/setter is public. This is different from regular members.</div>
<div>    - Type of property can be imcomplete, like return type of a member function. This is different from regular members.</div><div>    - We can use it to store how many parameters should be used for getter/setter</div>

<div>2. Add a MSPropertyRefExpr, like ObjCPropertyRefExpr. Preserve all (index) parameters for getter/setter calls in ast. This is necessary because (a.v)[1][2] and (a.v[1])[2] are both legal.</div><div>3. Lookup actual getter/setter, and generate CallExpr in PseudoObject related routines.</div>

<div> </div><div>And a complete test, covering all that I can think of now.</div><div> </div><div> </div><div>#include <iostream><br>#include <vector></div><div>class C<br>{<br> // property can be private, as long as getter/setter is public.<br>

 __declspec(property(get=GetA, put=SetA)) int A[123][321];<br>public:<br> // We choose getter/setter like regular overloaded functions.<br> int GetA() { std::cout << "Get 0\n"; return 0; }<br> int GetA(double i) { std::cout << "Get 1\n"; return 0; }<br>

 int GetA(int i) { std::cout << "Get 1i\n"; return 0; }<br> int GetA(double i, double j) { std::cout << "Get 2\n"; return 0; }<br> void SetA(int value) { std::cout << "Set 0\n"; }<br>

 void SetA(double i, double value) { std::cout << "Set 1\n"; }<br> void SetA(double i, double j, int value) { std::cout << "Set 2\n"; }</div><div> // Property type can be reference.<br> __declspec(property(get=GetA2, put=SetA2)) int& A2;<br>

 int& GetA2() { std::cout << "GetA2\n"; return ri; }<br> void SetA2(int& v) { std::cout << "SetA2\n"; ri = v; }</div><div> // "[]" can be filled with a integer number, which is legal, but useless.<br>

 // And "[]" that appear in typedef will also be treated as placeholder for parameter.<br> typedef int int_arr[10][10];<br> __declspec(property(get=GetA3, put=SetA3)) int_arr A3;<br> int GetA3() { std::cout << "GetA3 0\n"; return 0; }<br>

 int GetA3(double i) { std::cout << "GetA3 1\n"; return 0; }<br> int GetA3(double i, double j) { std::cout << "GetA3 2\n"; return 0; } // We can only leave this getter.</div><div> // If property type is pointer, only getter/setter with NO parameters will be picked.<br>

 __declspec(property(get=GetA4, put=SetA4)) int ***A4;<br> int*** GetA4() { std::cout << "GetA4 0\n"; return ppp; }<br> int*** GetA4(int i) { std::cout << "GetA4 1\n"; return ppp; }<br> int*** GetA4(int i, int j) { std::cout << "GetA4 2\n"; return ppp; }<br>

 void SetA4(int ***v) { std::cout << "SetA4 0\n"; }<br> void SetA4(int i, int ***v) { std::cout << "SetA4 1\n"; }<br> void SetA4(int i, int j, int ***v) { std::cout << "SetA4 2\n"; }</div>

<div> // Even if property type can be subscripted, we cannot directly subsrcipt it by appending "[]".<br> __declspec(property(get=GetA5)) std::vector<int> A5[];<br> std::vector<int> GetA5(int i) { std::cout << "GetA5 1\n"; return v; }<br>

 std::vector<int> GetA5(int i, int j) { std::cout << "GetA5 2\n"; return v; }</div><div> std::vector<int> v;<br> int i;<br> int &ri;<br> int *p;<br> int **pp;<br> int ***ppp;<br> C(int &ri_): ri(ri_) { p = &i, pp = &p, ppp = &pp; }<br>

};</div><div>int main()<br>{<br> int ri = 5445;<br> C c(ri);</div><div> int i = c.A; // Get 0<br> int j = c.A[1.0f]; // Get 1<br> int j2 = c.A[1]; // Get 1i<br> int k = c.A[1.0f][2.0f]; // Get 2<br> int k1 = (c.A)[1.0f][2.0f]; // Get 2<br>

 int k2 = (c.A[1.0f])[2.0f]; // Get 2</div><div> int& ir = c.A2; // GetA2<br> std::cout << ir << "\n"; // 5445<br> int ai = 4;<br> c.A2 = ai; // SetA2 // SetA2 must exist!<br> std::cout << c.A2 << "\n"; // GetA2 // 4<br>

 ai = 3;<br> std::cout << c.A2 << "\n"; // GetA2 // 4</div><div> int ii = c.A3; // GetA3 0<br> int jj = c.A3[1.0]; // GetA3 1<br> int kk = c.A3[1.0][2.0]; // GetA3 2<br> int ll = c.A3[1]; // GetA3 1</div>

<div> int ***a1 = c.A4; // GetA4 0<br> int **b1 = c.A4[0]; // GetA4 0<br> int *c1 = c.A4[0][0]; // GetA4 0<br> int d1 = c.A4[0][0][0]; // GetA4 0<br> // int d2 = c.A4[0][0][0][0]; // Doesn't compile<br> c.A4 = 0; // SetA4 0<br>

 c.A4[0] = c.pp; // GetA4 0<br> c.A4[0][0] = c.p; // GetA4 0<br> c.A4[0][0][0] = 0; // GetA4 0</div><div> std::vector<int> v = c.A5[0]; // GetA5 1<br> v = c.A5[0][0]; // GetA5 2<br> //int v2 = c.A5[0][0]; // Doesn't compile, "Cannot convert vector<int> to int"<br>

 //int v3 = c.A5[0][0][0]; // Doesn't compile, "Cannot convert vector<int> to int"<br>}</div>
</blockquote></div><br><br clear="all"><br>-- <br>Best Regards, Tong Shen (沈彤)<br>
</div>