summaryrefslogtreecommitdiff
path: root/boost/geometry/geometries/concepts/geometry_collection_concept.hpp
blob: 7d232c145fd082f2ef223b07b36e39ad9309b0e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
// Boost.Geometry

// Copyright (c) 2021, Oracle and/or its affiliates.

// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle

// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html

#ifndef BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_GEOMETRY_COLLECTION_CONCEPT_HPP
#define BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_GEOMETRY_COLLECTION_CONCEPT_HPP


#include <utility>

#include <boost/concept_check.hpp>
#include <boost/range/concepts.hpp>

#include <boost/geometry/core/geometry_types.hpp>
#include <boost/geometry/core/mutable_range.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/visit.hpp>

#include <boost/geometry/geometries/concepts/box_concept.hpp>
#include <boost/geometry/geometries/concepts/concept_type.hpp>
#include <boost/geometry/geometries/concepts/linestring_concept.hpp>
#include <boost/geometry/geometries/concepts/multi_point_concept.hpp>
#include <boost/geometry/geometries/concepts/multi_linestring_concept.hpp>
#include <boost/geometry/geometries/concepts/multi_polygon_concept.hpp>
#include <boost/geometry/geometries/concepts/point_concept.hpp>
#include <boost/geometry/geometries/concepts/polygon_concept.hpp>
#include <boost/geometry/geometries/concepts/ring_concept.hpp>
#include <boost/geometry/geometries/concepts/segment_concept.hpp>

#include <boost/geometry/util/sequence.hpp>
#include <boost/geometry/util/type_traits.hpp>


namespace boost { namespace geometry { namespace concepts
{

namespace detail
{

template
<
    typename Geometry,
    typename SubGeometry,
    typename Tag = typename tag<Geometry>::type,
    bool IsSubDynamicOrCollection = util::is_dynamic_geometry<SubGeometry>::value
                                 || util::is_geometry_collection<SubGeometry>::value
>
struct GeometryType;

// Prevent recursive concept checking
template <typename Geometry, typename SubGeometry, typename Tag>
struct GeometryType<Geometry, SubGeometry, Tag, true> {};

template <typename Geometry, typename SubGeometry, typename Tag>
struct GeometryType<Geometry const, SubGeometry, Tag, true> {};


template <typename Geometry, typename SubGeometry>
struct GeometryType<Geometry, SubGeometry, geometry_collection_tag, false>
    : concepts::concept_type<SubGeometry>::type
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
    BOOST_CONCEPT_USAGE(GeometryType)
    {
        Geometry* gc = nullptr;
        SubGeometry* sg = nullptr;
        traits::emplace_back<Geometry>::apply(*gc, std::move(*sg));
    }
#endif // DOXYGEN_NO_CONCEPT_MEMBERS
};

template <typename Geometry, typename SubGeometry>
struct GeometryType<Geometry const, SubGeometry, geometry_collection_tag, false>
    : concepts::concept_type<SubGeometry const>::type
{};


template <typename Geometry, typename ...SubGeometries>
struct GeometryTypesPack {};

template <typename Geometry, typename SubGeometry, typename ...SubGeometries>
struct GeometryTypesPack<Geometry, SubGeometry, SubGeometries...>
    : GeometryTypesPack<Geometry, SubGeometries...>
    , GeometryType<Geometry, SubGeometry>
{};


template <typename Geometry, typename SubGeometriesSequence>
struct GeometryTypes;

template <typename Geometry, typename ...SubGeometries>
struct GeometryTypes<Geometry, util::type_sequence<SubGeometries...>>
    : GeometryTypesPack<Geometry, SubGeometries...>
{};


} // namespace detail


template <typename Geometry>
struct GeometryCollection
    : boost::ForwardRangeConcept<Geometry>
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
    using sequence_t = typename traits::geometry_types<Geometry>::type;
    BOOST_CONCEPT_ASSERT( (detail::GeometryTypes<Geometry, sequence_t>) );

    BOOST_CONCEPT_USAGE(GeometryCollection)
    {
        Geometry* gc = nullptr;
        traits::clear<Geometry>::apply(*gc);
        traits::iter_visit<Geometry>::apply([](auto &&) {}, boost::begin(*gc));
    }
#endif // DOXYGEN_NO_CONCEPT_MEMBERS
};


template <typename Geometry>
struct ConstGeometryCollection
    : boost::ForwardRangeConcept<Geometry>
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
    using sequence_t = typename traits::geometry_types<Geometry>::type;
    BOOST_CONCEPT_ASSERT( (detail::GeometryTypes<Geometry const, sequence_t>) );

    BOOST_CONCEPT_USAGE(ConstGeometryCollection)
    {
        Geometry const* gc = nullptr;
        traits::iter_visit<Geometry>::apply([](auto &&) {}, boost::begin(*gc));
    }
#endif // DOXYGEN_NO_CONCEPT_MEMBERS
};


template <typename Geometry>
struct concept_type<Geometry, geometry_collection_tag>
{
    using type = GeometryCollection<Geometry>;
};

template <typename Geometry>
struct concept_type<Geometry const, geometry_collection_tag>
{
    using type = ConstGeometryCollection<Geometry>;
};


}}} // namespace boost::geometry::concepts


#endif // BOOST_GEOMETRY_GEOMETRIES_CONCEPTS_GEOMETRY_COLLECTION_CONCEPT_HPP