boost_fusion.hpp 4.4 KB

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