Boost logo

Boost :

From: Bruno Lalande (bruno.lalande_at_[hidden])
Date: 2008-05-10 08:49:19

>> I know the principle of avoiding blob traits, as exposed in
>> Abrahams and Gurtovoy's book. But I think it doesn't apply
>> here just because the traits in question is *way* short. A
>> type, a value, an accessor.
>> And most algorithms need all of them. Does it really make
>> sense to scatter them into several metafunctions??
> Well, I wrote / suggested that because I have in mind a very generic set
> of concepts associated with points that would be compatible with
> libraries like CGAL.
> I am worried that the traits will explode becuase there are so many uses
> for a point class that have subtly different requirements. The number of
> associated types etc. in the CGAL Kernel seems to indicate that in a
> sturdy geometry library that might be the case.
> eg, it looks a little bit like a point concept will require a 'space'
> concept that will end up involving tons of associated types for
> compatible geometric primatives (as in the CGAL Kernel).

OK I agree with you that if the number of traits needed happens to
grow up, scattering them will be much better than having a blob traits
class. I don't know much about the CGAL kernel in its whole, I will
take a closer look.

>> I agree with Luke on this point, I'm afraid about nightmares
>> that overloading ambiguities could bring to the user.
>> However, I will consider doing a few tests to see the actual
>> consequences of what you propose.
> I am not talking about requiring user code to depend on ADL, I mean make
> a special 'adapted' namespace like fusion does. I foresee less problems
> with
> ::point::adapted::at_c<0>(point);
> than I do with
> point_traits<MyPoint>::template at_c<0>(point)
> This involves 2 parts:
> 1. _if_ the traits get to be huge, it is possible to split namespaces
> accross header files.
> 2. The annoying 'template' keyword can be a source of problems, since it
> has been my experience that some compilers require it and others dont. I
> am also concerned about the 'typename' keyword (for the same reason).
> Some traits will also probably apply to multiple concepts, and since you
> can't partially implement a traits class, you will have to mix them by
> inheritance (I think) if you want to share some traits. Then you end up
> with an issue about dependant names inherited from template base classes
> that happens on g++ and not microsoft compilers.

This is what I wanted to do to get rid of the template keyword and
take advantage of the template parameter deduction on the point type.
I wanted to merely implement it by forwarding things to the
point_traits written by the user, but maybe this approach will be
problematic (not tried yet). If it is, your approach will be a better
option, indeed. This request had already been made in another thread
so it will be done anyway.

>> >>4. Make all requirements explicit in the concept class. This
>> >> way I can look at the concept code and see what they are.
>> Aren't the requirements explicit enough in the concept class
>> I've shown? If not, could you be more precise on what you'd
>> like to see more clearly specified?
>> Bruno
> I was worried because somebody was talking about using the traits class
> to add additional constraints. In your posted code, I dont see the
> actual definition of a traits class (I see a 'dimension_checker', and I
> see a point_traits template being used...)

Yep precisely because the concept literally says "there must exist a
specialization of point_traits with X such that this code is valid".
It's finally as much a "point traits concept" as a "point concept".
Maybe it would be better to have X being the specialized point_traits?
It would require an additional point_type typedef in the point traits
and would give something like:

template <class X> // X is a point_traits
struct PointTraits
  typedef typename X::coordinate_type ctype;
  enum { ccount = X::coordinate_count };

  template <int I, int Count>
  struct dimension_checker
      static void check()
          const typename PT::point_type* point;
          ctype coord = X::template get<I>(*point);
          typename PT::point_type* point2;
          X::template get<I>(*point2) = coord;

          dimension_checker<I+1, Count>::check();

  template <int Count>
  struct dimension_checker<Count, Count>
      static void check() {}

      dimension_checker<0, ccount>::check();

Then, requirements inside algorithms would be done this way:

template <class P>
   ((PointTraits<point_traits<P> >)),
function_requiring_a_point(const P& p)

It doesn't sound clearer to me though... If it's not what you were
expecting, could you propose another concept definition?


Boost list run by bdawes at, gregod at, cpdaniel at, john at