summaryrefslogtreecommitdiff
path: root/boost/geometry/policies/relate/tupled.hpp
blob: 853a8a26a8f1fc89bcc6c62571720e751ca503a7 (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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// Boost.Geometry (aka GGL, Generic Geometry Library)

// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.

// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

#ifndef BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_TUPLED_HPP
#define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_TUPLED_HPP


#include <string>

#include <boost/tuple/tuple.hpp>
#include <boost/geometry/strategies/side_info.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/util/select_most_precise.hpp>

namespace boost { namespace geometry
{

namespace policies { namespace relate
{


// "tupled" to return intersection results together.
// Now with two, with some meta-programming and derivations it can also be three (or more)
template <typename Policy1, typename Policy2, typename CalculationType = void>
struct segments_tupled
{
    typedef boost::tuple
        <
            typename Policy1::return_type,
            typename Policy2::return_type
        > return_type;

    // Take segments of first policy, they should be equal
    typedef typename Policy1::segment_type1 segment_type1;
    typedef typename Policy1::segment_type2 segment_type2;

    typedef typename select_calculation_type
        <
            segment_type1,
            segment_type2,
            CalculationType
        >::type coordinate_type;

    // Get the same type, but at least a double
    typedef typename select_most_precise<coordinate_type, double>::type rtype;

    static inline return_type segments_intersect(side_info const& sides,
                    coordinate_type const& dx1, coordinate_type const& dy1,
                    coordinate_type const& dx2, coordinate_type const& dy2,
                    segment_type1 const& s1, segment_type2 const& s2)
    {
        return boost::make_tuple
            (
                Policy1::segments_intersect(sides,
                    dx1, dy1, dx2, dy2, s1, s2),
                Policy2::segments_intersect(sides,
                    dx1, dy1, dx2, dy2, s1, s2)
            );
    }

    static inline return_type collinear_touch(coordinate_type const& x,
                coordinate_type const& y, int arrival_a, int arrival_b)
    {
        return boost::make_tuple
            (
                Policy1::collinear_touch(x, y, arrival_a, arrival_b),
                Policy2::collinear_touch(x, y, arrival_a, arrival_b)
            );
    }

    template <typename S>
    static inline return_type collinear_interior_boundary_intersect(S const& segment,
                bool a_within_b,
                int arrival_a, int arrival_b, bool opposite)
    {
        return boost::make_tuple
            (
                Policy1::collinear_interior_boundary_intersect(segment, a_within_b, arrival_a, arrival_b, opposite),
                Policy2::collinear_interior_boundary_intersect(segment, a_within_b, arrival_a, arrival_b, opposite)
            );
    }

    static inline return_type collinear_a_in_b(segment_type1 const& segment,
                bool opposite)
    {
        return boost::make_tuple
            (
                Policy1::collinear_a_in_b(segment, opposite),
                Policy2::collinear_a_in_b(segment, opposite)
            );
    }
    static inline return_type collinear_b_in_a(segment_type2 const& segment,
                    bool opposite)
    {
        return boost::make_tuple
            (
                Policy1::collinear_b_in_a(segment, opposite),
                Policy2::collinear_b_in_a(segment, opposite)
            );
    }


    static inline return_type collinear_overlaps(
                    coordinate_type const& x1, coordinate_type const& y1,
                    coordinate_type const& x2, coordinate_type const& y2,
                    int arrival_a, int arrival_b, bool opposite)
    {
        return boost::make_tuple
            (
                Policy1::collinear_overlaps(x1, y1, x2, y2, arrival_a, arrival_b, opposite),
                Policy2::collinear_overlaps(x1, y1, x2, y2, arrival_a, arrival_b, opposite)
            );
    }

    static inline return_type segment_equal(segment_type1 const& s,
                bool opposite)
    {
        return boost::make_tuple
            (
                Policy1::segment_equal(s, opposite),
                Policy2::segment_equal(s, opposite)
            );
    }

    static inline return_type degenerate(segment_type1 const& segment,
                bool a_degenerate)
    {
        return boost::make_tuple
            (
                Policy1::degenerate(segment, a_degenerate),
                Policy2::degenerate(segment, a_degenerate)
            );
    }

    static inline return_type disjoint()
    {
        return boost::make_tuple
            (
                Policy1::disjoint(),
                Policy2::disjoint()
            );
    }

    static inline return_type error(std::string const& msg)
    {
        return boost::make_tuple
            (
                Policy1::error(msg),
                Policy2::error(msg)
            );
    }

    static inline return_type collinear_disjoint()
    {
        return boost::make_tuple
            (
                Policy1::collinear_disjoint(),
                Policy2::collinear_disjoint()
            );
    }

};

}} // namespace policies::relate

}} // namespace boost::geometry

#endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_TUPLED_HPP