diff --git a/include/boost/geometry/algorithms/append.hpp b/include/boost/geometry/algorithms/append.hpp index 7675aeccd..e5b93d314 100644 --- a/include/boost/geometry/algorithms/append.hpp +++ b/include/boost/geometry/algorithms/append.hpp @@ -238,8 +238,6 @@ struct append { traits::visit::apply([&](auto & g) { - concepts::check>(); - append < std::remove_reference_t, RangeOrPoint @@ -273,6 +271,8 @@ template inline void append(Geometry& geometry, RangeOrPoint const& range_or_point, signed_size_type ring_index = -1, signed_size_type multi_index = 0) { + concepts::check(); + dispatch::append < Geometry, RangeOrPoint diff --git a/include/boost/geometry/algorithms/area.hpp b/include/boost/geometry/algorithms/area.hpp index 48dd0b567..e263891cc 100644 --- a/include/boost/geometry/algorithms/area.hpp +++ b/include/boost/geometry/algorithms/area.hpp @@ -19,7 +19,6 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_AREA_HPP #define BOOST_GEOMETRY_ALGORITHMS_AREA_HPP -#include #include #include #include diff --git a/include/boost/geometry/algorithms/length.hpp b/include/boost/geometry/algorithms/length.hpp index 98231d0c1..6a932ae48 100644 --- a/include/boost/geometry/algorithms/length.hpp +++ b/include/boost/geometry/algorithms/length.hpp @@ -22,7 +22,6 @@ #include -#include #include #include #include diff --git a/include/boost/geometry/geometries/concepts/dynamic_geometry_concept.hpp b/include/boost/geometry/geometries/concepts/dynamic_geometry_concept.hpp index f10558ddf..e1a1fc472 100644 --- a/include/boost/geometry/geometries/concepts/dynamic_geometry_concept.hpp +++ b/include/boost/geometry/geometries/concepts/dynamic_geometry_concept.hpp @@ -11,12 +11,16 @@ #define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_DYNAMIC_GEOMETRY_CONCEPT_HPP +#include + #include #include +#include #include #include +#include #include #include #include @@ -27,29 +31,46 @@ #include #include -#include - namespace boost { namespace geometry { namespace concepts { +namespace detail +{ + +template +struct GeometryType + : concepts::concept_type::type +{ +#ifndef DOXYGEN_NO_CONCEPT_MEMBERS + BOOST_CONCEPT_USAGE(GeometryType) + { + Geometry* dg = nullptr; + SubGeometry* sg = nullptr; + *dg = std::move(*sg); + } +#endif // DOXYGEN_NO_CONCEPT_MEMBERS +}; + +template +struct GeometryType + : concepts::concept_type::type +{}; + + +} // namespace detail + + template -class DynamicGeometry +struct DynamicGeometry { #ifndef DOXYGEN_NO_CONCEPT_MEMBERS using sequence_t = typename traits::geometry_types::type; - using first_t = typename util::sequence_front::type; - BOOST_CONCEPT_ASSERT( (typename concepts::concept_type::type) ); - -public: + BOOST_CONCEPT_ASSERT((detail::GeometryTypes)); BOOST_CONCEPT_USAGE(DynamicGeometry) { - Geometry* dg = 0; - first_t* g = 0; - - *dg = *g; - + Geometry* dg = nullptr; traits::visit::apply([](auto &&) {}, *dg); } #endif // DOXYGEN_NO_CONCEPT_MEMBERS @@ -57,19 +78,15 @@ public: template -class ConstDynamicGeometry +struct ConstDynamicGeometry { #ifndef DOXYGEN_NO_CONCEPT_MEMBERS using sequence_t = typename traits::geometry_types::type; - using first_t = typename util::sequence_front::type; - BOOST_CONCEPT_ASSERT( (typename concepts::concept_type::type) ); - -public: + BOOST_CONCEPT_ASSERT((detail::GeometryTypes)); BOOST_CONCEPT_USAGE(ConstDynamicGeometry) { - Geometry const* dg = 0; - + Geometry const* dg = nullptr; traits::visit::apply([](auto &&) {}, *dg); } #endif // DOXYGEN_NO_CONCEPT_MEMBERS diff --git a/include/boost/geometry/geometries/concepts/geometry_collection_concept.hpp b/include/boost/geometry/geometries/concepts/geometry_collection_concept.hpp index b0dd8edcd..0c40ab320 100644 --- a/include/boost/geometry/geometries/concepts/geometry_collection_concept.hpp +++ b/include/boost/geometry/geometries/concepts/geometry_collection_concept.hpp @@ -11,14 +11,19 @@ #define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_GEOMETRY_COLLECTION_CONCEPT_HPP +#include + #include #include #include #include +#include +#include #include #include +#include #include #include #include @@ -35,30 +40,81 @@ namespace boost { namespace geometry { namespace concepts { -template -class GeometryCollection +namespace detail +{ + +template +< + typename Geometry, + typename SubGeometry, + typename Tag = typename tag::type, + bool IsSubDynamicOrCollection = util::is_dynamic_geometry::value + || util::is_geometry_collection::value +> +struct GeometryType; + +// Prevent recursive concept checking +template +struct GeometryType {}; + +template +struct GeometryType {}; + + +template +struct GeometryType + : concepts::concept_type::type { #ifndef DOXYGEN_NO_CONCEPT_MEMBERS - BOOST_CONCEPT_ASSERT( (boost::ForwardRangeConcept) ); + BOOST_CONCEPT_USAGE(GeometryType) + { + Geometry* gc = nullptr; + SubGeometry* sg = nullptr; + traits::emplace_back::apply(*gc, std::move(*sg)); + } +#endif // DOXYGEN_NO_CONCEPT_MEMBERS +}; +template +struct GeometryType + : concepts::concept_type::type +{}; + + +template +struct GeometryTypesPack {}; + +template +struct GeometryTypesPack + : GeometryTypesPack + , GeometryType +{}; + + +template +struct GeometryTypes; + +template +struct GeometryTypes> + : GeometryTypesPack +{}; + + +} // namespace detail + + +template +struct GeometryCollection + : boost::ForwardRangeConcept +{ +#ifndef DOXYGEN_NO_CONCEPT_MEMBERS using sequence_t = typename traits::geometry_types::type; - using first_t = typename util::sequence_front::type; - // NOTE: It is possible to relax this requirement. - BOOST_GEOMETRY_STATIC_ASSERT((! util::is_geometry_collection::value), - "The first type can't be a geometry collection.", - Geometry); - BOOST_CONCEPT_ASSERT( (typename concepts::concept_type::type) ); - -public: + BOOST_CONCEPT_ASSERT( (detail::GeometryTypes) ); BOOST_CONCEPT_USAGE(GeometryCollection) { - Geometry* gc = 0; - first_t* g = 0; - - traits::clear::apply(*gc); - traits::emplace_back::apply(*gc, *g); - + Geometry* gc = nullptr; + traits::clear::apply(*gc); traits::iter_visit::apply([](auto &&) {}, boost::begin(*gc)); } #endif // DOXYGEN_NO_CONCEPT_MEMBERS @@ -66,25 +122,16 @@ public: template -class ConstGeometryCollection +struct ConstGeometryCollection + : boost::ForwardRangeConcept { #ifndef DOXYGEN_NO_CONCEPT_MEMBERS - BOOST_CONCEPT_ASSERT( (boost::ForwardRangeConcept) ); - using sequence_t = typename traits::geometry_types::type; - using first_t = typename util::sequence_front::type; - // NOTE: It is possible to relax this requirement. - BOOST_GEOMETRY_STATIC_ASSERT((! util::is_geometry_collection::value), - "The first type can't be a geometry collection.", - Geometry); - BOOST_CONCEPT_ASSERT( (typename concepts::concept_type::type) ); - -public: + BOOST_CONCEPT_ASSERT( (detail::GeometryTypes) ); BOOST_CONCEPT_USAGE(ConstGeometryCollection) { - Geometry const* gc = 0; - + Geometry const* gc = nullptr; traits::iter_visit::apply([](auto &&) {}, boost::begin(*gc)); } #endif // DOXYGEN_NO_CONCEPT_MEMBERS