Skip to content

Add scale-gated unary minus to temperature (enables negative literals)#6

Merged
cleishm merged 1 commit into
mainfrom
feat/temperature-unary-minus
Jul 15, 2026
Merged

Add scale-gated unary minus to temperature (enables negative literals)#6
cleishm merged 1 commit into
mainfrom
feat/temperature-unary-minus

Conversation

@cleishm

@cleishm cleishm commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Problem

Creating a negative absolute-temperature literal, e.g. -123_dc, failed to compile.

In C++ a user-defined literal never receives the sign, so -123_dc parses as -(123_dc). 123_dc produces a decicelsius (a temperature), and temperature defined ++/--/+=/-= but no unary operator- — so negating the result was ill-formed. This affected every absolute-temperature literal (_c, _dc, _mc, _f, …); delta literals were unaffected since delta already has unary minus.

Fix

Add a constexpr unary operator- to temperature, gated on a new _is_relative_scale trait (Scale::offset != 0):

  • Celsius / Fahrenheit — zero sits above absolute zero → negation is meaningful → available.
  • Kelvin — zero is absolute zero → a negated temperature is always below absolute zero → compile error.

This is a purely type-level gate with zero runtime cost. It intentionally does not enforce value-level physicality (e.g. -300_c is still constructible), consistent with the rest of the library, which does not enforce an absolute-zero floor anywhere (kelvin{-5}, 50_k - 100_k, etc. already compile).

Behavior

Expression Result
-123_dc decicelsius(-123) = −12.3 °C ✅
-40_f fahrenheit(-40)
-25_k compile error

Tests

New negation section in thermo_test.cpp:

  • A has_unary_minus concept asserting availability on celsius/decicelsius/fahrenheit and unavailability on kelvin/decikelvin/millikelvin (the compile-time "it fails" check).
  • static_asserts + runtime TEST_CASE for values (-123_dc == -123, -(-5_c) == 5_c, …).

Full suite: 157 assertions, 30 test cases, all passing.

Version

Minor bump 2.0.0 → 2.1.0 (backward-compatible feature) across all four version files: CMakeLists.txt, idf_component.yml, docs/Doxyfile, vcpkg-port/vcpkg.json. The vcpkg port SHA512 is left untouched (set post-release, direct to main).

Enables negative absolute-temperature literals such as -123_dc, which
previously failed to compile: a user-defined literal never sees the sign,
so -123_dc parses as -(123_dc) and temperature had no unary operator-.

Unary minus is gated on _is_relative_scale, so it is available on Celsius
and Fahrenheit (zero above absolute zero) but a compile error on Kelvin,
where a negated temperature would fall below absolute zero. Deltas remain
negatable on every scale.
@cleishm
cleishm merged commit 23647c9 into main Jul 15, 2026
6 checks passed
@cleishm
cleishm deleted the feat/temperature-unary-minus branch July 15, 2026 20:06
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.

1 participant