Belle II Software development
ESign.h
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#pragma once
9
10#include <algorithm>
11#include <cstdlib> // for abs
12#include <cmath> // for isnan
13#include <climits> // for SHRT_MIN
14
15namespace Belle2 {
21 namespace TrackFindingCDC {
22
24 namespace ESignUtil {
25
27 enum ESign : signed short {
29 c_Plus = 1,
30
32 c_Minus = -1,
33
35 c_Zero = 0,
36
38 c_Invalid = SHRT_MIN,
39 };
40
43 { return static_cast<ESign>(-s); }
44
46 inline bool isValid(ESign s)
47 { return std::abs(s) <= 1; }
48
57 static inline ESign common(ESign n1, ESign n2)
58 {
59 return ((not isValid(n1) and not isValid(n2)) ?
60 ESign::c_Invalid :
61 static_cast<ESign>((not(n1 <= 0) and not(n2 <= 0)) - (not(n1 >= 0) and not(n2 >= 0))));
62 }
63
72 static inline ESign common(float n1, float n2)
73 {
74 return ((std::isnan(n1) and std::isnan(n2)) ?
75 ESign::c_Invalid :
76 static_cast<ESign>((not(n1 <= 0) and not(n2 <= 0)) - (not(n1 >= 0) and not(n2 >= 0))));
77 }
78
87 static inline ESign common(float n1, float n2, float n3, float n4)
88 {
89 return ((std::isnan(n1) and std::isnan(n2) and std::isnan(n3) and std::isnan(n4)) ?
90 ESign::c_Invalid :
91 static_cast<ESign>((not(n1 <= 0) and not(n2 <= 0) and not(n3 <= 0) and not(n4 <= 0)) -
92 (not(n1 >= 0) and not(n2 >= 0) and not(n3 >= 0) and not(n4 >= 0))));
93 }
94
103 template<class FloatRange>
104 static inline ESign common(const FloatRange& as)
105 {
106 bool allNaN = std::all_of(as.begin(), as.end(), [](float a) { return std::isnan(a); });
107 if (allNaN) {
108 return ESign::c_Invalid;
109 } else {
110 return static_cast<ESign>(std::all_of(as.begin(), as.end(), [](float a) { return not(a <= 0); }) -
111 std::all_of(as.begin(), as.end(), [](float a) { return not(a >= 0); }));
112 }
113 }
114
115 };
116
118 using ESign = ESignUtil::ESign;
119
126 inline ESign sign(double x)
127 {
128 return std::isnan(x) ? ESign::c_Invalid : (std::signbit(x) ? ESign::c_Minus : ESign::c_Plus);
129 }
130
132 inline ESign sign(int x)
133 {
134 return static_cast<ESign>((x > 0) - (x < 0));
135 }
136
138 template<class Enum, Enum invalid = Enum::c_Invalid>
139 inline ESign sign(Enum x)
140 {
141 if (x == Enum::c_Invalid) return ESign::c_Invalid;
142 return sign(static_cast<int>(x));
143 }
144 }
145
147}
ESign
Enumeration for the distinct sign values of floating point variables.
Definition: ESign.h:27
@ c_Invalid
Constant for invalid sign, e.g. the sign of NAN.
Definition: ESign.h:38
@ c_Zero
Constant for undefined sign.
Definition: ESign.h:35
@ c_Minus
Constant for minus sign.
Definition: ESign.h:32
@ c_Plus
Constant for plus sign.
Definition: ESign.h:29
ESign opposite(ESign s)
Return the opposite sign. Leaves ESign::c_Invalid the same.
Definition: ESign.h:42
bool isValid(ESign s)
Returns true if sign is ESign::c_Plus, ESign::c_Minus or ESign::c_Zero.
Definition: ESign.h:46
static ESign common(ESign n1, ESign n2)
Check if two values have a common sign.
Definition: ESign.h:57
Abstract base class for different kinds of events.