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