Weird compilation error when using boost::geometry

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Weird compilation error when using boost::geometry

邓尧
Hi,

I have implemented my own "point" as specified by the point concept http://www.boost.org/doc/libs/1_59_0/libs/geometry/doc/html/geometry/reference/concepts/concept_point.html
When I use it along with boost::geometry::model::polygon/multi_polygon, GCC refuses to compile, tested on GCC 4.9/5.2. What's even more weird is that CLANG 3.6 would happy accept my code.

BTW, the Point implementation is part of a large project, it difficult to replace it with boost::geometry::model::point.

Here is my code: Point.hpp
#ifndef RAPTOR_POINT_HPP_INCLUDED_
#define RAPTOR_POINT_HPP_INCLUDED_

#include <boost/mpl/int.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/multi/geometries/multi_polygon.hpp>

namespace raptor {

template<typename T, int tDimension = 2>
class Point {
public:
Point() = default;

Point(T a, T b) {
data[0] = a;
data[1] = b;
}

Point(T a, T b, T c) {
data[0] = a;
data[1] = b;
data[2] = c;
}

T& operator [] (long index) {
return data[index];
}

const T& operator [] (long index) const {
return data[index];
}

private:
T data[tDimension];
};

using CubicPoint = Point<long, 3>;
using PlanarPoint = Point<long>;
using SphericalPoint = Point<double>;

template<typename T>
using Polygon = boost::geometry::model::polygon<T>;

template<typename T>
using PolySet = boost::geometry::model::multi_polygon<Polygon<T>>;

} // namespace raptor

namespace boost { namespace geometry { namespace traits {

template<typename Type, std::size_t tDimension>
struct tag<::raptor::Point<Type, tDimension>> {
typedef point_tag type;
};

template<typename Type, std::size_t tDimension>
struct coordinate_type<::raptor::Point<Type, tDimension>> {
typedef Type type;
};

template<typename Type, std::size_t tDimension>
struct coordinate_system<::raptor::Point<Type, tDimension>> {
typedef boost::geometry::cs::cartesian type;
};

template<typename Type, std::size_t tDimension>
struct dimension<::raptor::Point<Type, tDimension>>
: public boost::mpl::int_<tDimension> {
// EMPTY
};

template<typename Type, std::size_t tDimension, std::size_t tIndex>
struct access<::raptor::Point<Type, tDimension>, tIndex> {
static Type get(const ::raptor::Point<Type, tDimension>& p) {
return p[tIndex];
}

static void set(::raptor::Point<Type, tDimension>& p,
const Type& value) {
p[tIndex] = value;
}
};

}}} // namespace boost::geometry::traits

#endif // RAPTOR_POINT_HPP_INCLUDED_  
 
A real simple main.cpp: 
#include "Point.hpp"

int main() {
raptor::Polygon<raptor::SphericalPoint> pl;
raptor::PolySet<raptor::SphericalPoint> set;
return sizeof(pl) + sizeof(set);
}

 
GCC compilation error:  g++ main.cpp -std=c++14
In file included from /usr/include/boost/geometry/core/access.hpp:20:0,
                 from Point.hpp:5,
                 from main.cpp:1:
/usr/include/boost/geometry/core/point_type.hpp: In instantiation of 'struct boost::geometry::traits::point_type<raptor::Point<double> >':
/usr/include/boost/geometry/core/point_type.hpp:66:17:   required from 'struct boost::geometry::core_dispatch::point_type<void, raptor::Point<double> >'
/usr/include/boost/geometry/core/coordinate_type.hpp:58:62:   required from 'struct boost::geometry::core_dispatch::coordinate_type<void, raptor::Point<double> >'
/usr/include/boost/geometry/core/coordinate_type.hpp:92:25:   required from 'struct boost::geometry::coordinate_type<raptor::Point<double> >'
/usr/include/boost/geometry/geometries/concepts/point_concept.hpp:90:54:   required from 'class boost::geometry::concept::Point<raptor::Point<double> >'
/usr/include/boost/concept/detail/has_constraints.hpp:32:62:   required by substitution of 'template<class Model> boost::concepts::detail::yes boost::concepts::detail::has_constraints_(Model*, boost::concepts::detail::wrap_constraints<Model, (& Model:: constraints)>*) [with Model = boost::geometry::concept::Point<raptor::Point<double> >]'
/usr/include/boost/concept/detail/has_constraints.hpp:42:5:   required from 'const bool boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double> > >::value'
/usr/include/boost/concept/detail/has_constraints.hpp:45:31:   required from 'struct boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double> > >'
/usr/include/boost/mpl/if.hpp:67:11:   required from 'struct boost::mpl::if_<boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double> > >, boost::concepts::constraint<boost::geometry::concept::Point<raptor::Point<double> > >, boost::concepts::requirement<boost::concepts::failed************ boost::geometry::concept::Point<raptor::Point<double> >::************> >'
/usr/include/boost/concept/detail/general.hpp:50:8:   required from 'struct boost::concepts::requirement_<void (*)(boost::geometry::concept::Point<raptor::Point<double> >)>'
/usr/include/boost/geometry/geometries/ring.hpp:60:5:   required from 'class boost::geometry::model::polygon<raptor::Point<double>, true, true, std::vector, std::vector, std::allocator, std::allocator>'
main.cpp:4:42:   required from here
/usr/include/boost/geometry/core/point_type.hpp:45:5: error: no matching function for call to 'assertion_failed(mpl_::failed************ (boost::geometry::traits::point_type<raptor::Point<double> >::NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE::************)(mpl_::assert_::types<raptor::Point<double>, mpl_::na, mpl_::na, mpl_::na>))'
     BOOST_MPL_ASSERT_MSG
     ^
