calculation_type.hpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. // Boost.Geometry (aka GGL, Generic Geometry Library)
  2. // Copyright (c) 2012 Barend Gehrels, Amsterdam, the Netherlands.
  3. // Copyright (c) 2012 Bruno Lalande, Paris, France.
  4. // Copyright (c) 2012 Mateusz Loskot, London, UK.
  5. // This file was modified by Oracle on 2018.
  6. // Modifications copyright (c) 2018, Oracle and/or its affiliates.
  7. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
  8. // Use, modification and distribution is subject to the Boost Software License,
  9. // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. #ifndef BOOST_GEOMETRY_UTIL_CALCULATION_TYPE_HPP
  12. #define BOOST_GEOMETRY_UTIL_CALCULATION_TYPE_HPP
  13. #include <boost/config.hpp>
  14. #include <boost/mpl/if.hpp>
  15. #include <boost/static_assert.hpp>
  16. #include <boost/type_traits/is_floating_point.hpp>
  17. #include <boost/type_traits/is_fundamental.hpp>
  18. #include <boost/type_traits/is_void.hpp>
  19. #include <boost/geometry/util/select_coordinate_type.hpp>
  20. #include <boost/geometry/util/select_most_precise.hpp>
  21. namespace boost { namespace geometry
  22. {
  23. namespace util
  24. {
  25. namespace detail
  26. {
  27. struct default_integral
  28. {
  29. #ifdef BOOST_HAS_LONG_LONG
  30. typedef boost::long_long_type type;
  31. #else
  32. typedef int type;
  33. #endif
  34. };
  35. /*!
  36. \details Selects the most appropriate:
  37. - if calculation type is specified (not void), that one is used
  38. - else if type is non-fundamental (user defined e.g. ttmath), that one
  39. - else if type is floating point, the specified default FP is used
  40. - else it is integral and the specified default integral is used
  41. */
  42. template
  43. <
  44. typename Type,
  45. typename CalculationType,
  46. typename DefaultFloatingPointCalculationType,
  47. typename DefaultIntegralCalculationType
  48. >
  49. struct calculation_type
  50. {
  51. BOOST_STATIC_ASSERT((
  52. boost::is_fundamental
  53. <
  54. DefaultFloatingPointCalculationType
  55. >::type::value
  56. ));
  57. BOOST_STATIC_ASSERT((
  58. boost::is_fundamental
  59. <
  60. DefaultIntegralCalculationType
  61. >::type::value
  62. ));
  63. typedef typename boost::mpl::if_
  64. <
  65. boost::is_void<CalculationType>,
  66. typename boost::mpl::if_
  67. <
  68. boost::is_floating_point<Type>,
  69. typename select_most_precise
  70. <
  71. DefaultFloatingPointCalculationType,
  72. Type
  73. >::type,
  74. typename select_most_precise
  75. <
  76. DefaultIntegralCalculationType,
  77. Type
  78. >::type
  79. >::type,
  80. CalculationType
  81. >::type type;
  82. };
  83. } // namespace detail
  84. namespace calculation_type
  85. {
  86. namespace geometric
  87. {
  88. template
  89. <
  90. typename Geometry,
  91. typename CalculationType,
  92. typename DefaultFloatingPointCalculationType = double,
  93. typename DefaultIntegralCalculationType = detail::default_integral::type
  94. >
  95. struct unary
  96. {
  97. typedef typename detail::calculation_type
  98. <
  99. typename geometry::coordinate_type<Geometry>::type,
  100. CalculationType,
  101. DefaultFloatingPointCalculationType,
  102. DefaultIntegralCalculationType
  103. >::type type;
  104. };
  105. template
  106. <
  107. typename Geometry1,
  108. typename Geometry2,
  109. typename CalculationType,
  110. typename DefaultFloatingPointCalculationType = double,
  111. typename DefaultIntegralCalculationType = detail::default_integral::type
  112. >
  113. struct binary
  114. {
  115. typedef typename detail::calculation_type
  116. <
  117. typename select_coordinate_type<Geometry1, Geometry2>::type,
  118. CalculationType,
  119. DefaultFloatingPointCalculationType,
  120. DefaultIntegralCalculationType
  121. >::type type;
  122. };
  123. /*!
  124. \brief calculation type (ternary, for three geometry types)
  125. */
  126. template
  127. <
  128. typename Geometry1,
  129. typename Geometry2,
  130. typename Geometry3,
  131. typename CalculationType,
  132. typename DefaultFloatingPointCalculationType = double,
  133. typename DefaultIntegralCalculationType = detail::default_integral::type
  134. >
  135. struct ternary
  136. {
  137. typedef typename detail::calculation_type
  138. <
  139. typename select_most_precise
  140. <
  141. typename coordinate_type<Geometry1>::type,
  142. typename select_coordinate_type
  143. <
  144. Geometry2,
  145. Geometry3
  146. >::type
  147. >::type,
  148. CalculationType,
  149. DefaultFloatingPointCalculationType,
  150. DefaultIntegralCalculationType
  151. >::type type;
  152. };
  153. }} // namespace calculation_type::geometric
  154. } // namespace util
  155. }} // namespace boost::geometry
  156. #endif // BOOST_GEOMETRY_UTIL_CALCULATION_TYPE_HPP