
I'm not entirely convinced that it should be possible to treat a prism as a rectangle without an explicit conversion of some kind. contains for a prism should treat it as as prism. The general solution to this kind of problem is tag dispatching.
Yes, I can see how defining a prism_tag and rectangle_tag in traits classes would allow template<class T, class T2> bool contains (const T& r1, const T& r2) { return contains_dispatch(r1, r2, traits<T>::type_tag); } to disambiguate through the added layer of abstraction.
How important is it to not make a copy of the prism? Alternately, how important is it to be able to copy the whole prism while treating it as a rectangle?
It is important for performance considerations, but also becomes increasingly important as the size of the object increases. For a polygon which may have anywhere from 4 to 4 million vertices requiring copy conversion simply to satisfy type requirements when viewing it as a polygon with holes vs. polygon without holes the issue is cast in a different light. It is somewhat less important to copy the whole prism when viewing it as a rectangle, but I do use this feature of the design pattern, for instance, to generically treat polygons and polygons with holes as polygons and allow holes to copy through automatically. Otherwise I would need two functions is places where I now have only one.
I'm looking for the boost community's feedback on what approach to rewriting the library they find preferable, and a sort of final decision on whether the generic inheritance/static_cast/mimicry design-pattern I came up with is unacceptable for acceptance into boost, implying that a complete rewrite is truly needed. Is the requirement that code never do anything the standard doesn't guarantee is safe, or is the requirement that code be portable and functional?
The absolute minimum requirement is that it should work on several platforms. I think that to the extent that is possible, code should only rely on what the standard guarantees. I believe that if you rely only on non-member functions and reinterpret_cast back and forth, it is possible to make the mimicry legal.
Can you explain that last part about relying on non-member functions and reinterpret_cast making it possible to be legal? Do you mean what I am already doing with non-member functions providing the interface? What exactly to you mean by legal? Do you mean legal syntax according to the compiler, or standard compliant syntax? The code compiles (and runs correctly) with gcc 3.2.2, 3.4.2, 4.2.2 and 4.3.0, icc 9.0 and 10.0, VC7 and VC8 and runs in ia32, EMT64 and itanium machines in Windows and linux. Other compilers, architectures and OS's should be for the most part OK, but I lack access to them to check. Is this is sufficient to meet the minimum requirement for portability? I would be very happy to keep the broader design as is and focus on naming conventions and more minor improvements such as using output iterators for results of algorithms instead of the less generic method of passing std container by reference. I also have a lot of work to do to bring the documentation up to date. Luke