• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getboost::geometry::traits::access127     static inline ctype get(Sequence const& point)
128     {
129         return boost::fusion::at_c<Dimension>(point);
130     }
131 
132     template <class CoordinateType>
setboost::geometry::traits::access133     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
179