Boost logo

Boost Users :

Subject: Re: [Boost-users] metaprogramming help
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2010-12-13 19:02:15


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<newclass&>(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<xxx,yyy> : std::tr1::true_type {};
> to enable cisam_cast<xxx>(a_yyy) to have the same meaning as reinterpret_cast<xxx&>(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<Str*>((char**)A);
> and I would want
> Str* SA= cisam_cast<Str*>(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<class T, class U>
struct cisam<const T, const U> : cisam<T, U> {};
template<class T, class U>
struct cisam<volatile T, volatile U> : cisam<T, U> {};
template<class T, class U>
struct cisam<const volatile T, const volatile U> : cisam<T, U> {};
template<class T, class U>
struct cisam<T*, U*> : cisam<T, U> {};

In Christ,
Steven Watanabe


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net