22 #ifndef SPATIAL_MATH_HPP
23 #define SPATIAL_MATH_HPP
28 #include "spatial_import_type_traits.hpp"
29 #include "../exception.hpp"
30 #include "spatial_check_concept.hpp"
41 inline typename enable_if<import::is_arithmetic<Tp> >::type
46 std::stringstream out;
47 out << x <<
" is negative";
69 template <
typename Tp>
72 <std::numeric_limits<Tp>::is_integer
73 && std::numeric_limits<Tp>::is_signed, Tp>::type
76 if (x == (std::numeric_limits<Tp>::min)())
78 std::stringstream out;
79 out <<
"absolute of " << x <<
" caused overflow";
85 template <
typename Tp>
87 <!std::numeric_limits<Tp>::is_integer
88 || !std::numeric_limits<Tp>::is_signed, Tp>::type
90 {
return std::abs(x); }
107 template <
typename Tp>
112 if (((std::numeric_limits<Tp>::max)() - x) < y)
114 std::stringstream out;
115 out << x <<
" + " << y <<
" caused overflow";
131 template <
typename Tp>
139 if (((std::numeric_limits<Tp>::max)() / abs) < abs)
141 std::stringstream out;
142 out <<
"square(" << x <<
") caused overflow";
164 template <
typename Tp>
171 if (((std::numeric_limits<Tp>::max)() / x) < y)
173 std::stringstream out;
174 out << x <<
" * " << y <<
" caused overflow";
190 template <
typename Key,
typename Difference,
typename Unit>
195 Unit d = diff(dim, origin, key);
196 #ifdef SPATIAL_SAFER_ARITHMETICS
207 template <
typename Key,
typename Difference,
typename Unit>
212 Unit sum = square_euclid_distance_to_plane<Key, Difference, Unit>
213 (0, origin, key, diff);
216 #ifdef SPATIAL_SAFER_ARITHMETICS
218 (square_euclid_distance_to_plane<Key, Difference, Unit>
219 (i, origin, key, diff), sum);
222 <Key, Difference, Unit>(i, origin, key, diff);
232 template <
typename Key,
typename Difference,
typename Unit>
237 return std::abs(diff(dim, origin, key));
260 template <
typename Key,
typename Difference,
typename Unit>
265 #ifdef SPATIAL_SAFER_ARITHMETICS
267 Unit max = euclid_distance_to_plane<Key, Difference, Unit>
268 (0, origin, key, diff);
272 Unit d = euclid_distance_to_plane<Key, Difference, Unit>
273 (i, origin, key, diff);
274 if (d > max) { max = d; max_dim = i; }
276 const Unit zero = Unit();
277 if (max == zero)
return zero;
282 Unit div = diff(i, origin, key) / max;
287 Unit div = diff(i, origin, key) / max;
292 return std::sqrt(square_euclid_distance_to_key<Key, Difference, Unit>
293 (rank, origin, key, diff));
302 template <
typename Key,
typename Difference,
typename Unit>
307 #ifdef SPATIAL_SAFER_ARITHMETICS
310 return std::abs(diff(dim, origin, key));
317 template <
typename Key,
typename Difference,
typename Unit>
322 Unit sum = manhattan_distance_to_plane<Key, Difference, Unit>
323 (0, origin, key, diff);
326 #ifdef SPATIAL_SAFER_ARITHMETICS
328 (manhattan_distance_to_plane<Key, Difference, Unit>
329 (i, origin, key, diff), sum);
332 <Key, Difference, Unit>(i, origin, key, diff);
349 #endif // SPATIAL_MATH_HPP
enable_if< import::is_arithmetic< Tp >, Tp >::type check_square(Tp x)
This arithmetic check is only used when the macro SPATIAL_SAFER_ARITHMETICS is defined.
enable_if< import::is_arithmetic< Unit >, Unit >::type square_euclid_distance_to_key(dimension_type rank, const Key &origin, const Key &key, Difference diff)
Compute the square value of the distance between origin and key.
enable_if_c< std::numeric_limits< Tp >::is_integer &&std::numeric_limits< Tp >::is_signed, Tp >::type check_abs(Tp x)
This arithmetic check is only used when the macro SPATIAL_SAFER_ARITHMETICS is defined.
enable_if< import::is_floating_point< Unit >, Unit >::type euclid_distance_to_key(dimension_type rank, const Key &origin, const Key &key, Difference diff)
Computes the euclidian distance between 2 points.
enable_if< import::is_arithmetic< Tp > >::type check_positive_distance(Tp x)
Check that the distance given x has a positive value.
Thrown to report that an arithmetic error has occured during a calculation.
enable_if< import::is_arithmetic< Unit >, Unit >::type manhattan_distance_to_key(dimension_type rank, const Key &origin, const Key &key, Difference diff)
Compute the manhattan distance between origin and key.
Thrown to report that an negative distance has been passed as a parameter while distances are expecte...
enable_if< import::is_arithmetic< Tp >, Tp >::type check_positive_add(Tp x, Tp y)
This arithmetic check is only used when the macro SPATIAL_SAFER_ARITHMETICS is defined.
std::size_t dimension_type
Defines the type for the dimension as being a size.
If B is true, spatial::enable_if has a public member typedef type, equal to Tp; otherwise, there is no member typedef.
The main namespace used in the library.
enable_if< import::is_floating_point< Unit >, Unit >::type euclid_distance_to_plane(dimension_type dim, const Key &origin, const Key &key, Difference diff)
Compute the distance between the origin and the closest point to the plane orthogonal to the axis of ...
enable_if< import::is_arithmetic< Unit >, Unit >::type square_euclid_distance_to_plane(dimension_type dim, const Key &origin, const Key &key, Difference diff)
Compute the distance between the origin and the closest point to the plane orthogonal to the axis of ...
enable_if< import::is_arithmetic< Tp >, Tp >::type check_positive_mul(Tp x, Tp y)
This arithmetic check is only used when the macro SPATIAL_SAFER_ARITHMETICS is defined.
enable_if< import::is_arithmetic< Unit >, Unit >::type manhattan_distance_to_plane(dimension_type dim, const Key &origin, const Key &key, Difference diff)
Compute the distance between the origin and the closest point to the plane orthogonal to the axis of ...