Skip to content

Commit 4789f03

Browse files
authored
Merge pull request #747 from awulkiew/feature/traits_make
Add optional traits::make and use it in cross_product() and make().
2 parents 20ce3d5 + 95a9b43 commit 4789f03

File tree

18 files changed

+434
-80
lines changed

18 files changed

+434
-80
lines changed

include/boost/geometry/algorithms/make.hpp

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
55
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
66

7+
// Copyright (c) 2020, Oracle and/or its affiliates.
8+
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9+
710
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
811
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
912

@@ -14,8 +17,12 @@
1417
#ifndef BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP
1518
#define BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP
1619

20+
#include <type_traits>
21+
1722
#include <boost/geometry/algorithms/assign.hpp>
1823

24+
#include <boost/geometry/core/make.hpp>
25+
1926
#include <boost/geometry/geometries/concepts/check.hpp>
2027

2128
namespace boost { namespace geometry
@@ -32,12 +39,10 @@ namespace detail { namespace make
3239
\tparam Range \tparam_range_point
3340
\param range \param_range_point
3441
\return The constructed geometry, here: a linestring or a ring
35-
3642
\qbk{distinguish, with a range}
3743
\qbk{
3844
[heading Example]
3945
[make_with_range] [make_with_range_output]
40-
4146
[heading See also]
4247
\* [link geometry.reference.algorithms.assign.assign_points assign]
4348
}
@@ -75,7 +80,12 @@ inline Geometry make_points(Range const& range)
7580
\* [link geometry.reference.algorithms.assign.assign_values_3_2_coordinate_values assign]
7681
}
7782
*/
78-
template <typename Geometry, typename Type>
83+
template
84+
<
85+
typename Geometry,
86+
typename Type,
87+
std::enable_if_t<! traits::make<Geometry>::is_specialized, int> = 0
88+
>
7989
inline Geometry make(Type const& c1, Type const& c2)
8090
{
8191
concepts::check<Geometry>();
@@ -90,6 +100,23 @@ inline Geometry make(Type const& c1, Type const& c2)
90100
return geometry;
91101
}
92102

103+
104+
template
105+
<
106+
typename Geometry,
107+
typename Type,
108+
std::enable_if_t<traits::make<Geometry>::is_specialized, int> = 0
109+
>
110+
constexpr inline Geometry make(Type const& c1, Type const& c2)
111+
{
112+
concepts::check<Geometry>();
113+
114+
// NOTE: This is not fully equivalent to the above because assign uses
115+
// numeric_cast which can't be used here since it's not constexpr.
116+
return traits::make<Geometry>::apply(c1, c2);
117+
}
118+
119+
93120
/*!
94121
\brief Construct a geometry
95122
\ingroup make
@@ -109,7 +136,12 @@ inline Geometry make(Type const& c1, Type const& c2)
109136
\* [link geometry.reference.algorithms.assign.assign_values_4_3_coordinate_values assign]
110137
}
111138
*/
112-
template <typename Geometry, typename Type>
139+
template
140+
<
141+
typename Geometry,
142+
typename Type,
143+
std::enable_if_t<! traits::make<Geometry>::is_specialized, int> = 0
144+
>
113145
inline Geometry make(Type const& c1, Type const& c2, Type const& c3)
114146
{
115147
concepts::check<Geometry>();
@@ -124,6 +156,22 @@ inline Geometry make(Type const& c1, Type const& c2, Type const& c3)
124156
return geometry;
125157
}
126158

159+
template
160+
<
161+
typename Geometry,
162+
typename Type,
163+
std::enable_if_t<traits::make<Geometry>::is_specialized, int> = 0
164+
>
165+
constexpr inline Geometry make(Type const& c1, Type const& c2, Type const& c3)
166+
{
167+
concepts::check<Geometry>();
168+
169+
// NOTE: This is not fully equivalent to the above because assign uses
170+
// numeric_cast which can't be used here since it's not constexpr.
171+
return traits::make<Geometry>::apply(c1, c2, c3);
172+
}
173+
174+
127175
template <typename Geometry, typename Type>
128176
inline Geometry make(Type const& c1, Type const& c2, Type const& c3, Type const& c4)
129177
{

include/boost/geometry/arithmetic/cross_product.hpp

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <type_traits>
2121

2222
#include <boost/geometry/core/access.hpp>
23+
#include <boost/geometry/core/make.hpp>
2324
#include <boost/geometry/core/coordinate_dimension.hpp>
2425
#include <boost/geometry/core/static_assert.hpp>
2526

@@ -84,9 +85,10 @@ struct cross_product<3>
8485
assert_dimension<P2, 3>();
8586
assert_dimension<ResultP, 3>();
8687

87-
return ResultP(get<1>(p1) * get<2>(p2) - get<2>(p1) * get<1>(p2),
88-
get<2>(p1) * get<0>(p2) - get<0>(p1) * get<2>(p2),
89-
get<0>(p1) * get<1>(p2) - get<1>(p1) * get<0>(p2));
88+
return traits::make<ResultP>::apply(
89+
get<1>(p1) * get<2>(p2) - get<2>(p1) * get<1>(p2),
90+
get<2>(p1) * get<0>(p2) - get<0>(p1) * get<2>(p2),
91+
get<0>(p1) * get<1>(p2) - get<1>(p1) * get<0>(p2));
9092
}
9193
};
9294

