Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CONSTEXPR_CHECK and CONSTEXPR_REQUIRE #76

Merged
merged 64 commits into from
Apr 8, 2023
Merged

Add CONSTEXPR_CHECK and CONSTEXPR_REQUIRE #76

merged 64 commits into from
Apr 8, 2023

Conversation

cschreib
Copy link
Member

@cschreib cschreib commented Mar 25, 2023

This PR introduces full support for compile-time testing. This includes compile-time evaluation and expression decomposition. For this purpose, two new sets of macros are included:

  • CONSTEVAL_* performs a check purely at compile-time, reports failure to compile as constant expression at compile-time (duh), and failure of the test at run-time. No code (other than the potential failure reporting) is executed at run-time, therefore this will not generate coverage data.
  • CONSTEXPR_* performs a check both at compile-time and run-time. Failure to compile as constant expression is still reported at compile-time, and failure of the test is still reported at run-time. But because the code is executed both at compile-time and at run-time, this will generate coverage data.

Although we already know at compile-time if a compile-time test passes or fail, the test failure is nonetheless only reported at run-time. This is done to follow the same reporting mechanism as the one set up for regular run-time tests (custom reporter, etc.).

To achieve this, I needed to implement constexpr integer and float serialization functions, since the C++20 STL does not provide anything usable at compile time (in C++23 we would be able to use std::to_chars, but only for integers and not for floats). Although integer serialization is pretty easy, float is not. The algorithm I used is based on fixed point arithmetic with 64 bit worth of digits in base 10. It is a simpler form of common state-of-the-art algorithms (e.g. Grisu). It is probably nowhere near as efficient, but on the plus side doesn't require storing large tables or complicated arbitrary precision types. To keep it simple, I only implemented exponential format with fixed precision (6 digits after the decimal point for float, and 15 for double). This achieves a perfect match to std::printf() for floats and 6 digits precision in 99.995% of the cases (when it fails, it's just the very last digit that is off by one). I don't have the stats for doubles.

I also needed to refactor the expression decomposer a little bit, to be constexpr-friendly. This had the nice side effect of improving compilation times slightly overall.

Closes #77.
Closes #60.

@codecov
Copy link

codecov bot commented Mar 25, 2023

Codecov Report

Merging #76 (d6cb28d) into main (793baf8) will increase coverage by 0.04%.
The diff coverage is 94.64%.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main      #76      +/-   ##
==========================================
+ Coverage   92.56%   92.61%   +0.04%     
==========================================
  Files           2        2              
  Lines        1049     1272     +223     
==========================================
+ Hits          971     1178     +207     
- Misses         78       94      +16     
Impacted Files Coverage Δ
include/snitch/snitch.hpp 95.03% <94.38%> (-1.03%) ⬇️
src/snitch.cpp 90.67% <100.00%> (-0.29%) ⬇️

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 69d813b...d6cb28d. Read the comment docs.

@cschreib cschreib merged commit f3a6398 into main Apr 8, 2023
@cschreib cschreib deleted the constexpr_check branch April 9, 2023 13:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
1 participant