make.hpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
  5. // Copyright (c) 2020, Oracle and/or its affiliates.
  6. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  7. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  8. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  9. // Use, modification and distribution is subject to the Boost Software License,
  10. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  11. // http://www.boost.org/LICENSE_1_0.txt)
  12. #ifndef BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP
  13. #define BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP
  14. #include <type_traits>
  15. #include <boost/geometry/algorithms/assign.hpp>
  16. #include <boost/geometry/core/make.hpp>
  17. #include <boost/geometry/geometries/concepts/check.hpp>
  18. namespace boost { namespace geometry
  19. {
  20. #ifndef DOXYGEN_NO_DETAIL
  21. namespace detail { namespace make
  22. {
  23. /*!
  24. \brief Construct a geometry
  25. \ingroup make
  26. \tparam Geometry \tparam_geometry
  27. \tparam Range \tparam_range_point
  28. \param range \param_range_point
  29. \return The constructed geometry, here: a linestring or a ring
  30. \qbk{distinguish, with a range}
  31. \qbk{
  32. [heading Example]
  33. [make_with_range] [make_with_range_output]
  34. [heading See also]
  35. \* [link geometry.reference.algorithms.assign.assign_points assign]
  36. }
  37. */
  38. template <typename Geometry, typename Range>
  39. inline Geometry make_points(Range const& range)
  40. {
  41. concepts::check<Geometry>();
  42. Geometry geometry;
  43. geometry::append(geometry, range);
  44. return geometry;
  45. }
  46. }} // namespace detail::make
  47. #endif // DOXYGEN_NO_DETAIL
  48. /*!
  49. \brief Construct a geometry
  50. \ingroup make
  51. \details
  52. \note It does not work with array-point types, like int[2]
  53. \tparam Geometry \tparam_geometry
  54. \tparam Type \tparam_numeric to specify the coordinates
  55. \param c1 \param_x
  56. \param c2 \param_y
  57. \return The constructed geometry, here: a 2D point
  58. \qbk{distinguish, 2 coordinate values}
  59. \qbk{
  60. [heading Example]
  61. [make_2d_point] [make_2d_point_output]
  62. [heading See also]
  63. \* [link geometry.reference.algorithms.assign.assign_values_3_2_coordinate_values assign]
  64. }
  65. */
  66. template
  67. <
  68. typename Geometry,
  69. typename Type,
  70. std::enable_if_t<! traits::make<Geometry>::is_specialized, int> = 0
  71. >
  72. inline Geometry make(Type const& c1, Type const& c2)
  73. {
  74. concepts::check<Geometry>();
  75. Geometry geometry;
  76. dispatch::assign
  77. <
  78. typename tag<Geometry>::type,
  79. Geometry,
  80. geometry::dimension<Geometry>::type::value
  81. >::apply(geometry, c1, c2);
  82. return geometry;
  83. }
  84. template
  85. <
  86. typename Geometry,
  87. typename Type,
  88. std::enable_if_t<traits::make<Geometry>::is_specialized, int> = 0
  89. >
  90. constexpr inline Geometry make(Type const& c1, Type const& c2)
  91. {
  92. concepts::check<Geometry>();
  93. // NOTE: This is not fully equivalent to the above because assign uses
  94. // numeric_cast which can't be used here since it's not constexpr.
  95. return traits::make<Geometry>::apply(c1, c2);
  96. }
  97. /*!
  98. \brief Construct a geometry
  99. \ingroup make
  100. \tparam Geometry \tparam_geometry
  101. \tparam Type \tparam_numeric to specify the coordinates
  102. \param c1 \param_x
  103. \param c2 \param_y
  104. \param c3 \param_z
  105. \return The constructed geometry, here: a 3D point
  106. \qbk{distinguish, 3 coordinate values}
  107. \qbk{
  108. [heading Example]
  109. [make_3d_point] [make_3d_point_output]
  110. [heading See also]
  111. \* [link geometry.reference.algorithms.assign.assign_values_4_3_coordinate_values assign]
  112. }
  113. */
  114. template
  115. <
  116. typename Geometry,
  117. typename Type,
  118. std::enable_if_t<! traits::make<Geometry>::is_specialized, int> = 0
  119. >
  120. inline Geometry make(Type const& c1, Type const& c2, Type const& c3)
  121. {
  122. concepts::check<Geometry>();
  123. Geometry geometry;
  124. dispatch::assign
  125. <
  126. typename tag<Geometry>::type,
  127. Geometry,
  128. geometry::dimension<Geometry>::type::value
  129. >::apply(geometry, c1, c2, c3);
  130. return geometry;
  131. }
  132. template
  133. <
  134. typename Geometry,
  135. typename Type,
  136. std::enable_if_t<traits::make<Geometry>::is_specialized, int> = 0
  137. >
  138. constexpr inline Geometry make(Type const& c1, Type const& c2, Type const& c3)
  139. {
  140. concepts::check<Geometry>();
  141. // NOTE: This is not fully equivalent to the above because assign uses
  142. // numeric_cast which can't be used here since it's not constexpr.
  143. return traits::make<Geometry>::apply(c1, c2, c3);
  144. }
  145. template <typename Geometry, typename Type>
  146. inline Geometry make(Type const& c1, Type const& c2, Type const& c3, Type const& c4)
  147. {
  148. concepts::check<Geometry>();
  149. Geometry geometry;
  150. dispatch::assign
  151. <
  152. typename tag<Geometry>::type,
  153. Geometry,
  154. geometry::dimension<Geometry>::type::value
  155. >::apply(geometry, c1, c2, c3, c4);
  156. return geometry;
  157. }
  158. /*!
  159. \brief Construct a box with inverse infinite coordinates
  160. \ingroup make
  161. \details The make_inverse function initializes a 2D or 3D box with large coordinates, the
  162. min corner is very large, the max corner is very small. This is useful e.g. in combination
  163. with the expand function, to determine the bounding box of a series of geometries.
  164. \tparam Geometry \tparam_geometry
  165. \return The constructed geometry, here: a box
  166. \qbk{
  167. [heading Example]
  168. [make_inverse] [make_inverse_output]
  169. [heading See also]
  170. \* [link geometry.reference.algorithms.assign.assign_inverse assign_inverse]
  171. }
  172. */
  173. template <typename Geometry>
  174. inline Geometry make_inverse()
  175. {
  176. concepts::check<Geometry>();
  177. Geometry geometry;
  178. dispatch::assign_inverse
  179. <
  180. typename tag<Geometry>::type,
  181. Geometry
  182. >::apply(geometry);
  183. return geometry;
  184. }
  185. /*!
  186. \brief Construct a geometry with its coordinates initialized to zero
  187. \ingroup make
  188. \details The make_zero function initializes a 2D or 3D point or box with coordinates of zero
  189. \tparam Geometry \tparam_geometry
  190. \return The constructed and zero-initialized geometry
  191. */
  192. template <typename Geometry>
  193. inline Geometry make_zero()
  194. {
  195. concepts::check<Geometry>();
  196. Geometry geometry;
  197. dispatch::assign_zero
  198. <
  199. typename tag<Geometry>::type,
  200. Geometry
  201. >::apply(geometry);
  202. return geometry;
  203. }
  204. }} // namespace boost::geometry
  205. #endif // BOOST_GEOMETRY_ALGORITHMS_MAKE_HPP