boost_fusion.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2011-2015 Akira Takahashi
  3. // Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands.
  4. // This file was modified by Oracle on 2015.
  5. // Modifications copyright (c) 2015, Oracle and/or its affiliates.
  6. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
  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_GEOMETRIES_ADAPTED_FUSION_HPP
  11. #define BOOST_GEOMETRY_GEOMETRIES_ADAPTED_FUSION_HPP
  12. #include <cstddef>
  13. #include <boost/core/enable_if.hpp>
  14. #include <boost/fusion/include/is_sequence.hpp>
  15. #include <boost/fusion/include/size.hpp>
  16. #include <boost/fusion/include/tag_of.hpp>
  17. #include <boost/fusion/include/front.hpp>
  18. #include <boost/fusion/include/at.hpp>
  19. #include <boost/fusion/mpl.hpp>
  20. #include <boost/mpl/and.hpp>
  21. #include <boost/mpl/count_if.hpp>
  22. #include <boost/mpl/front.hpp>
  23. #include <boost/mpl/placeholders.hpp>
  24. #include <boost/mpl/pop_front.hpp>
  25. #include <boost/mpl/size.hpp>
  26. #include <boost/type_traits/is_same.hpp>
  27. #include <boost/type_traits/remove_reference.hpp>
  28. #include <boost/geometry/core/access.hpp>
  29. #include <boost/geometry/core/coordinate_dimension.hpp>
  30. #include <boost/geometry/core/coordinate_system.hpp>
  31. #include <boost/geometry/core/coordinate_type.hpp>
  32. #include <boost/geometry/core/point_type.hpp>
  33. #include <boost/geometry/core/tags.hpp>
  34. namespace boost { namespace geometry
  35. {
  36. namespace fusion_adapt_detail
  37. {
  38. template <class Sequence>
  39. struct all_same :
  40. boost::mpl::bool_<
  41. boost::mpl::count_if<
  42. Sequence,
  43. boost::is_same<
  44. typename boost::mpl::front<Sequence>::type,
  45. boost::mpl::_
  46. >
  47. >::value == boost::mpl::size<Sequence>::value
  48. >
  49. {};
  50. template <class Sequence>
  51. struct is_coordinate_size : boost::mpl::bool_<
  52. boost::fusion::result_of::size<Sequence>::value == 2 ||
  53. boost::fusion::result_of::size<Sequence>::value == 3> {};
  54. template<typename Sequence>
  55. struct is_fusion_sequence
  56. : boost::mpl::and_<boost::fusion::traits::is_sequence<Sequence>,
  57. fusion_adapt_detail::is_coordinate_size<Sequence>,
  58. fusion_adapt_detail::all_same<Sequence> >
  59. {};
  60. } // namespace fusion_adapt_detail
  61. #ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
  62. namespace traits
  63. {
  64. // Boost Fusion Sequence, 2D or 3D
  65. template <typename Sequence>
  66. struct coordinate_type
  67. <
  68. Sequence,
  69. typename boost::enable_if
  70. <
  71. fusion_adapt_detail::is_fusion_sequence<Sequence>
  72. >::type
  73. >
  74. {
  75. typedef typename boost::mpl::front<Sequence>::type type;
  76. };
  77. template <typename Sequence>
  78. struct dimension
  79. <
  80. Sequence,
  81. typename boost::enable_if
  82. <
  83. fusion_adapt_detail::is_fusion_sequence<Sequence>
  84. >::type
  85. > : boost::mpl::size<Sequence>
  86. {};
  87. template <typename Sequence, std::size_t Dimension>
  88. struct access
  89. <
  90. Sequence,
  91. Dimension,
  92. typename boost::enable_if
  93. <
  94. fusion_adapt_detail::is_fusion_sequence<Sequence>
  95. >::type
  96. >
  97. {
  98. typedef typename coordinate_type<Sequence>::type ctype;
  99. static inline ctype get(Sequence const& point)
  100. {
  101. return boost::fusion::at_c<Dimension>(point);
  102. }
  103. template <class CoordinateType>
  104. static inline void set(Sequence& point, CoordinateType const& value)
  105. {
  106. boost::fusion::at_c<Dimension>(point) = value;
  107. }
  108. };
  109. template <typename Sequence>
  110. struct tag
  111. <
  112. Sequence,
  113. typename boost::enable_if
  114. <
  115. fusion_adapt_detail::is_fusion_sequence<Sequence>
  116. >::type
  117. >
  118. {
  119. typedef point_tag type;
  120. };
  121. } // namespace traits
  122. #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
  123. }} // namespace boost::geometry
  124. // Convenience registration macro to bind a Fusion sequence to a CS
  125. #define BOOST_GEOMETRY_REGISTER_BOOST_FUSION_CS(CoordinateSystem) \
  126. namespace boost { namespace geometry { namespace traits { \
  127. template <typename Sequence> \
  128. struct coordinate_system \
  129. < \
  130. Sequence, \
  131. typename boost::enable_if \
  132. < \
  133. fusion_adapt_detail::is_fusion_sequence<Sequence> \
  134. >::type \
  135. > \
  136. { typedef CoordinateSystem type; }; \
  137. }}}
  138. #endif // BOOST_GEOMETRY_GEOMETRIES_ADAPTED_FUSION_HPP