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
48namespace boost { namespace geometry
49{
50
51namespace fusion_adapt_detail
52{
53
54template <class Sequence>
55struct 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
67template <class Sequence>
68struct 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
72template<typename Sequence>
73struct 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
84namespace traits
85{
86
87// Boost Fusion Sequence, 2D or 3D
88template <typename Sequence>
89struct 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
102template <typename Sequence>
103struct 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
114template <typename Sequence, std::size_t Dimension>
115struct 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
140template <typename Sequence>
141struct 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

source code of boost/boost/geometry/geometries/adapted/boost_fusion.hpp