A type-safe, header-only C++23 library for temperature handling, modeled after std::chrono.
📚 Full API Documentation
Features
- Type-safe temperatures with distinct types for Celsius, Kelvin, and Fahrenheit
- Configurable precision (degree, decidegree, millidegree) plus real-valued (
double) types for display and computation
- Automatic conversions between scales and precisions
- Lossless implicit conversions (lossy conversions require explicit casts)
- Temperature deltas distinct from absolute temperatures
- User-defined literals for concise notation
- **
std::format support** (when available)
- Fully constexpr - all operations can be evaluated at compile time
Requirements
- C++23 compiler (GCC 13+, Clang 17+, MSVC 19.36+)
- MSVC users: The following compiler flags are required:
/std:c++latest - Enable C++23 features
/Zc:__cplusplus - Set __cplusplus macro correctly
/utf-8 - Treat source files as UTF-8 (for degree symbols)
Installation
CMake FetchContent
include(FetchContent)
FetchContent_Declare(
thermo
GIT_REPOSITORY https://github.com/cleishm/thermo-cpp.git
GIT_TAG v1.0.0
)
FetchContent_MakeAvailable(thermo)
target_link_libraries(your_target PRIVATE thermo::thermo)
vcpkg
vcpkg install cleishm-thermo-cpp
find_package(thermo CONFIG REQUIRED)
target_link_libraries(your_target PRIVATE thermo::thermo)
Manual
Copy the include/thermo/ directory to your project.
Usage
#include <thermo/thermo>
auto boiling = 100_c;
auto freezing = 32_f;
auto absolute_zero = 0_k;
auto new_temp = room_temp +
delta;
}
std::string disp = std::format("{:.1f}", reading);
std::string raw = std::format("{}", reading);
A temperature difference with a representation and precision.
An absolute temperature on a given scale.
User-defined literals for temperature types.
Temperature types and utilities.
std::string to_string(const delta< Rep, Precision > &d)
Renders a delta as its exact count with a precision-qualified unit, e.g.
constexpr auto difference(const temperature< Scale, Delta1 > &lhs, const temperature< Scale, Delta2 > &rhs) -> std::common_type_t< Delta1, Delta2 >
Returns the difference between two temperatures as a delta.
Temperature Types
Absolute Temperatures
| Type | Scale | Precision |
celsius | Celsius | 1°C |
decicelsius | Celsius | 0.1°C |
millicelsius | Celsius | 0.001°C |
kelvin | Kelvin | 1 K |
decikelvin | Kelvin | 0.1 K |
millikelvin | Kelvin | 0.001 K |
fahrenheit | Fahrenheit | 1°F |
decifahrenheit | Fahrenheit | 0.1°F |
millifahrenheit | Fahrenheit | 0.001°F |
With std::format, {} renders a temperature as its exact stored value with a precision-qualified unit (e.g. millicelsius{22500} → 22500m°C), while any floating-point format spec renders the value in scale degrees — no cast needed ({:.1f} of millicelsius{22534} → 22.5°C).
Temperature Deltas
| Type | Precision |
delta_celsius / delta_kelvin | 1° |
delta_decicelsius / delta_decikelvin | 0.1° |
delta_millicelsius / delta_millikelvin | 0.001° |
delta_fahrenheit | 1°F (= 5/9°C) |
delta_decifahrenheit | 0.1°F |
delta_millifahrenheit | 0.001°F |
Literals
20_c
200_dc
20000_mc
293_k
68_f
-123_dc
-40_f
5_Δc
5000_Δmc
9_Δf
Unary minus is available on relative scales (Celsius, Fahrenheit) so that negative literals like -123_dc work — the sign is applied to the value the literal produces, i.e. -(123_dc). It is deliberately not available on the absolute Kelvin scale, where a negated temperature would fall below absolute zero; -25_k is a compile error. Deltas are negatable on every scale.
Conversion Rules
Conversions follow the same philosophy as std::chrono:
- Implicit conversions are allowed when lossless (e.g.,
celsius → millicelsius)
- Explicit conversions are required when lossy (e.g.,
millicelsius → celsius)
- Cross-scale conversions consider both precision and scale offset
auto k2 = temperature_cast<kelvin>(
celsius{100});
Building Tests
cmake -B build -DTHERMO_BUILD_TESTS=ON
cmake --build build
ctest --test-dir build
Building with MSVC
When using MSVC, you must pass the required compiler flags:
cmake -B build -DTHERMO_BUILD_TESTS=ON -DCMAKE_CXX_FLAGS="/std:c++latest /Zc:__cplusplus /utf-8 /EHsc"
cmake --build build --config Release
ctest --test-dir build -C Release
License
MIT License - see [LICENSE](LICENSE) for details.