forked from AmbaPant/mantid
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Validation.h
86 lines (72 loc) · 2.79 KB
/
Validation.h
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
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once
#include <algorithm>
#include <cfloat>
#include <cmath>
#include <stdexcept>
namespace Mantid {
namespace HistogramData {
class HistogramX;
class HistogramY;
class HistogramE;
namespace detail {
template <class TargetType> struct Validator {
template <class T> static bool isValid(const T &) { return true; }
template <class T> static void checkValidity(const T &) {}
};
template <> struct Validator<HistogramX> {
template <class T> static bool isValid(const T &data);
template <class T> static void checkValidity(const T &data);
};
template <> struct Validator<HistogramY> {
template <class T> static bool isValid(const T &data);
template <class T> static void checkValidity(const T &data);
};
template <> struct Validator<HistogramE> {
template <class T> static bool isValid(const T &data);
template <class T> static void checkValidity(const T &data);
};
template <class T> bool Validator<HistogramX>::isValid(const T &data) {
auto it = std::find_if_not(data.begin(), data.end(), [](const double d) { return std::isnan(d); });
if (it == data.end())
return true;
for (; it < data.end() - 1; ++it) {
if (std::isnan(*(it + 1)))
break;
double delta = *(it + 1) - *it;
// Not 0.0, not denormal
if (delta < DBL_MIN)
return false;
}
++it;
// after first NAN everything must be NAN
return std::find_if_not(it, data.end(), [](const double d) { return std::isnan(d); }) == data.end();
}
template <class T> void Validator<HistogramX>::checkValidity(const T &data) {
if (!isValid(data))
throw std::runtime_error("Invalid data found during construction of HistogramX");
}
template <class T> bool Validator<HistogramY>::isValid(const T &data) {
auto result = std::find_if(data.begin(), data.end(), [](const double y) { return std::isinf(y); });
return result == data.end();
}
template <class T> void Validator<HistogramY>::checkValidity(const T &data) {
if (!isValid(data))
throw std::runtime_error("Invalid data found during construction of HistogramY");
}
template <class T> bool Validator<HistogramE>::isValid(const T &data) {
auto result = std::find_if(data.begin(), data.end(), [](const double e) { return e < 0.0 || std::isinf(e); });
return result == data.end();
}
template <class T> void Validator<HistogramE>::checkValidity(const T &data) {
if (!isValid(data))
throw std::runtime_error("Invalid data found during construction of HistogramE");
}
} // namespace detail
} // namespace HistogramData
} // namespace Mantid