visit.hpp 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Boost.Geometry
  2. // Copyright (c) 2021, Oracle and/or its affiliates.
  3. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  4. // Licensed under the Boost Software License version 1.0.
  5. // http://www.boost.org/users/license.html
  6. #ifndef BOOST_GEOMETRY_CORE_VISIT_HPP
  7. #define BOOST_GEOMETRY_CORE_VISIT_HPP
  8. #include <utility>
  9. #include <boost/range/value_type.hpp>
  10. #include <boost/geometry/core/static_assert.hpp>
  11. #include <boost/geometry/util/type_traits_std.hpp>
  12. namespace boost { namespace geometry { namespace traits
  13. {
  14. // TODO: Alternatives:
  15. // - free function
  16. // template <typename Visitor, typename ...Variants>
  17. // auto visit(Visitor &&, Variants && ...) {}
  18. //
  19. // - additional Enable tparam
  20. // template <bool Enable, typename ...DynamicGeometries>
  21. // struct visit {};
  22. template <typename ...DynamicGeometries>
  23. struct visit
  24. {
  25. BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
  26. "Not implemented for these DynamicGeometries types.",
  27. DynamicGeometries...);
  28. };
  29. // By default call 1-parameter visit for each geometry
  30. template <typename DynamicGeometry1, typename DynamicGeometry2>
  31. struct visit<DynamicGeometry1, DynamicGeometry2>
  32. {
  33. template <typename Function, typename Variant1, typename Variant2>
  34. static void apply(Function && function, Variant1 && variant1, Variant2 && variant2)
  35. {
  36. visit<util::remove_cref_t<Variant1>>::apply([&](auto && g1)
  37. {
  38. using ref1_t = decltype(g1);
  39. visit<util::remove_cref_t<Variant2>>::apply([&](auto && g2)
  40. {
  41. function(std::forward<ref1_t>(g1),
  42. std::forward<decltype(g2)>(g2));
  43. }, std::forward<Variant2>(variant2));
  44. }, std::forward<Variant1>(variant1));
  45. }
  46. };
  47. // By default treat GeometryCollection as a range of DynamicGeometries
  48. template <typename GeometryCollection>
  49. struct iter_visit
  50. {
  51. template <typename Function, typename Iterator>
  52. static void apply(Function && function, Iterator iterator)
  53. {
  54. using value_t = typename boost::range_value<GeometryCollection>::type;
  55. using reference_t = typename std::iterator_traits<Iterator>::reference;
  56. visit<value_t>::apply(std::forward<Function>(function),
  57. std::forward<reference_t>(*iterator));
  58. }
  59. };
  60. }}} // namespace boost::geometry::traits
  61. #endif // BOOST_GEOMETRY_CORE_VISIT_HPP