Skip to content

Commit 5354296

Browse files
ckormanyosjwakely
andauthored
Git issue 040 (#41)
* Correct C++11 <cmath> and docs * Update CI * Repair CI and more update docs * Try to repair CI * Try again to repair CI * Update docs again * cmath: Restore definitions of std::fpclassify This partially reverts 5a4c53d and adds the constants needed for it to work. Fixes: #40 * Repait lex-parser issue on GCC 15.1.0 * Manual merge jwakely <cmath> corrections * Update docs yet again --------- Co-authored-by: Jonathan Wakely <[email protected]>
1 parent 123a0d7 commit 5354296

File tree

5 files changed

+88
-36
lines changed

5 files changed

+88
-36
lines changed

.github/workflows/compile_examples.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ on:
88

99
jobs:
1010
unittests-linux-generic:
11-
runs-on: ubuntu-20.04
11+
runs-on: ubuntu-latest
1212
container:
1313
image: ghcr.io/modm-ext/modm-build-avr:latest
1414

@@ -19,7 +19,7 @@ jobs:
1919

2020
steps:
2121
- name: Check out repository
22-
uses: actions/checkout@v2
22+
uses: actions/checkout@v4
2323

2424
- name: Check environment
2525
run: |

README.md

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -238,12 +238,9 @@ and their directly relevant code sequences have been removed.
238238
Simple mechanisms such as those found in `<cassert>`
239239
and `<cerrno>`, however, remain mostly available.
240240

241-
- **`<atomic>`:** Even though the intended compilers are built with no threading,
242-
the `<atomic>` library and its use as a dependency has
243-
been removed. This means that atomic functions and
244-
atomic store/load functions are not available. So if you are sharing
245-
data in an operating system or mixed program/interrupt mode,
246-
self-written atomic primitives are needed.
241+
- **`<atomic>`:** The `<atomic>` library is being handled
242+
specifically in the draft of
243+
[avr-libstdcpp/pull/36](https://github.com/modm-io/avr-libstdcpp/pull/36).
247244

248245
- **`<random>`:** There is no source of entropy whatsoever on these platforms
249246
in their standard configuration. So `std::random_device`
@@ -280,12 +277,6 @@ The widths depend on the compiler command line options `-mdouble=32`
280277
`std::exp()` and the like will, therefore, have input and output
281278
widths according to these command line options.
282279

283-
- **`<cmath>`:** In compiler versions of `avr-gcc` 11 and higher,
284-
slight discrepancies in the signatures of functions like
285-
`isnan()`, `isinf()`, etc. seem to be in the process of being corrected.
286-
Future patches of math function signatures in `<cmath>`
287-
may be needed as the `<math.h>` header continues to evolve.
288-
289280
## C++20 `constexpr` support
290281

291282
The following is a rather advanced, highly useful topic.
@@ -337,18 +328,24 @@ int main()
337328
```
338329
339330
See also the [numeric.cpp](./examples/numeric/numeric.cpp) file
340-
in the [./examples/numeric](./examples/numeric) directory.
331+
in the [/examples/numeric](./examples/numeric) directory.
341332
342333
## Additional details
343334
344335
`avr-libstdcpp` is intended for a modern `avr-gcc`
345-
such as the 11.2 port available in the [modm-io project](https://github.com/modm-io/avr-gcc)
346-
repository. Tests show usability also for `avr-gcc` 10 through 13 (and beyond).
336+
such as the port available in the [modm-io project](https://github.com/modm-io/avr-gcc)
337+
repository. Tests show usability for `avr-gcc` 7 through 15.
338+
339+
This library has been checked for compatibility on `avr-gcc`
340+
with language standards C++11,14,17,20,23 and 2c.
347341
348-
Using the port way back to `avr-gcc` 5, however, does not work
342+
Using the port way back to `avr-gcc` 5 does not work
349343
at the moment with today's form of the checked-in library,
350-
as the older compiler's lexical parser is not capable of
351-
properly handling some of the library's template code.
344+
and `avr-gcc` 7 or higher is required.
345+
This is because the very old compiler lexical parsers are not capable
346+
of properly handling some of the library's template code.
347+
See also [avr-libstdcpp/issues/15](https://github.com/modm-io/avr-libstdcpp/issues/15)
348+
which is closed and includes justification for its closure.
352349
353350
## Licensing
354351
@@ -357,6 +354,6 @@ and the library include files in [`include/` and its subfolders](./include/)
357354
(with two exceptions for the sources, as mentioned below)
358355
are licensed under [GNU General Public License Version 3](./COPYING3) or higher.
359356
360-
The [example codes](./examples/) and two library source files
357+
All of the [example codes](./examples/) and also two library source files
361358
(namely `functexcept.cc` and `math.cc` in [`src/`](./src/))
362359
are subject to the terms of the [Mozilla Public License Version 2.0](./COPYING.MPLv2).

examples/cmath/cmath.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Christopher Kormanyos
2+
* Copyright (c) 2022, 2025, Christopher Kormanyos
33
*
44
* This file is part of the modm project.
55
*
@@ -33,7 +33,7 @@ auto integral
3333
real_value_type step = ((b - a) / 2U);
3434
real_value_type result = (real_function(a) + real_function(b)) * step;
3535

36-
const std::uint_fast8_t k_max = UINT8_C(32);
36+
constexpr std::uint_fast8_t k_max { UINT8_C(32) };
3737

3838
for(std::uint_fast8_t k = UINT8_C(0); k < k_max; ++k)
3939
{
@@ -80,12 +80,29 @@ auto is_close_fraction
8080
using floating_point_type = FloatingPointType;
8181

8282
using std::fabs;
83+
using std::fpclassify;
8384

84-
const floating_point_type ratio = fabs(floating_point_type((floating_point_type(1) * a) / b));
85+
const int fpc_a { fpclassify(a) };
86+
const int fpc_b { fpclassify(b) };
8587

86-
const floating_point_type closeness = fabs(floating_point_type(1 - ratio));
88+
bool result_is_ok { };
8789

88-
return (closeness < tol);
90+
if(fpc_b == FP_ZERO)
91+
{
92+
const floating_point_type closeness { (fpc_a == FP_ZERO) ? floating_point_type { 0 } : fabs(a - b) };
93+
94+
result_is_ok = (closeness < tol);
95+
}
96+
else
97+
{
98+
const floating_point_type ratio = fabs(floating_point_type((floating_point_type(1) * a) / b));
99+
100+
const floating_point_type closeness = fabs(floating_point_type(1 - ratio));
101+
102+
result_is_ok = (closeness < tol);
103+
}
104+
105+
return result_is_ok;
89106
}
90107

91108
// N[Pi, 51]
@@ -108,7 +125,7 @@ auto cyl_bessel_j(const std::uint_fast8_t n, const FloatingPointType& x) noexcep
108125
using std::sin;
109126
using std::sqrt;
110127

111-
const auto tol = sqrt(epsilon);
128+
const floating_point_type tol { sqrt(epsilon) };
112129

113130
const auto integration_result =
114131
detail::integral
@@ -121,7 +138,7 @@ auto cyl_bessel_j(const std::uint_fast8_t n, const FloatingPointType& x) noexcep
121138
return cos(x * sin(t) - (t * static_cast<floating_point_type>(n)));
122139
});
123140

124-
const auto jn = static_cast<floating_point_type>(integration_result / detail::pi_v<floating_point_type>);
141+
const floating_point_type jn { static_cast<floating_point_type>(integration_result / detail::pi_v<floating_point_type>) };
125142

126143
return jn;
127144
}
@@ -130,9 +147,9 @@ auto cyl_bessel_j(const std::uint_fast8_t n, const FloatingPointType& x) noexcep
130147

131148
auto main() -> int
132149
{
133-
using my_float_type = long double;
150+
using my_float_type = std::float_t;
134151

135-
static_assert((std::numeric_limits<my_float_type>::digits >= 24), "Error: Incorrect my_float_type type definition");
152+
static_assert((std::numeric_limits<my_float_type>::digits == 24), "Error: Incorrect my_float_type type definition");
136153

137154
constexpr my_float_type my_tol =
138155
static_cast<my_float_type>

include/bits/stl_iterator.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2150,6 +2150,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
21502150
const counted_iterator<_It2>& __y)
21512151
{ return __y._M_length <=> __x._M_length; }
21522152

2153+
private:
2154+
template<input_or_output_iterator _It2> friend class counted_iterator;
2155+
2156+
_It _M_current = _It();
2157+
iter_difference_t<_It> _M_length = 0;
2158+
21532159
friend constexpr iter_rvalue_reference_t<_It>
21542160
iter_move(const counted_iterator& __i)
21552161
noexcept(noexcept(ranges::iter_move(__i._M_current)))
@@ -2162,12 +2168,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
21622168
const counted_iterator<_It2>& __y)
21632169
noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
21642170
{ ranges::iter_swap(__x._M_current, __y._M_current); }
2165-
2166-
private:
2167-
template<input_or_output_iterator _It2> friend class counted_iterator;
2168-
2169-
_It _M_current = _It();
2170-
iter_difference_t<_It> _M_length = 0;
21712171
};
21722172

21732173
template<typename _It>

include/cmath

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
611611
#undef islessgreater
612612
#undef isunordered
613613

614+
#if !defined(FP_NAN) && !defined(FP_INFINITE) && !defined(FP_ZERO) \
615+
&& !defined(FP_SUBNORMAL) && !defined(FP_NORMAL)
616+
#define FP_NAN 0
617+
#define FP_INFINITE 1
618+
#define FP_ZERO 2
619+
#define FP_SUBNORMAL 3
620+
#define FP_NORMAL 4
621+
#elif !defined(FP_NAN) || !defined(FP_INFINITE) || !defined(FP_ZERO) \
622+
|| !defined(FP_SUBNORMAL) || !defined(FP_NORMAL)
623+
#error "Some floating-point number classification macros are missing."
624+
#error "Either define all of them or define none of them so that <cmath> can do it."
625+
#endif
626+
614627
#if __cplusplus >= 201103L
615628

629+
#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP
630+
constexpr int
631+
fpclassify(float __x)
632+
{ return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
633+
FP_SUBNORMAL, FP_ZERO, __x); }
634+
635+
constexpr int
636+
fpclassify(double __x)
637+
{ return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
638+
FP_SUBNORMAL, FP_ZERO, __x); }
639+
640+
constexpr int
641+
fpclassify(long double __x)
642+
{ return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
643+
FP_SUBNORMAL, FP_ZERO, __x); }
644+
#endif
645+
646+
#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_INT
647+
template<typename _Tp>
648+
constexpr typename __gnu_cxx::__enable_if<__is_integer<_Tp>::__value,
649+
int>::__type
650+
fpclassify(_Tp __x)
651+
{ return __x != 0 ? FP_NORMAL : FP_ZERO; }
652+
#endif
653+
616654
#ifndef __CORRECT_ISO_CPP11_MATH_H_PROTO_FP
617655
constexpr bool
618656
isfinite(float __x)

0 commit comments

Comments
 (0)