/usr/include/boost/mpl/assert.hpp:82:5: note: candidate: template<bool C> int mpl_::assertion_failed(typename mpl_::assert<C>::type)
 int assertion_failed( typename assert<C>::type );
     ^
/usr/include/boost/mpl/assert.hpp:82:5: note:   template argument deduction/substitution failed:
/usr/include/boost/geometry/core/point_type.hpp:45:5: note:   cannot convert 'boost::geometry::traits::point_type<Geometry>::NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE48::assert_arg<raptor::Point<double> >()' (type 'mpl_::failed************ (boost::geometry::traits::point_type<raptor::Point<double> >::NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE::************)(mpl_::assert_::types<raptor::Point<double>, mpl_::na, mpl_::na, mpl_::na>)') to type 'mpl_::assert<false>::type {aka mpl_::assert<false>}'
     BOOST_MPL_ASSERT_MSG
     ^
In file included from /usr/include/boost/geometry/core/coordinate_type.hpp:21:0,
                 from /usr/include/boost/geometry/core/access.hpp:24,
                 from Point.hpp:5,
                 from main.cpp:1:
/usr/include/boost/geometry/core/point_type.hpp: In instantiation of 'struct boost::geometry::core_dispatch::point_type<void, raptor::Point<double> >':
/usr/include/boost/geometry/core/coordinate_type.hpp:58:62:   required from 'struct boost::geometry::core_dispatch::coordinate_type<void, raptor::Point<double> >'
/usr/include/boost/geometry/core/coordinate_type.hpp:92:25:   required from 'struct boost::geometry::coordinate_type<raptor::Point<double> >'
/usr/include/boost/geometry/geometries/concepts/point_concept.hpp:90:54:   required from 'class boost::geometry::concept::Point<raptor::Point<double> >'
/usr/include/boost/concept/detail/has_constraints.hpp:32:62:   required by substitution of 'template<class Model> boost::concepts::detail::yes boost::concepts::detail::has_constraints_(Model*, boost::concepts::detail::wrap_constraints<Model, (& Model:: constraints)>*) [with Model = boost::geometry::concept::Point<raptor::Point<double> >]'
/usr/include/boost/concept/detail/has_constraints.hpp:42:5:   required from 'const bool boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double> > >::value'
/usr/include/boost/concept/detail/has_constraints.hpp:45:31:   required from 'struct boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double> > >'
/usr/include/boost/mpl/if.hpp:67:11:   required from 'struct boost::mpl::if_<boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double> > >, boost::concepts::constraint<boost::geometry::concept::Point<raptor::Point<double> > >, boost::concepts::requirement<boost::concepts::failed************ boost::geometry::concept::Point<raptor::Point<double> >::************> >'
/usr/include/boost/concept/detail/general.hpp:50:8:   required from 'struct boost::concepts::requirement_<void (*)(boost::geometry::concept::Point<raptor::Point<double> >)>'
/usr/include/boost/geometry/geometries/ring.hpp:60:5:   required from 'class boost::geometry::model::polygon<raptor::Point<double>, true, true, std::vector, std::vector, std::allocator, std::allocator>'
main.cpp:4:42:   required from here
/usr/include/boost/geometry/core/point_type.hpp:66:17: error: no type named 'type' in 'struct boost::geometry::traits::point_type<raptor::Point<double> >'
         >::type type;
                 ^
In file included from /usr/include/boost/geometry/geometries/polygon.hpp:26:0,
                 from Point.hpp:10,
                 from main.cpp:1:
