AMDG On 12/13/2010 3:52 PM, John Dlugosz wrote:
A couple of times I've run into the situation where a "new" C++ class is written to exactly match "legacy" C structures. At the edges where old code meets new code, you can cast one to the other in-place. For example, given a huge mess of data that includes oldstruct s1; you could write the line newclass& s2= reinterpret_cast
(s1); because s2 is designed to exactly overlay s1. It might even derive from it, and just add member functions and friendlier accessors. Another example I've seen is a class that contains nothing but a char* pointer member, that contains overloaded operators to replace the ancient str* functions. In particular, it has an operator==, so casting an array of char* to an array of that class allowed std::find to be used! I don't like the wild and unchecked use of reinterpret_cast, but I can see the point for these and think the idiom can be tamed. Basically, I want to write a cisam_cast that behaves like a reinterpret_cast but only for those conversions I've explicitly nominated as being cisam's. CISAM is "compatible in structure and meaning", and I avoid calling it "upgrade" because it works in either direction or sideways between different code bases' definitions of the same wire data.
I'm thinking that I should be able to declare something like template<> cisam
: std::tr1::true_type {}; to enable cisam_cast<xxx>(a_yyy) to have the same meaning as reinterpret_cast (a_yyy), etc. (foreshadowing hard question...) Since it would be common to make a new class to wrap a primitive type or old struct, a shortcut would be to include a typedef yyy cisam; as a member of xxx.
Now I get around to my actual question: the "etc." part above. Given that xxx and yyy are cisam-mates, I want to enable not only xxx to yyy and vice versa, but handle const and volatile qualified forms with correct cv-modifier carry-through, and handle pointers to them to any depth, which is complicated by the fact that there could be cv-qualifiers at any level.
In the earlier example, the original code was something like: char* A[7]; char* val; //... Str* SA= reinterpret_cast
((char**)A); and I would want Str* SA= cisam_cast (A); to be accepted. Note that the cisam-ness is between (char*) and (Str), so there are a different number of stars on the before and the after. So, how might I write the cisam_cast machinery to elaborate the basic cisam definitions into the full set of allowed casts?
something like this?
template