Chris@16
|
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
|
Chris@16
|
2
|
Chris@101
|
3 // Copyright (c) 2011-2015 Akira Takahashi
|
Chris@101
|
4 // Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
Chris@101
|
5
|
Chris@101
|
6 // This file was modified by Oracle on 2015.
|
Chris@101
|
7 // Modifications copyright (c) 2015, Oracle and/or its affiliates.
|
Chris@101
|
8
|
Chris@101
|
9 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
Chris@16
|
10
|
Chris@16
|
11 // Use, modification and distribution is subject to the Boost Software License,
|
Chris@16
|
12 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
13 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
14
|
Chris@16
|
15 #ifndef BOOST_GEOMETRY_GEOMETRIES_ADAPTED_FUSION_HPP
|
Chris@16
|
16 #define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_FUSION_HPP
|
Chris@16
|
17
|
Chris@16
|
18
|
Chris@16
|
19 #include <cstddef>
|
Chris@16
|
20
|
Chris@101
|
21 #include <boost/core/enable_if.hpp>
|
Chris@101
|
22
|
Chris@16
|
23 #include <boost/fusion/include/is_sequence.hpp>
|
Chris@16
|
24 #include <boost/fusion/include/size.hpp>
|
Chris@16
|
25 #include <boost/fusion/include/tag_of.hpp>
|
Chris@16
|
26 #include <boost/fusion/include/front.hpp>
|
Chris@16
|
27 #include <boost/fusion/include/at.hpp>
|
Chris@101
|
28 #include <boost/fusion/mpl.hpp>
|
Chris@16
|
29
|
Chris@101
|
30 #include <boost/mpl/and.hpp>
|
Chris@101
|
31 #include <boost/mpl/count_if.hpp>
|
Chris@16
|
32 #include <boost/mpl/front.hpp>
|
Chris@101
|
33 #include <boost/mpl/placeholders.hpp>
|
Chris@16
|
34 #include <boost/mpl/pop_front.hpp>
|
Chris@16
|
35 #include <boost/mpl/size.hpp>
|
Chris@101
|
36
|
Chris@16
|
37 #include <boost/type_traits/is_same.hpp>
|
Chris@16
|
38 #include <boost/type_traits/remove_reference.hpp>
|
Chris@16
|
39
|
Chris@16
|
40 #include <boost/geometry/core/access.hpp>
|
Chris@16
|
41 #include <boost/geometry/core/coordinate_dimension.hpp>
|
Chris@16
|
42 #include <boost/geometry/core/coordinate_system.hpp>
|
Chris@16
|
43 #include <boost/geometry/core/coordinate_type.hpp>
|
Chris@16
|
44 #include <boost/geometry/core/point_type.hpp>
|
Chris@16
|
45 #include <boost/geometry/core/tags.hpp>
|
Chris@16
|
46
|
Chris@16
|
47
|
Chris@16
|
48 namespace boost { namespace geometry
|
Chris@16
|
49 {
|
Chris@16
|
50
|
Chris@16
|
51 namespace fusion_adapt_detail
|
Chris@16
|
52 {
|
Chris@16
|
53
|
Chris@16
|
54 template <class Sequence>
|
Chris@16
|
55 struct all_same :
|
Chris@16
|
56 boost::mpl::bool_<
|
Chris@16
|
57 boost::mpl::count_if<
|
Chris@16
|
58 Sequence,
|
Chris@16
|
59 boost::is_same<
|
Chris@16
|
60 typename boost::mpl::front<Sequence>::type,
|
Chris@16
|
61 boost::mpl::_
|
Chris@16
|
62 >
|
Chris@16
|
63 >::value == boost::mpl::size<Sequence>::value
|
Chris@16
|
64 >
|
Chris@16
|
65 {};
|
Chris@16
|
66
|
Chris@16
|
67 template <class Sequence>
|
Chris@16
|
68 struct is_coordinate_size : boost::mpl::bool_<
|
Chris@16
|
69 boost::fusion::result_of::size<Sequence>::value == 2 ||
|
Chris@16
|
70 boost::fusion::result_of::size<Sequence>::value == 3> {};
|
Chris@16
|
71
|
Chris@16
|
72 template<typename Sequence>
|
Chris@16
|
73 struct is_fusion_sequence
|
Chris@101
|
74 : boost::mpl::and_<boost::fusion::traits::is_sequence<Sequence>,
|
Chris@16
|
75 fusion_adapt_detail::is_coordinate_size<Sequence>,
|
Chris@16
|
76 fusion_adapt_detail::all_same<Sequence> >
|
Chris@16
|
77 {};
|
Chris@16
|
78
|
Chris@16
|
79
|
Chris@16
|
80 } // namespace fusion_adapt_detail
|
Chris@16
|
81
|
Chris@16
|
82
|
Chris@16
|
83 #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
|
Chris@16
|
84 namespace traits
|
Chris@16
|
85 {
|
Chris@16
|
86
|
Chris@16
|
87 // Boost Fusion Sequence, 2D or 3D
|
Chris@16
|
88 template <typename Sequence>
|
Chris@16
|
89 struct coordinate_type
|
Chris@16
|
90 <
|
Chris@16
|
91 Sequence,
|
Chris@16
|
92 typename boost::enable_if
|
Chris@16
|
93 <
|
Chris@16
|
94 fusion_adapt_detail::is_fusion_sequence<Sequence>
|
Chris@16
|
95 >::type
|
Chris@16
|
96 >
|
Chris@16
|
97 {
|
Chris@16
|
98 typedef typename boost::mpl::front<Sequence>::type type;
|
Chris@16
|
99 };
|
Chris@16
|
100
|
Chris@16
|
101
|
Chris@16
|
102 template <typename Sequence>
|
Chris@16
|
103 struct dimension
|
Chris@16
|
104 <
|
Chris@16
|
105 Sequence,
|
Chris@16
|
106 typename boost::enable_if
|
Chris@16
|
107 <
|
Chris@16
|
108 fusion_adapt_detail::is_fusion_sequence<Sequence>
|
Chris@16
|
109 >::type
|
Chris@16
|
110 > : boost::mpl::size<Sequence>
|
Chris@16
|
111 {};
|
Chris@16
|
112
|
Chris@16
|
113
|
Chris@16
|
114 template <typename Sequence, std::size_t Dimension>
|
Chris@16
|
115 struct access
|
Chris@16
|
116 <
|
Chris@16
|
117 Sequence,
|
Chris@16
|
118 Dimension,
|
Chris@16
|
119 typename boost::enable_if
|
Chris@16
|
120 <
|
Chris@16
|
121 fusion_adapt_detail::is_fusion_sequence<Sequence>
|
Chris@16
|
122 >::type
|
Chris@16
|
123 >
|
Chris@16
|
124 {
|
Chris@16
|
125 typedef typename coordinate_type<Sequence>::type ctype;
|
Chris@16
|
126
|
Chris@16
|
127 static inline ctype get(Sequence const& point)
|
Chris@16
|
128 {
|
Chris@16
|
129 return boost::fusion::at_c<Dimension>(point);
|
Chris@16
|
130 }
|
Chris@16
|
131
|
Chris@16
|
132 template <class CoordinateType>
|
Chris@16
|
133 static inline void set(Sequence& point, CoordinateType const& value)
|
Chris@16
|
134 {
|
Chris@16
|
135 boost::fusion::at_c<Dimension>(point) = value;
|
Chris@16
|
136 }
|
Chris@16
|
137 };
|
Chris@16
|
138
|
Chris@16
|
139
|
Chris@16
|
140 template <typename Sequence>
|
Chris@16
|
141 struct tag
|
Chris@16
|
142 <
|
Chris@16
|
143 Sequence,
|
Chris@16
|
144 typename boost::enable_if
|
Chris@16
|
145 <
|
Chris@16
|
146 fusion_adapt_detail::is_fusion_sequence<Sequence>
|
Chris@16
|
147 >::type
|
Chris@16
|
148 >
|
Chris@16
|
149 {
|
Chris@16
|
150 typedef point_tag type;
|
Chris@16
|
151 };
|
Chris@16
|
152
|
Chris@16
|
153
|
Chris@16
|
154 } // namespace traits
|
Chris@16
|
155
|
Chris@16
|
156 #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
|
Chris@16
|
157
|
Chris@16
|
158
|
Chris@16
|
159 }} // namespace boost::geometry
|
Chris@16
|
160
|
Chris@16
|
161
|
Chris@16
|
162 // Convenience registration macro to bind a Fusion sequence to a CS
|
Chris@16
|
163 #define BOOST_GEOMETRY_REGISTER_BOOST_FUSION_CS(CoordinateSystem) \
|
Chris@16
|
164 namespace boost { namespace geometry { namespace traits { \
|
Chris@16
|
165 template <typename Sequence> \
|
Chris@16
|
166 struct coordinate_system \
|
Chris@16
|
167 < \
|
Chris@16
|
168 Sequence, \
|
Chris@16
|
169 typename boost::enable_if \
|
Chris@16
|
170 < \
|
Chris@16
|
171 fusion_adapt_detail::is_fusion_sequence<Sequence> \
|
Chris@16
|
172 >::type \
|
Chris@16
|
173 > \
|
Chris@16
|
174 { typedef CoordinateSystem type; }; \
|
Chris@16
|
175 }}}
|
Chris@16
|
176
|
Chris@16
|
177
|
Chris@16
|
178 #endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_FUSION_HPP
|