/usr/include/boost/geometry/geometries/concepts/point_concept.hpp: In instantiation of 'class boost::geometry::concept::Point<raptor::Point<double> >':
/usr/include/boost/concept/detail/has_constraints.hpp:32:62:   required by substitution of 'template<class Model> boost::concepts::detail::yes boost::concepts::detail::has_constraints_(Model*, boost::concepts::detail::wrap_constraints<Model, (& Model:: constraints)>*) [with Model = boost::geometry::concept::Point<raptor::Point<double> >]'
/usr/include/boost/concept/detail/has_constraints.hpp:42:5:   required from 'const bool boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double> > >::value'
/usr/include/boost/concept/detail/has_constraints.hpp:45:31:   required from 'struct boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double> > >'
/usr/include/boost/mpl/if.hpp:67:11:   required from 'struct boost::mpl::if_<boost::concepts::not_satisfied<boost::geometry::concept::Point<raptor::Point<double> > >, boost::concepts::constraint<boost::geometry::concept::Point<raptor::Point<double> > >, boost::concepts::requirement<boost::concepts::failed************ boost::geometry::concept::Point<raptor::Point<double> >::************> >'
/usr/include/boost/concept/detail/general.hpp:50:8:   required from 'struct boost::concepts::requirement_<void (*)(boost::geometry::concept::Point<raptor::Point<double> >)>'
/usr/include/boost/geometry/geometries/ring.hpp:60:5:   required from 'class boost::geometry::model::polygon<raptor::Point<double>, true, true, std::vector, std::vector, std::allocator, std::allocator>'
main.cpp:4:42:   required from here
/usr/include/boost/geometry/geometries/concepts/point_concept.hpp:93:10: error: 'value' is not a member of 'boost::geometry::dimension<raptor::Point<double> >'
     enum { ccount = dimension<Geometry>::value };
          ^
 

Where is the problem ? or it's a GCC bug ? 

Thanks

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

Re: Weird compilation error when using boost::geometry

Adam Wulkiewicz
Hi,

2015-09-19 8:08 GMT+02:00 邓尧 <[hidden email]>:


template<typename T, int tDimension = 2>
class Point {

<snip>


template<typename Type, std::size_t tDimension>
struct tag<::raptor::Point<Type, tDimension>> {
typedef point_tag type;
};


Different integral types are used for tDimension in Point class and traits specializations, after changing e.g. int to std::size_t in Point class the code compiles.

Regards,
Adam

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

Re: Weird compilation error when using boost::geometry

Boost - Users mailing list
Hi Adam,

is there any other way around/through this? I am working with a point geometry with the same issue: the template type for dimensions is 'int' and it would be a lot of hassle to change it.

Thanks, cheers.

Jeremy


On 4 October 2015 at 04:16, Adam Wulkiewicz <[hidden email]> wrote:
Hi,

2015-09-19 8:08 GMT+02:00 邓尧 <[hidden email]>:


template<typename T, int tDimension = 2>
class Point {

<snip>


template<typename Type, std::size_t tDimension>
struct tag<::raptor::Point<Type, tDimension>> {
typedef point_tag type;
};


Different integral types are used for tDimension in Point class and traits specializations, after changing e.g. int to std::size_t in Point class the code compiles.

Regards,
Adam

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


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

Re: Weird compilation error when using boost::geometry

Boost - Users mailing list
Hi Jeremy,

Jeremy Murphy wrote:
is there any other way around/through this? I am working with a point geometry with the same issue: the template type for dimensions is 'int' and it would be a lot of hassle to change it.


The type in trait specialization has to be specified correctly. So assuming that you don't want to change the geometry template you should change the specialization, like this:

    template<typename T, int tDimension = 2>
    class Point {};

    // ...

    template<typename Type, int tDimension>
    struct tag<Point<Type, tDimension>> {
        typedef point_tag type;
    };

Adam



On 4 October 2015 at 04:16, Adam Wulkiewicz <[hidden email]> wrote:
Hi,

2015-09-19 8:08 GMT+02:00 邓尧 <[hidden email]>:


template<typename T, int tDimension = 2>
class Point {

<snip>


template<typename Type, std::size_t tDimension>
struct tag<::raptor::Point<Type, tDimension>> {
typedef point_tag type;
};


Different integral types are used for tDimension in Point class and traits specializations, after changing e.g. int to std::size_t in Point class the code compiles.

Regards,
Adam

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



 


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

Re: Weird compilation error when using boost::geometry

Boost - Users mailing list


On 15 November 2017 at 22:28, Adam Wulkiewicz <[hidden email]> wrote:
Hi Jeremy,

Jeremy Murphy wrote:
is there any other way around/through this? I am working with a point geometry with the same issue: the template type for dimensions is 'int' and it would be a lot of hassle to change it.


The type in trait specialization has to be specified correctly. So assuming that you don't want to change the geometry template you should change the specialization, like this:

    template<typename T, int tDimension = 2>
    class Point {};

    // ...

    template<typename Type, int tDimension>
    struct tag<Point<Type, tDimension>> {
        typedef point_tag type;
    };

Adam


Thanks, Adam, that worked a treat.
Cheers.

Jeremy


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