Boost logo

Boost :

From: Simonson, Lucanus J (lucanus.j.simonson_at_[hidden])
Date: 2008-05-06 13:22:27


Simonson, Lucanus J wrote:
>> I've been working on an idea for using some compile time concept type
>> introspection and tag dispatching to allow generically named free
>> functions (such as contains()) to compile and work in user code when
>> called with any sensible combination of geometry types. This should
>> make user code much more concise than with my current design; all the
>> concept related boilerplate can be dispensed with.
>> Do you guys prefer this scheme to what I showed in example3.cpp?
>>
Steven Watanabe replied:
>I haven't looked at your code yet, but it feels sound. This is
>basically how fusion, MPL, &c. work, BTW.

I thought of another problem with the tag dispatching scheme for making
everything free functions. The difficulty was that often the return
value of a function should depend upon the types passed into it. I
solve this problem with SFINAE to overload, for example, the get()
function to return a coordinate when called with a point type and to
return an interval when called with a rectangle type. (The
horizontal-axis component of a rectangle is an interval from low x to
high x values.) This allows different coordinate types to be the return
value when get is called on different objects of the same conceptual
type and completely different types when the get function is called on
dissimilar types. I added a return type to the geometry traits with a
different name for each conceptual type and then look it up for the
return value of overloaded versions of get. If it isn't specified in
the specialization of geometry_traits for the given type that is
substitution failure, and the compiler selects the other version of get.
See code snippet below.

Thanks,
Luke

struct no_type {};

template <typename T>
struct geometry_traits {
  typedef no_type geometry_concept;
};

template <>
struct geometry_traits<point_data<int> > {
  typedef point_concept geometry_concept;
  typedef int point_get_retval;
};

template <>
struct geometry_traits<point_data<long long> > {
  typedef point_concept geometry_concept;
  typedef long long point_get_retval;
};

template <>
struct geometry_traits<rectangle_data<int> > {
  typedef rectangle_concept geometry_concept;
  typedef interval_data<int> rectangle_get_retval;
};

template <>
struct geometry_traits<rectangle_data<long long> > {
  typedef rectangle_concept geometry_concept;
  typedef interval_data<long long> rectangle_get_retval;
};

template <typename point_type>
typename geometry_traits<point_type>::point_get_retval
get(const point_type& point, orientation_2d orient) {
  return point_concept::get(point, orient);
}

template <typename rectangle_type>
typename geometry_traits<rectangle_type>::rectangle_get_retval
get(const rectangle_type& rectangle, orientation_2d orient) {
  return rectangle_concept::get(rectangle, orient);
}

void foo() {
  get(point, HORIZONTAL);
  get(rect1, HORIZONTAL);
  get(rect3, HORIZONTAL);
}


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