Template specialization for Boost.Polygon

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Template specialization for Boost.Polygon

Boost - Users mailing list
Dear Experts,

This is a question about Boost.Polygon but please keep reading
even if you've never used that library as it's really just about
how to resolve ambiguous template specialisations.

Boost.Polygon has a mechanism by which you can tell it about
your own types by specialising templates.  I want to tell it that
std::array<Point,N> is a polygon, which I try to do like this:

  template <size_t N>
  struct geometry_concept< std::array<Point,N> >
  {
    using type = polygon_concept;
  };

  template <size_t N>
  struct polygon_traits< std::array<Point,N> >
  {  ....... };

This doesn't work because of ambiguity between that specialisation
of polygon_traits and a default specialization that is in the library
itself; the library code looks something like this:

  template <typename T, typename enable = gtl_yes>
  struct polygon_traits {};

  template <typename T>
  struct polygon_traits<T, ...some SFINAE stuff.... >
  { ......... };

If I try to just specialize one size of array it works:

  template <>
  struct polygon_traits< std::array<g2i::Point,3> >
  {  ....... };

The error is:

test_template_specialization.cc:64:19: error: ambiguous partial specializations of 'polygon_traits<std::__1::array<Point, 3>, boost::polygon::gtl_yes>'
  boost::polygon::polygon_traits<std::array<Point,3>>::iterator_type i = nullptr;
                  ^
/usr/local/include/boost/polygon/polygon_traits.hpp:100:10: note: partial specialization matches [with T = std::__1::array<Point, 3>]
  struct polygon_traits<T,
         ^
test_template_specialization.cc:32:8: note: partial specialization matches [with N = 3]
struct polygon_traits< std::array<Point,N> >
       ^

I have the same issue when I attempt to use a Point class that
takes the coordinate type as a template parameter.

Can anyone suggest how I can write my specialisations so that they
are unambiguous?

A complete test program follows.  I'm testing with Boost 1.69.0, but
I don't think anything has changed in Polygon since then.

Thanks, Phil.



#include <boost/polygon/polygon.hpp>
#include <array>

struct Point { int x; int y; };

namespace boost { namespace polygon {

template <>
struct geometry_concept<Point>
{
  using type = point_concept;
};

template <>
struct point_traits<Point>
{
  using coordinate_type = int;

  static inline coordinate_type get(const Point& point, orientation_2d orient)
  {
    return (orient==HORIZONTAL) ? point.x : point.y;
  }
};

template <size_t N>
struct geometry_concept< std::array<Point,N> >
{
  using type = polygon_concept;
};

template <size_t N>
struct polygon_traits< std::array<Point,N> >
{
  using coordinate_type = int;
  using iterator_type = typename std::array<Point,N>::const_iterator;
  using point_type = Point;

  static inline iterator_type begin_points(const std::array<Point,N>& p)
  {
    return p.begin();
  }

  static inline iterator_type end_points(const std::array<Point,N>& p)
  {
    return p.end();
  }

  static inline std::size_t size(const std::array<Point,N>&)
  {
    return N;
  }

  static inline winding_direction winding(const std::array<Point,N>&)
  {
    return unknown_winding;  // Hmm.
  }
};

}; };  // namespace boost, polygon


int main()
{
  boost::polygon::polygon_traits<std::array<Point,3>>::iterator_type i = nullptr;
  return 0;
}


_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Template specialization for Boost.Polygon

Boost - Users mailing list
On 8/26/19 5:39 PM, Phil Endecott via Boost-users wrote:

> Can anyone suggest how I can write my specialisations so that they
> are unambiguous?

By adding another level of indirection. Create your own trait template.
Let both the generalization and your specialization redirect to
polygon_traits.

Something like this (warning untested code ahead)

template <typename T, typename Enable = void>
struct my_polygon_traits
     : public polygon_traits<T, Enable>
{
};

template <std::size_t N>
struct my_polygon_traits<std::array<Point, N>>
     : public polygon_traits<std::array<Point, N>>
{
};
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Template specialization for Boost.Polygon

Boost - Users mailing list
Hi Bjorn,

Bjorn Reese wrote:

>> Can anyone suggest how I can write my specialisations so that they
>> are unambiguous?
>
> By adding another level of indirection. Create your own trait template.
> Let both the generalization and your specialization redirect to
> polygon_traits.
>
> Something like this (warning untested code ahead)
>
> template <typename T, typename Enable = void>
> struct my_polygon_traits
>      : public polygon_traits<T, Enable>
> {
> };
>
> template <std::size_t N>
> struct my_polygon_traits<std::array<Point, N>>
>      : public polygon_traits<std::array<Point, N>>
> {
> };


Forgive me if I have misunderstood, but how can that cause
Boost.Polygon to see my specialisation when it looks up
polygon_traits<std::array<Point,3>> ?


Regards, Phil.




_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Template specialization for Boost.Polygon

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
On 8/27/19 2:39 PM, Phil Endecott via Boost-users wrote:

> Forgive me if I have misunderstood, but how can that cause
> Boost.Polygon to see my specialisation when it looks up
> polygon_traits<std::array<Point,3>> ?

Sorry, I did not look into your particular details, but simply
described a general way of avoiding ambiguities.
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Template specialization for Boost.Polygon

Boost - Users mailing list
In reply to this post by Boost - Users mailing list
"Phil Endecott" <[hidden email]> writes:

> Forgive me if I have misunderstood, but how can that cause
> Boost.Polygon to see my specialisation when it looks up
> polygon_traits<std::array<Point,3>> ?

I had a similar problem.

As it turns out, Boost.Polygon already uses a level of indirection
internally. You can specialize boost_polygon_traits_general (instead of
boost_polygon_traits).

This is undocumented, but it was the only way I found to get it working.

I would argue this is a bug, or at least a deficiency. Not sure if the
right fix is to change the documentation or the implementation.

 - Pat
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Template specialization for Boost.Polygon

Boost - Users mailing list
Patrick J. LoPresti wrote:

> "Phil Endecott" <[hidden email]> writes:
>
>> Forgive me if I have misunderstood, but how can that cause
>> Boost.Polygon to see my specialisation when it looks up
>> polygon_traits<std::array<Point,3>> ?
>
> I had a similar problem.
>
> As it turns out, Boost.Polygon already uses a level of indirection
> internally. You can specialize boost_polygon_traits_general (instead of
> boost_polygon_traits).

THANKS!  Yes, that works.  It's a hack but I've done worse...

> This is undocumented, but it was the only way I found to get it working.
>
> I would argue this is a bug, or at least a deficiency. Not sure if the
> right fix is to change the documentation or the implementation.

It's clearly a misfeature.  Regarding fixing it, I have the impression
that Boost.Polygon is essentially abandoned.  Are you actively using it?
Anyone else out there?


Regards, Phil.




_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: Template specialization for Boost.Polygon

Boost - Users mailing list
On Wed, Aug 28, 2019 at 5:19 PM Phil Endecott wrote:
> It's clearly a misfeature.  Regarding fixing it, I have the impression
> that Boost.Polygon is essentially abandoned.  Are you actively using it?
> Anyone else out there?

It has a semi active maintainer who is also a co-author (Andrii
Sydorchuk). It does have active users; some submit pull requests too.

Glen
_______________________________________________
Boost-users mailing list
[hidden email]
https://lists.boost.org/mailman/listinfo.cgi/boost-users