Subject: Re: [boost] Proposal/InterestCheck: Boost.Geom
From: Anis Benyelloul (anis.benyelloul_at_[hidden])
Date: 2009-01-28 08:12:41


Simonson, Lucanus J <lucanus.j.simonson <at> intel.com> writes:

>
> > bx.center() = point(0,0); // this will ``move'' the box so that it's
> > // center is at the origin
> This is very clever, does center() generate an object that casts to point, but
> caches a reference to the box and implements an assignment operator that
> modifies box? What an interesting idea.

I could have done it that way, but I didn't want to pay for an extra temporary
object. So what it does is to return a ref to the _box itself_ (i.e `this') but
wrapped behind a point interface. In fact, this uses the same mechanism that
lets you wrap a QPoint/wxPoint/XPOINT/POINT... behind a geom::point<> (but see
below).

The corner() mechanism is also implemented this way.
 
> I would assume that bx.center() returns a point by value,

Yeah, but what about this:

point pt;

pt.x()=10; // ????

Well, for simple properties like X, Y, Z most people will read the above line as
``assign 10 to the X property of pt''. What I wanted to do is to keep the
consistency and be able to write:

box bx;

bx.center()=pt; // Assign pt to the `center' property of box.

All the code revolves around this idea of abstractions and properties.

> Rich seems like a less subjective term than pretty, since it implies quantity.
Yes

 
> struct A {};
> struct B { A a; void bar(); };
> void foo() {
> A a;
> B b;
> B& B_view_of_A = *((B*)&(a)); //result of cast is undefined,
> but generally works because B is the same in
> memory as A is most compilers
> B_view_of_A.bar();
> }

I'm not sure about this either... I thought since those are non-polymorphic
types, they have to be compatible with C, and C doesn't allow a compiler to
add any funny pointer to virtual tables or such to structs....

> template <typename T>
> boost::enable_if<is_box_like<T>::type, point>::type
> center(T& obj);
>
> This definition of center can accept an A directly without need of wrapping it.

Wrapping is not needed when you want to pass agruments to the library.

POINT pt1;
geom::point<POINT> pt2; pt2=pt1; // Assign geom::point = POINT works

Wrapping is needed when you have a POINT a you need to work with it behind a
geom::point<>. It is of course possible to copy to a geom::point and then copy
the results back...

> I got around it by making point conform to the default expectation of the
> point_traits so that you could recursively call traits until you got down to
> the base level. Since there are no wrappers in the concepts based
> implementation I don't have such a problem anymore.

What I do is to first unwrap a type such as point < point < point_impl > > to
get the point_impl inside, then I pass that to point_traits.

> It should not be necessary to use traits to provide type specific
> optimizations.
>... This is somewhat more direct than providing for the ability to use a user
>defined trait for every behavior of

Yeah, but my idea was to keep the ``user customizable parts'' apart from the
non-``user cutomizable parts'' of the library... but that's an idea.

> We did a lot of analysis, and in real code the compiler often failed to inline
> the simple accessor functions that it always inlined in toy test cases.

Yes, I understand.

PS. I hear lots of people in this thread talking about their own ideas in this
domain but I find it hard to find each person's proposition/code (latest
versions, and documentation when available), if everyone could provide links to
their work it would be great.

Reguards,