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.htmlWhen 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