-
Notifications
You must be signed in to change notification settings - Fork 0
/
Common.hpp
96 lines (72 loc) · 2.64 KB
/
Common.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#ifndef GEOINDEX_COMMON
#define GEOINDEX_COMMON
#include <vector>
#include "BasicGeometry.hpp"
#ifdef GEO_INDEX_SAFETY_CHECKS
#include <stdexcept>
#include <cmath>
#include<limits>
#endif
namespace geoIndex {
/** This file collects elements that are common to all the algorithms. */
/** This struct is useful for sorting operations on points or coordinates or distances....
* It has no actual point inside to keep it as small as it can get.
* The content is not constant to allow auto-generation of constructors, operators... (try to put const there!).
*/
template <typename POINT>
struct IndexAndGeometry {
typename PointTraits<POINT>::index pointIndex;
typename PointTraits<POINT>::coordinate geometricValue;
};
/** Helpers to sort and search. */
template <typename POINT>
static const bool SortByPointIndex(const IndexAndGeometry<POINT>& lhs,
const IndexAndGeometry<POINT>& rhs)
{
return lhs.pointIndex < rhs.pointIndex;
}
template <typename POINT>
static bool SortByGeometry(const IndexAndGeometry<POINT>& lhs,
const IndexAndGeometry<POINT>& rhs)
{
return lhs.geometricValue < rhs.geometricValue;
}
/** Alias from when we store the distance for a point to a reference. */
template <typename POINT>
using IndexAndSquaredDistance = IndexAndGeometry<POINT>;
/** Alias to store coordinates. */
template <typename POINT>
using IndexAndCoordinate = IndexAndGeometry<POINT>;
#ifdef GEO_INDEX_SAFETY_CHECKS
template <typename POINT_COORDINATE>
void CheckOverflow(const POINT_COORDINATE value) {
if (std::isinf(value))
throw std::runtime_error("Overflow");
}
template <typename DISTANCE_TYPE>
void CheckMeaningfulDistance(const DISTANCE_TYPE d) {
if (d <= 0)
throw std::runtime_error("Negative distance");
if (std::isnan(d))
throw std::runtime_error("Invalid distance");
CheckOverflow(d);
}
/** Throws if a + b would go over the maximum.
* We are solidly in "best quick and dirty effort" territory. This probably has holes,
* but may still help to smoke out bugs. */
template <typename T>
void StopSumOverflow(const T a, const T b) {
if (std::numeric_limits<T>::max() - a < b)
throw std::runtime_error("Sum about to overflow.");
}
/** Throws if a - b would go below the minimum.
* We are solidly in "best quick and dirty effort" territory. This probably has holes,
* but may still help to smoke out bugs. */
template <typename T>
void StopDifferenceUnderflow(const T a, const T b) {
if (a < std::numeric_limits<T>::min() + b)
throw std::runtime_error("Difference about to underflow.");
}
#endif
}
#endif