Boost logo

Boost :

From: Simonson, Lucanus J (lucanus.j.simonson_at_[hidden])
Date: 2008-05-01 13:46:42


Phil wrote:
>You should be able to express this something like "Type T models the
>Point Concept if there exists a specialisation point_interface<T>
>having members ....". Can you write a definition like that?

As it stands right now:
Type T models the Point concept if it is default constructable, copy
constructable and there exists a specialization of PointInterface<T>
having the members:
static Unit pointGet(const T& t, Orientation2D orient);
static void pointSet(T& t, Orientatino2D orient, Unit value);
static T pointConstruct(Unit x, Unit y);

Except for capitalization, I would keep this portion of the library the
same (I like runtime resolution of getting x or y value and depend on
compiler constant propagation and optimization to provide fast access if
orient is known at compile time.) Orientation2D is a class-encapsulated
enum to enforce compile time checking that index values are legal.

Phil wrote:
>I think it would be an interesting thought-experiment to consider how
>the standard library would look if re-written in this style, e.g. not
>using std::pair in maps.
>There are three groups of people affected:
>- Users with legacy code, who benefit.
>- Users without legacy code, who have a (perhaps small) extra step on
>their learning curve.
>- People writing libraries, who have more work to do.

Users without legacy code have the option of either using the geometry
types provided by the library or defining their own that match the
expectations of the default (non-specialized version) of the interface.
This should offset the added complexity of the extra layer of
abstraction to a large degree. I have found new users starting from
scratch to be generally happier using GTL than the users with legacy
code.

I always consider doing work as a library author to safe work for the
library user to be a win. I don't see how I create work for people
writing other libraries, since they have the option us conforming to the
default interface.

Bruno wrote:
>The point concept of Barend's library doesn't require any x() or y()
>member functions. The fact that the library proposes 2 predefined
>point classes, point_xy and point_ll, can be a bit confusing but don't
>be fooled: they do *not* represent the point concept, they are only 2
>classes that satisfy it. The point concept uses accessors of this kind
>: template <int I> value() const;

That looks much better to me. I didn't follow Barend's thread closely
enough, I was unsubscribed at the time.

Bruno wrote:
>In the second preview of the library, there was also runtime indexing
>accessors, but they should disappear to only have compile-time
>accessors as shown above (I'm currently working on this with Barend).

There is no need to have both run time and compile time accessors, and
you can do things with run time accessors that you cannot do with
compile time accessors. The reverse is not true. I think you made the
wrong decision and should consider making the accessors runtime only
instead.
The way my accessors work is that I pass a class-encapsulated enum
value, which, if the data type is particularly well formed, can be used
to index directly into an array of member data. This turns out to be
just as fast (when optimized) as direct access to a data member when the
index is known at compile time and faster if the index is a runtime
variable.
Consider the difference between:

int get(array<int, 2> point, int index) { return point[index]; }

and

int get(const tuple<int, int>& point, int index) {
        if(index==0) return get<0>(point); else return get<1>(point); }

If you want to be passing the index around as data you don't want it to
be a compile time parameter. I want to pass it around as data. I want
my point to be a class-encapsulated array.
 
Bruno wrote:
>Also, the point concept as currently defined might be replaced by a
>point_traits class usable the same way as what you propose with your
>point_interface<T>. It gives something like :
>point_traits<T>::value<0>(p) to have the first coordinate of a point
>p. The point concept would then follow the exact definition just given
>by Phil. Not sure yet this will be done, but it brings a lot of
>advantages (non-intrusiveness, possibility of using native arrays as
>points, ...).

I have thought about changing the name to traits. For more complex
types, such as polygons, there are typedefs in the interface for
iterators, and sometimes entire classes defined to adapt a polygon data
type to iterator range semantics.
The new pattern might look like:

template <class T> class point_traits {
public:
        typedef T::coordinate_type coordinate_type;
        static inline coordinate_type get(const T& t, Orientation2D
orient) {
                return T.get(orient);
        }
        static inline void set(T& t, Orientation2D orient,
                                        coordinate_type value) {
                t.set(orient, value);
        }
        static inline T construct(coordinate_type x, coordinate_type y)
{
                return T(x, y);
        }
};

which can be partially specialized to allow legacy types to work with
the library.

Hartmut wrote:
>Joel explicitly alluded to that in the first discussion and
>I think there is no other way forward. ... And - anything not
conformant to >the Standard shouldn't even be considered
>as a Boost library, IMHO

Yes, Joel did suggest compile time accessors, and tuples in the first
discussion. A point can be a tuple; it doesn't have to be.
Heterogeneous coordinate types for different axis' coordinate values is
reasonable, and provided that they all provide conversion to and from
the library's coordinate type they work fine. I have been trying to
figure out how to make templating the coordinate data type (everywhere)
work, and it provides some advantages, but adds a lot of complexity. It
would be even worse if I tried to have separate x_coordinate_type and
y_coordinate_type.

I'm fine with changing the library (even big changes) to make it
conformant to the Standard. I said so when I first posted my code to
the vault. Some of my internal install base is even willing to port
their code to a new "boost-ified" version, if it comes to that. I think
doing so would constitute and improvement.

Luke


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk