Skip to content

Make the compare headers self-contained (move comparison_error to its own header) - #51

Merged
Lastique merged 5 commits into
boostorg:developfrom
reach2sayan:fix/compare-headers-self-contained
Sep 29, 2026
Merged

Lastique merged 5 commits into
boostorg:developfrom
reach2sayan:fix/compare-headers-self-contained

Conversation

@reach2sayan

@reach2sayan reach2sayan commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

The compare/*.hpp headers (certain, possible, lexicographic, set, tribool) throw comparison_error, but they only see the forward declaration in detail/interval_prototype.hpp.
The actual class is defined in interval.hpp, which they don't include. Since throw comparison_error(); doesn't depend on the template parameters, clang checks it right away and fails if the class hasn't been defined yet.

g++ doesn't complain.

In practice you would hit the issue with compare/tribool.hpp. The docs list it as an extension that interval.hpp doesn't include, so users include it themselves. If it ends up above interval/interval.hpp (which is what alphabetical include sorting gives you), clang fails:

 #include <boost/numeric/interval/compare/tribool.hpp>
 #include <boost/numeric/interval/interval.hpp>
compare/tribool.hpp:26:39: error: invalid use of incomplete type 'comparison_error'  detail/interval_prototype.hpp:20:7: note: forward declaration of 'boost::numeric::interval_lib::comparison_error'
Include order clang g++
compare/certain.hpp alone fails ok
compare/certain.hpp, then interval.hpp fails ok
interval.hpp, then compare/certain.hpp ok ok
compare/tribool.hpp, then interval/interval.hpp fails ok

Changes

nothing changes for code that already works.

  • comparison_error is marked BOOST_SYMBOL_VISIBLE so it can be caught across shared library boundaries with older gcc versions.

  • ext/x86_fast_rounding_control.hpp now includes what it uses (rounding.hpp and detail/x86_rounding_control.hpp). It was the only other public header that didn't compile on its own.

  • Self-contained header tests for every public header. A single test/self_contained_header.cpp is compiled once per header.
    Both b2 (path.glob-tree) and CMake (file(GLOB_RECURSE)) glob the headers and skip detail/. ext/x86_fast_rounding_control.hpp is x86-only by design, so its test only runs on x86: b2 uses check-target-builds /boost/architecture//x86 and CMake checks CMAKE_SYSTEM_PROCESSOR.

  • The tests are off by default. Set the BOOST_NUMERIC_INTERVAL_TEST_SELF_CONTAINED_HEADERS environment variable for b2, or
    -DBOOST_NUMERIC_INTERVAL_TEST_SELF_CONTAINED_HEADERS=ON for CMake.
    CI turns them on in one b2 job (clang-22) and one CMake job (ubuntu, shared, Debug).

@codecov

codecov Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 81.90%. Comparing base (d9ad29a) to head (aa48982).

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff            @@
##           develop      #51   +/-   ##
========================================
  Coverage    81.90%   81.90%           
========================================
  Files           22       23    +1     
  Lines          923      923           
  Branches       373      373           
========================================
  Hits           756      756           
  Misses         160      160           
  Partials         7        7           
Files with missing lines Coverage Δ
include/boost/numeric/interval/compare/certain.hpp 66.66% <ø> (ø)
...e/boost/numeric/interval/compare/lexicographic.hpp 100.00% <ø> (ø)
...nclude/boost/numeric/interval/compare/possible.hpp 66.66% <ø> (ø)
include/boost/numeric/interval/compare/set.hpp 100.00% <ø> (ø)
include/boost/numeric/interval/compare/tribool.hpp 100.00% <ø> (ø)
...boost/numeric/interval/detail/comparison_error.hpp 100.00% <100.00%> (ø)
include/boost/numeric/interval/interval.hpp 93.57% <ø> (-0.18%) ⬇️

Continue to review full report in Codecov by Harness.

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@reach2sayan

Copy link
Copy Markdown
Contributor Author

@Lastique Would you please review this - may seem lots of file - but I think I may have a point

Comment thread include/boost/numeric/interval/detail/comparison_error.hpp Outdated
Comment thread test/CMakeLists.txt Outdated
Comment on lines +29 to +33
# Each compare header must compile on its own (clang rejects them otherwise).
foreach(h certain possible lexicographic set tribool)
boost_test(TYPE compile SOURCES compare_${h}_self_contained.cpp)
endforeach()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say every public header must be self-contained, not just compare headers.

Instead of listing headers and duplicating the test .cpp, use a glob and a single tes .cpp. For example: Jamfile, .cpp. I don't have a CMakeLists.txt example at hand, but it should be easy to do with file(GLOB).

Note that the self-contained tests are better be disabled by default. Enable them only in one or two jobs in CI. These tests tend to take a long time, especially on Windows, and there's no point in running them in every CI configuration. (Do note that the tests will run each time for debug/release and static/dynamic link, i.e. 4 times, if your CI job requests that.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Lastique Should be better now

compare/{certain,possible,lexicographic,set,tribool}.hpp throw comparison_error, but only see its
  forward declaration in detail/interval_prototype.hpp. Clang rejects them when they are included standalone (incomplete type 'comparison_error'); g++ accepts them. These
  compile tests fail on clang until that is fixed.
…self-contained

The compare headers throw comparison_error but only saw its forward declaration in detail/interval_prototype.hpp; the definition lived in interval.hpp. Move it to detail/comparison_error.hpp and include that from interval.hpp and from compare/{certain,possible,lexicographic,set,tribool}.hpp. The class itself is unchanged.
@reach2sayan
reach2sayan force-pushed the fix/compare-headers-self-contained branch from 5b0467a to aa48982 Compare September 29, 2026 16:51
@Lastique
Lastique merged commit e9c103a into boostorg:develop Sep 29, 2026
56 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants