thermo 1.0.0
Type-safe temperature handling library modeled after std::chrono
Loading...
Searching...
No Matches
thermo

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)
  • 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> // or <thermo/thermo.hpp>
using namespace thermo;
using namespace thermo_literals;
// Absolute temperatures
celsius room_temp{20};
kelvin absolute = room_temp; // implicit conversion to higher precision
fahrenheit f = fahrenheit(room_temp); // explicit cross-scale conversion
// Using literals
auto boiling = 100_c;
auto freezing = 32_f;
auto absolute_zero = 0_k;
// Precision control
millicelsius precise{25500}; // 25.5°C
celsius coarse = celsius(precise); // explicit lossy conversion (truncates to 25°C)
millicelsius back = coarse; // implicit lossless conversion (25000 m°C)
// Temperature deltas (differences)
auto delta = 5_Δc; // 5 degree change
auto new_temp = room_temp + delta; // 25°C
// Computing differences
delta_celsius diff = difference(boiling, room_temp); // 80°C difference
// Comparisons work across precisions
if (millicelsius{20000} == celsius{20}) {
// true - same temperature, different precision
}
// String conversion
std::string s = to_string(room_temp); // "20°C"
A temperature difference with a representation and precision.
Definition thermo.hpp:120
An absolute temperature on a given scale.
Definition thermo.hpp:599
User-defined literals for temperature types.
Definition thermo.hpp:1023
Temperature types and utilities.
Definition thermo.hpp:37
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.
Definition thermo.hpp:770
std::string to_string(delta< int64_t > d)
Definition thermo.hpp:480

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

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

using namespace thermo_literals;
// Absolute temperatures
20_c // celsius(20)
200_dc // decicelsius(200) = 20.0°C
20000_mc // millicelsius(20000) = 20.000°C
293_k // kelvin(293)
68_f // fahrenheit(68)
// Temperature deltas
5_Δc // delta_celsius(5)
5000_Δmc // delta_millicelsius(5000)
9_Δf // delta_fahrenheit(9) = delta_celsius(5)

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
// Implicit (lossless)
millicelsius mc = celsius{20}; // OK: 20°C → 20000 m°C
millikelvin mk = millicelsius{0}; // OK: 0 m°C → 273150 mK
// Explicit required (lossy)
celsius c = celsius(millicelsius{1500}); // 1500 m°C → 1°C (truncates)
kelvin k = kelvin(celsius{0}); // 0°C → 273 K (truncates 273.15)
// Use temperature_cast for explicit conversions
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.