convert.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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. // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
  6. // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
  7. // Use, modification and distribution is subject to the Boost Software License,
  8. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  9. // http://www.boost.org/LICENSE_1_0.txt)
  10. #ifndef BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP
  11. #define BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP
  12. #include <boost/range/metafunctions.hpp>
  13. #include <boost/geometry/algorithms/convert.hpp>
  14. #include <boost/geometry/multi/core/tags.hpp>
  15. #include <boost/geometry/multi/geometries/concepts/check.hpp>
  16. namespace boost { namespace geometry
  17. {
  18. #ifndef DOXYGEN_NO_DETAIL
  19. namespace detail { namespace conversion
  20. {
  21. template <typename Single, typename Multi, typename Policy>
  22. struct single_to_multi: private Policy
  23. {
  24. static inline void apply(Single const& single, Multi& multi)
  25. {
  26. traits::resize<Multi>::apply(multi, 1);
  27. Policy::apply(single, *boost::begin(multi));
  28. }
  29. };
  30. template <typename Multi1, typename Multi2, typename Policy>
  31. struct multi_to_multi: private Policy
  32. {
  33. static inline void apply(Multi1 const& multi1, Multi2& multi2)
  34. {
  35. traits::resize<Multi2>::apply(multi2, boost::size(multi1));
  36. typename boost::range_iterator<Multi1 const>::type it1
  37. = boost::begin(multi1);
  38. typename boost::range_iterator<Multi2>::type it2
  39. = boost::begin(multi2);
  40. for (; it1 != boost::end(multi1); ++it1, ++it2)
  41. {
  42. Policy::apply(*it1, *it2);
  43. }
  44. }
  45. };
  46. }} // namespace detail::convert
  47. #endif // DOXYGEN_NO_DETAIL
  48. #ifndef DOXYGEN_NO_DISPATCH
  49. namespace dispatch
  50. {
  51. // Dispatch for multi <-> multi, specifying their single-version as policy.
  52. // Note that, even if the multi-types are mutually different, their single
  53. // version types might be the same and therefore we call boost::is_same again
  54. template <typename Multi1, typename Multi2, std::size_t DimensionCount>
  55. struct convert<Multi1, Multi2, multi_tag, multi_tag, DimensionCount, false>
  56. : detail::conversion::multi_to_multi
  57. <
  58. Multi1,
  59. Multi2,
  60. convert
  61. <
  62. typename boost::range_value<Multi1>::type,
  63. typename boost::range_value<Multi2>::type,
  64. typename single_tag_of
  65. <
  66. typename tag<Multi1>::type
  67. >::type,
  68. typename single_tag_of
  69. <
  70. typename tag<Multi2>::type
  71. >::type,
  72. DimensionCount
  73. >
  74. >
  75. {};
  76. template <typename Single, typename Multi, typename SingleTag, std::size_t DimensionCount>
  77. struct convert<Single, Multi, SingleTag, multi_tag, DimensionCount, false>
  78. : detail::conversion::single_to_multi
  79. <
  80. Single,
  81. Multi,
  82. convert
  83. <
  84. Single,
  85. typename boost::range_value<Multi>::type,
  86. typename tag<Single>::type,
  87. typename single_tag_of
  88. <
  89. typename tag<Multi>::type
  90. >::type,
  91. DimensionCount,
  92. false
  93. >
  94. >
  95. {};
  96. } // namespace dispatch
  97. #endif // DOXYGEN_NO_DISPATCH
  98. }} // namespace boost::geometry
  99. #endif // BOOST_GEOMETRY_MULTI_ALGORITHMS_CONVERT_HPP