@@ -110,13 +112,7 @@ template
110112
std::enable_if_t
111113
<
112114
dimension<ResultP>::value != 3
113-
|| ! std::is_constructible
114-
<
115-
ResultP,
116-
typename coordinate_type<ResultP>::type const&,
117-
typename coordinate_type<ResultP>::type const&,
118-
typename coordinate_type<ResultP>::type const&
119-
>::value,
115+
|| ! traits::make<ResultP>::is_specialized,
120116
int
121117
> = 0
122118
>
@@ -137,13 +133,7 @@ template
137133
std::enable_if_t
138134
<
139135
dimension<ResultP>::value == 3
140-
&& std::is_constructible
141-
<
142-
ResultP,
143-
typename coordinate_type<ResultP>::type const&,
144-
typename coordinate_type<ResultP>::type const&,
145-
typename coordinate_type<ResultP>::type const&
146-
>::value,
136+
&& traits::make<ResultP>::is_specialized,
147137
int
148138
> = 0
149139
>
@@ -177,13 +167,7 @@ template
177167
std::enable_if_t
178168
<
179169
dimension<P>::value != 3
180-
|| ! std::is_constructible
181-
<
182-
P,
183-
typename coordinate_type<P>::type const&,
184-
typename coordinate_type<P>::type const&,
185-
typename coordinate_type<P>::type const&
186-
>::value,
170+
|| ! traits::make<P>::is_specialized,
187171
int
188172
> = 0
189173
>
@@ -204,13 +188,7 @@ template
204188
std::enable_if_t
205189
<
206190
dimension<P>::value == 3
207-
&& std::is_constructible
208-
<
209-
P,
210-
typename coordinate_type<P>::type const&,
211-
typename coordinate_type<P>::type const&,
212-
typename coordinate_type<P>::type const&
213-
>::value,
191+
&& traits::make<P>::is_specialized,
214192
int
215193
> = 0
216194
>
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Boost.Geometry
2+
3+
// Copyright (c) 2020, Oracle and/or its affiliates.
4+
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
5+
6+
// Use, modification and distribution is subject to the Boost Software License,
7+
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
8+
// http://www.boost.org/LICENSE_1_0.txt)
9+
10+
#ifndef BOOST_GEOMETRY_CORE_MAKE_HPP
11+
#define BOOST_GEOMETRY_CORE_MAKE_HPP
12+
13+
namespace boost { namespace geometry
14+
{
15+
16+
namespace traits
17+
{
18+
19+
/*!
20+
\brief Traits class to create an object of Geometry type.
21+
\details This trait is optional and allows to define efficient way of creating Geometries.
22+
\ingroup traits
23+
\par Geometries:
24+
- points
25+
- boxes
26+
- segments
27+
\par Specializations should provide:
28+
- static const bool is_specialized = true;
29+
- static member function apply() taking:
30+
- N coordinates (points)
31+
- 2 points, min and max (boxes)
32+
- 2 points, first and second (segments)
33+
\tparam Geometry geometry
34+
*/
35+
template <typename Geometry>
36+
struct make
37+
{
38+
static const bool is_specialized = false;
39+
};
40+
41+
} // namespace traits
42+
43+
44+
}} // namespace boost::geometry
45+
46+
#endif // BOOST_GEOMETRY_CORE_MAKE_HPP

include/boost/geometry/geometries/box.hpp

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
#include <boost/concept/assert.hpp>
2525

2626
#include <boost/geometry/algorithms/convert.hpp>
27+
28+
#include <boost/geometry/core/access.hpp>
29+
#include <boost/geometry/core/make.hpp>
30+
#include <boost/geometry/core/point_type.hpp>
31+
#include <boost/geometry/core/tag.hpp>
32+
#include <boost/geometry/core/tags.hpp>
33+
2734
#include <boost/geometry/geometries/concepts/point_concept.hpp>
2835

