1//
2// FPEnvironment_C99.h
3//
4// Library: Foundation
5// Package: Core
6// Module: FPEnvironment
7//
8// Definitions of class FPEnvironmentImpl for C99.
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_FPEnvironment_C99_INCLUDED
18#define Foundation_FPEnvironment_C99_INCLUDED
19
20
21#include "Poco/Foundation.h"
22#include <fenv.h>
23#include <cmath>
24
25
26namespace Poco {
27
28
29class FPEnvironmentImpl
30{
31protected:
32 enum RoundingModeImpl
33 {
34#if defined(FE_DOWNWARD)
35 FP_ROUND_DOWNWARD_IMPL = FE_DOWNWARD,
36#else
37 FP_ROUND_DOWNWARD_IMPL = 0,
38#endif
39#if defined(FE_UPWARD)
40 FP_ROUND_UPWARD_IMPL = FE_UPWARD,
41#else
42 FP_ROUND_UPWARD_IMPL = 0,
43#endif
44#if defined(FE_TONEAREST)
45 FP_ROUND_TONEAREST_IMPL = FE_TONEAREST,
46#else
47 FP_ROUND_TONEAREST_IMPL = 0,
48#endif
49#if defined(FE_TOWARDZERO)
50 FP_ROUND_TOWARDZERO_IMPL = FE_TOWARDZERO
51#else
52 FP_ROUND_TOWARDZERO_IMPL = 0
53#endif
54 };
55 enum FlagImpl
56 {
57#if defined(FE_DIVBYZERO)
58 FP_DIVIDE_BY_ZERO_IMPL = FE_DIVBYZERO,
59#else
60 FP_DIVIDE_BY_ZERO_IMPL = 0,
61#endif
62#if defined(FE_INEXACT)
63 FP_INEXACT_IMPL = FE_INEXACT,
64#else
65 FP_INEXACT_IMPL = 0,
66#endif
67#if defined(FE_OVERFLOW)
68 FP_OVERFLOW_IMPL = FE_OVERFLOW,
69#else
70 FP_OVERFLOW_IMPL = 0,
71#endif
72#if defined(FE_UNDERFLOW)
73 FP_UNDERFLOW_IMPL = FE_UNDERFLOW,
74#else
75 FP_UNDERFLOW_IMPL = 0,
76#endif
77#if defined(FE_INVALID)
78 FP_INVALID_IMPL = FE_INVALID
79#else
80 FP_INVALID_IMPL = 0
81#endif
82 };
83 FPEnvironmentImpl();
84 FPEnvironmentImpl(const FPEnvironmentImpl& env);
85 ~FPEnvironmentImpl();
86 FPEnvironmentImpl& operator = (const FPEnvironmentImpl& env);
87 void keepCurrentImpl();
88 static void clearFlagsImpl();
89 static bool isFlagImpl(FlagImpl flag);
90 static void setRoundingModeImpl(RoundingModeImpl mode);
91 static RoundingModeImpl getRoundingModeImpl();
92 static bool isInfiniteImpl(float value);
93 static bool isInfiniteImpl(double value);
94 static bool isInfiniteImpl(long double value);
95 static bool isNaNImpl(float value);
96 static bool isNaNImpl(double value);
97 static bool isNaNImpl(long double value);
98 static float copySignImpl(float target, float source);
99 static double copySignImpl(double target, double source);
100 static long double copySignImpl(long double target, long double source);
101
102private:
103 fenv_t _env;
104};
105
106
107//
108// inlines
109//
110inline bool FPEnvironmentImpl::isInfiniteImpl(float value)
111{
112#if POCO_OS == POCO_OS_AIX
113 return ::isinf(value) != 0;
114#else
115 return std::isinf(value) != 0;
116#endif
117}
118
119
120inline bool FPEnvironmentImpl::isInfiniteImpl(double value)
121{
122#if POCO_OS == POCO_OS_AIX
123 return ::isinf(value) != 0;
124#else
125 return std::isinf(value) != 0;
126#endif
127}
128
129
130inline bool FPEnvironmentImpl::isInfiniteImpl(long double value)
131{
132#if POCO_OS == POCO_OS_AIX
133 return ::isinf((double) value) != 0;
134#else
135 return std::isinf((double) value) != 0;
136#endif
137}
138
139
140inline bool FPEnvironmentImpl::isNaNImpl(float value)
141{
142#if POCO_OS == POCO_OS_AIX
143 return ::isnan(value) != 0;
144#else
145 return std::isnan(value) != 0;
146#endif
147}
148
149
150inline bool FPEnvironmentImpl::isNaNImpl(double value)
151{
152#if POCO_OS == POCO_OS_AIX
153 return ::isnan(value) != 0;
154#else
155 return std::isnan(value) != 0;
156#endif
157}
158
159
160inline bool FPEnvironmentImpl::isNaNImpl(long double value)
161{
162#if POCO_OS == POCO_OS_AIX
163 return ::isnan((double) value) != 0;
164#else
165 return std::isnan((double) value) != 0;
166#endif
167}
168
169
170inline float FPEnvironmentImpl::copySignImpl(float target, float source)
171{
172 return copysignf(target, source);
173}
174
175
176inline double FPEnvironmentImpl::copySignImpl(double target, double source)
177{
178 return copysign(target, source);
179}
180
181
182} // namespace Poco
183
184
185#endif // Foundation_FPEnvironment_C99_INCLUDED
186