2936
#if defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
@@ -84,18 +91,14 @@ class box
8491
*/
8592
template
8693
<
87-
typename P1 = Point,
88-
typename P2 = Point,
94+
typename P = Point,
8995
std::enable_if_t
9096
<
91-
! std::is_copy_constructible<P1>::value
92-
|| ! std::is_copy_constructible<P2>::value
93-
|| ! std::is_convertible<P1 const&, Point>::value
94-
|| ! std::is_convertible<P2 const&, Point>::value,
97+
! std::is_copy_constructible<P>::value,
9598
int
9699
> = 0
97100
>
98-
box(P1 const& min_corner, P2 const& max_corner)
101+
box(Point const& min_corner, Point const& max_corner)
99102
{
100103
geometry::convert(min_corner, m_min_corner);
101104
geometry::convert(max_corner, m_max_corner);
@@ -110,21 +113,17 @@ class box
110113
*/
111114
template
112115
<
113-
typename P1 = Point,
114-
typename P2 = Point,
116+
typename P = Point,
115117
std::enable_if_t
116118
<
117-
std::is_copy_constructible<P1>::value
118-
&& std::is_copy_constructible<P2>::value
119-
&& std::is_convertible<P1 const&, Point>::value
120-
&& std::is_convertible<P2 const&, Point>::value,
119+
std::is_copy_constructible<P>::value,
121120
int
122121
> = 0
123122
>
124123
#if ! defined(BOOST_GEOMETRY_ENABLE_ACCESS_DEBUGGING)
125124
constexpr
126125
#endif
127-
box(P1 const& min_corner, P2 const& max_corner)
126+
box(Point const& min_corner, Point const& max_corner)
128127
: m_min_corner(min_corner)
129128
, m_max_corner(max_corner)
130129
{
@@ -234,6 +233,20 @@ struct indexed_access<model::box<Point>, max_corner, Dimension>
234233
}
235234
};
236235

236+
template <typename Point>
237+
struct make<model::box<Point> >
238+
{
239+
typedef model::box<Point> box_type;
240+
241+
static const bool is_specialized = true;
242+
243+
static constexpr box_type apply(Point const& min_corner, Point const& max_corner)
244+
{
245+
return box_type(min_corner, max_corner);
246+
}
247+
};
248+
249+
237250
} // namespace traits
238251
#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
239252

include/boost/geometry/geometries/concepts/check.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ struct checker<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const>
219219
\ingroup concepts
220220
*/
221221
template <typename Geometry>
222-
inline void check()
222+
constexpr inline void check()
223223
{
224224
detail::checker<Geometry> c;
225225
boost::ignore_unused(c);
@@ -232,7 +232,7 @@ inline void check()
232232
\ingroup concepts
233233
*/
234234
template <typename Geometry1, typename Geometry2>
235-
inline void check_concepts_and_equal_dimensions()
235+
constexpr inline void check_concepts_and_equal_dimensions()
236236
{
237237
check<Geometry1>();
238238
check<Geometry2>();

include/boost/geometry/geometries/geometries.hpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
55
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
66

7+
// This file was modified by Oracle on 2020.
8+
// Modifications copyright (c) 2020, Oracle and/or its affiliates.
9+
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10+
711
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
812
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
913

@@ -14,15 +18,15 @@
1418
#ifndef BOOST_GEOMETRY_GEOMETRIES_HPP
1519
#define BOOST_GEOMETRY_GEOMETRIES_HPP
1620

17-
#include <boost/geometry/geometries/point.hpp>
21+
#include <boost/geometry/geometries/box.hpp>
1822
#include <boost/geometry/geometries/linestring.hpp>
19-
#include <boost/geometry/geometries/polygon.hpp>
20-
21-
#include <boost/geometry/geometries/multi_point.hpp>
2223
#include <boost/geometry/geometries/multi_linestring.hpp>
24+
#include <boost/geometry/geometries/multi_point.hpp>
2325
#include <boost/geometry/geometries/multi_polygon.hpp>
24-
25-
#include <boost/geometry/geometries/box.hpp>
26+
#include <boost/geometry/geometries/point.hpp>
27+
#include <boost/geometry/geometries/point_xy.hpp>
28+
#include <boost/geometry/geometries/point_xyz.hpp>
29+
#include <boost/geometry/geometries/polygon.hpp>
2630
#include <boost/geometry/geometries/ring.hpp>
2731
#include <boost/geometry/geometries/segment.hpp>
2832

0 commit comments

Comments
 (0)