Skip to content

Commit

Permalink
Merge branch 'mpusz:master' into add_fma
Browse files Browse the repository at this point in the history
  • Loading branch information
NAThompson committed Dec 11, 2023
2 parents 51f8b47 + ccd9bb1 commit a3434c5
Show file tree
Hide file tree
Showing 13 changed files with 137 additions and 69 deletions.
30 changes: 15 additions & 15 deletions .github/workflows/ci-conan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,18 +116,18 @@ jobs:
lib: "libc++",
conan-config: "",
}
# - {
# name: "Apple Clang 13",
# os: macos-11,
# compiler:
# {
# type: APPLE_CLANG,
# version: "13.0",
# cc: "clang",
# cxx: "clang++",
# },
# conan-config: "",
# }
- {
name: "Apple Clang 15",
os: macos-13,
compiler:
{
type: APPLE_CLANG,
version: "15.0",
cc: "clang",
cxx: "clang++",
},
conan-config: "",
}
build_type: ["Release", "Debug"]

env:
Expand Down Expand Up @@ -174,11 +174,11 @@ jobs:
shell: bash
run: |
sudo apt install -y libc++-${{ matrix.config.compiler.version }}-dev libc++abi-${{ matrix.config.compiler.version }}-dev libunwind-${{ matrix.config.compiler.version }}-dev
- name: Select Xcode 13.0
if: matrix.config.compiler.type == 'APPLE_CLANG' && matrix.config.compiler.version == '13.0'
- name: Select Xcode version
if: matrix.config.compiler.type == 'APPLE_CLANG'
shell: bash
run: |
sudo xcode-select -s "/Applications/Xcode_13.0.app"
sudo xcode-select -s /Applications/Xcode_${{ matrix.config.compiler.version }}.app && /usr/bin/xcodebuild -version
- name: Install Ninja
shell: bash
run: |
Expand Down
29 changes: 15 additions & 14 deletions .github/workflows/ci-test-package-cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,17 +111,18 @@ jobs:
lib: "libc++",
conan-config: "",
}
# - {
# name: "Apple Clang 13",
# os: macos-11,
# compiler:
# {
# type: APPLE_CLANG,
# version: "13.0",
# cc: "clang",
# cxx: "clang++",
# },
# }
- {
name: "Apple Clang 15",
os: macos-13,
compiler:
{
type: APPLE_CLANG,
version: "15.0",
cc: "clang",
cxx: "clang++",
},
conan-config: "",
}
build_type: ["Release", "Debug"]

env:
Expand Down Expand Up @@ -167,11 +168,11 @@ jobs:
shell: bash
run: |
sudo apt install -y libc++-${{ matrix.config.compiler.version }}-dev libc++abi-${{ matrix.config.compiler.version }}-dev libunwind-${{ matrix.config.compiler.version }}-dev
- name: Select Xcode 13.0
if: matrix.config.compiler.type == 'APPLE_CLANG' && matrix.config.compiler.version == '13.0'
- name: Select Xcode version
if: matrix.config.compiler.type == 'APPLE_CLANG'
shell: bash
run: |
sudo xcode-select -s "/Applications/Xcode_13.0.app"
sudo xcode-select -s /Applications/Xcode_${{ matrix.config.compiler.version }}.app && /usr/bin/xcodebuild -version
- name: Install Ninja
shell: bash
run: |
Expand Down
34 changes: 33 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

## mp-units

### 2.1.0 <small>WIP</small> { id="2.1.0" }
### 2.2.0 <small>WIP</small> { id="2.2.0" }


### 2.1.0 <small>December 9, 2023</small> { id="2.1.0" }

- (!) feat: `inverse()` support added for dimensions, quantity_spec, units, and references
(`1 / s` will now create `quantity` and not a `Unit`)
- (!) feat: `quantity_point` does not provide `zero()` anymore
- (!) feat: `quantity_spec` and its kind should not compare equal
- (!) feat: mutating interface removed from `fixed_string`
- (!) feat: `common_type` with a raw value is not needed anymore as for a long time now raw values are
not convertible to the dimensionless quantities
- (!) feat: `symbol_text` definition simplified
- feat: `basic_fixed_string(const CharT*, std::integral_constant<std::size_t, N>)` constructor added
- feat: `isq::activity` added and `becquerel` definition updated to benefit from it
- feat: `gray` and `sievert` now have correct associated quantity kinds
Expand All @@ -18,16 +24,42 @@
- feat: interoperability with other libraries redesigned
- feat: equality for dimensions now will allow derived classes as well (but not from `derived_dimension`)
- feat: `zero_Fahrenheit` point origin added
- feat: users are now allowed to inherit their ow types from absolute point origins
- feat: equivalent point origins handling improved
- feat(example): unit symbols added to the currency example
- (!) refactor: `unit_symbol<fmt>(U)` signature refactored and the resulting text can now also be used at runtime
- (!) refactor: `make_xxx` factory functions replaced with two-parameter constructors
- (!) refactor: `unit_symbol` changed to `consteval`
- refactor: `in(U)` and `force_in(U)` now return `auto` to provide better diagnostics on clang
- refactor: `quantity` operators constraints refactored
- refactor: more type members added to `fixed_string` definition
- refactor: `unit_symbol_formatting` enums now use `std::int8_t` as a representation type
- fix: symbols of named dimensionless units with the ratio = 1 were not printed
- fix: iterator is now properly updated for all cases in `unit_symbol`
- fix: Fahrenheit conversion ratio was inverted
- fix: `CommonlyInvocableQuantities` was overconstrained for the current library design
- fix: `are_ingredients_convertible` now mandates explicit conversion for `To` dimensionless quantities
- fix: `quantity_point::point_for(PO)` constraints fixed
- fix(example): `latitude` and `longitude` fixed to include `0` for `N` and `E` respectively
- ci: clang-17 enabled
- ci: apple-clang-15 enabled
- ci: Added C++23 builds to the CI matrix
- docs: "Getting Started" chapters updated
- docs: "Basic Concepts" and "Interface Introduction" chapters updated
- docs: "Design Overview" chapter added and "Concepts" chapter reworked
- docs: "Output stream formatting" chapter updated
- docs: "Default formatting" chapter updated
- docs: "Derived unit symbols generation" chapter added
- docs: outdated affine space chapter updated
- docs: `CameCase` concept identifiers FAQ added
- docs: `gravitational_potential_energy` equation fixed on a graph
- docs: YouTube video link updated to the C++ on Sea 2023
- docs: ISO papers reference added to docs and README
- docs: a representation type in a dimensionless quantity FAQ fixed
- docs: titles added to some important admonitions
- docs: "Terms and Definitions" slightly updated
- docs: "canonical unit" added to glossary and its documentation in code was updated
- docs: Design overview graph updated

### 2.0.0 <small>September 24, 2023</small> { id="2.0.0" }

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
[![GitHub Workflow Documentation](https://img.shields.io/github/actions/workflow/status/mpusz/mp-units/documentation.yml?branch=master&label=Documentation)](https://github.com/mpusz/mp-units/actions?query=workflow%3ADocumentation+branch%3Amaster)

[![Conan stable](https://img.shields.io/conan/v/mp-units?label=ConanCenter&color=blue)](https://conan.io/center/mp-units)
[![Conan testing](https://img.shields.io/badge/mpusz.jfrog.io-2.1.0%3Atesting-blue)](https://mpusz.jfrog.io/ui/packages/conan:%2F%2Fmp-units/2.1.0)
[![Conan testing](https://img.shields.io/badge/mpusz.jfrog.io-2.2.0%3Atesting-blue)](https://mpusz.jfrog.io/ui/packages/conan:%2F%2Fmp-units/2.2.0)


# `mp-units` - A Physical Quantities and Units library for C++
# `mp-units` - A Quantities and Units library for C++

**The mp-units library might be the subject of ISO standardization for C++29. More on this can
be found in the following ISO C++ proposals:**

- [P1935: A C++ Approach to Physical Units](https://wg21.link/p1935),
- [P2980: A motivation, scope, and plan for a physical quantities and units library](https://wg21.link/p2980),
- [P2980: A motivation, scope, and plan for a quantities and units library](https://wg21.link/p2980),
- [P2981: Improving our safety with a physical quantities and units library](https://wg21.link/p2981),
- [P2982: `std::quantity` as a numeric type](https://wg21.link/p2982).

Expand Down
7 changes: 4 additions & 3 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
class MPUnitsConan(ConanFile):
name = "mp-units"
homepage = "https://github.com/mpusz/mp-units"
description = "A Physical Quantities and Units library for C++"
description = "A Quantities and Units library for C++"
topics = (
"units",
"dimensions",
Expand Down Expand Up @@ -74,8 +74,9 @@ def _min_cppstd(self):
def _minimum_compilers_version(self):
return {
"gcc": "11",
"clang": "16"
# , "apple-clang": "13", "msvc": "192"
"clang": "16",
"apple-clang": "15"
# , "msvc": "192"
}

@property
Expand Down
7 changes: 4 additions & 3 deletions docs/getting_started/installation_and_usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- please note that we observed some ICEs on gcc-11
- no problems with gcc-12.2+
- clang-16
- apple-clang-15


## Repository Structure and Dependencies
Expand Down Expand Up @@ -283,7 +284,7 @@ The following steps may be performed to obtain an official library release:

```ini title="conanfile.txt"
[requires]
mp-units/2.0.0
mp-units/2.1.0

[layout]
cmake_layout
Expand Down Expand Up @@ -340,7 +341,7 @@ with the following differences:

```ini title="conanfile.txt" hl_lines="2"
[requires]
mp-units/2.1.0@mpusz/testing
mp-units/2.2.0@mpusz/testing

[layout]
cmake_layout
Expand Down Expand Up @@ -443,5 +444,5 @@ The above will create a Conan package and run tests provided in _./test_package_
## Uploading **mp-units** Package to the Conan Server
```shell
conan upload -r <remote-name> --all mp-units/2.0.0@<user>/<channel>
conan upload -r <remote-name> --all mp-units/2.1.0@<user>/<channel>
```
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ The library source code is hosted on [GitHub](https://github.com/mpusz/mp-units)
- please note that we observed some ICEs on gcc-11
- no problems with gcc-12.2+
- clang-16
- apple-clang-15
41 changes: 29 additions & 12 deletions docs/users_guide/framework_basics/the_affine_space.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

The affine space has two types of entities:

- **_point_** - a position specified with coordinate values (e.g. location, address, etc.)
- **_vector_** - the difference between two points (e.g. shift, offset, displacement, duration, etc.)
- **_point_** - a position specified with coordinate values (e.g., location, address, etc.)
- **_vector_** - the difference between two points (e.g., shift, offset, displacement, duration, etc.)


!!! note
Expand Down Expand Up @@ -38,16 +38,33 @@ Here are the primary operations one can do in the affine space:
- multiply nor divide _points_ with anything else.


## _Points_ are more common than most of us imagine

_Point_ abstractions should be used more often in the C++ software.
They are not only about temperature or time. _Points_ are everywhere around us and should become
more popular in the products we implement. They can be used to implement:

- temperature points,
- timestamps,
- daily mass readouts from the scale,
- altitudes of mountain peaks on a map,
- current speed displayed on a car's speed-o-meter,
- today's price of instruments on the market,
- and many more.

Improving the affine space's _points_ intuition will allow us to write better and safer software.


## _Vector_ is modeled by `quantity`

Up until now, each time when we used a `quantity` in our code, we were modeling some kind of a
Up until now, each time we used a `quantity` in our code, we were modeling some kind of a
difference between two things:

- the distance between two points
- duration between two time points
- the difference in speed (even if relative to `0`)
- the distance between two points,
- duration between two time points,
- the difference in speed (even if relative to zero).

As we already know, a `quantity` type provides all operations required for _vector_ type in
As we already know, a `quantity` type provides all operations required for a _vector_ type in
the affine space.


Expand Down Expand Up @@ -327,7 +344,7 @@ The following operations are not allowed in the affine space:
- **adding** two `quantity_point` objects
- It is physically impossible to add positions of home and Denver airports.
- **subtracting** a `quantity_point` from a `quantity`
- What would it mean to subtract DEN airport location from the distance to it?
- What would it mean to subtract the DEN airport location from the distance to it?
- **multiplying/dividing** a `quantity_point` with a scalar
- What is the position of `2 *` DEN airport location?
- **multiplying/dividing** a `quantity_point` with a quantity
Expand All @@ -337,13 +354,13 @@ The following operations are not allowed in the affine space:
- **mixing** `quantity_points` of different quantity kinds
- It is physically impossible to subtract time from length.
- **mixing** `quantity_points` of inconvertible quantities
- What does it mean to subtract a distance point to DEN airport from the Mount Everest base camp
altitude?
- What does subtracting a distance point to DEN airport from the Mount Everest base camp
altitude mean?
- **mixing** `quantity_points` of convertible quantities but with unrelated origins
- How to subtract a point on our trip to CppCon measured relatively to our home location from
- How do we subtract a point on our trip to CppCon measured relatively to our home location from
a point measured relative to the center of the Solar System?

!!! important "Important: The affine space improves safety"

The usage of `quantity_point` and affine space types in general, improves expressiveness and
The usage of `quantity_point` and affine space types, in general, improves expressiveness and
type-safety of the code we write.
3 changes: 2 additions & 1 deletion example/include/geographic.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ namespace geographic {

inline constexpr struct equator : mp_units::absolute_point_origin<equator, mp_units::isq::angular_measure> {
} equator;
inline constexpr struct prime_meridian : mp_units::absolute_point_origin<prime_meridian, mp_units::isq::angular_measure> {
inline constexpr struct prime_meridian :
mp_units::absolute_point_origin<prime_meridian, mp_units::isq::angular_measure> {
} prime_meridian;


Expand Down
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
# SOFTWARE.

cmake_minimum_required(VERSION 3.19)
project(mp-units VERSION 2.1.0 LANGUAGES CXX)
project(mp-units VERSION 2.2.0 LANGUAGES CXX)

set(projectPrefix MP_UNITS_)

Expand Down
32 changes: 22 additions & 10 deletions src/utility/include/mp-units/math.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,19 +144,31 @@ template<auto R, typename Rep>
* @param b: Addend
* @return Quantity: The nearest floating point representable to ax+b
*/
template<auto R, auto S, typename Rep>
[[nodiscard]] constexpr quantity<R, Rep> fma(const quantity<R, Rep>& a, const quantity<S, Rep>& x,
const quantity<R, Rep>& b) noexcept

template<auto R, auto S, auto T, typename Rep1, typename Rep2, typename Rep3>
[[nodiscard]] constexpr QuantityOf<common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S),
get_quantity_spec(T))> auto
fma( // QuantityOf takes a QuantitySpec as an argument
const quantity<R, Rep1>& a, const quantity<S, Rep2>& x, const quantity<T, Rep3>& b) noexcept
requires requires {
fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), b.numerical_value_ref_in(b.unit));
} || requires {
std::fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), b.numerical_value_ref_in(b.unit));
}
common_quantity_spec(get_quantity_spec(R) * get_quantity_spec(S), get_quantity_spec(T));
} && // or just common_reference but I wanted to express that the quantity types must match here and we don't care
// too much about units
(get_unit(R) * get_unit(S) ==
get_unit(T)) && // units that we want to add are equivalent (have the same magnitude)
(
requires {
fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit),
b.numerical_value_ref_in(b.unit));
} ||
requires {
std::fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit),
b.numerical_value_ref_in(b.unit));
})
{
using std::fma;
return {static_cast<Rep>(
fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), b.numerical_value_ref_in(b.unit))),
R};
return quantity{
fma(a.numerical_value_ref_in(a.unit), x.numerical_value_ref_in(x.unit), b.numerical_value_ref_in(b.unit)), T};
}


Expand Down
4 changes: 2 additions & 2 deletions test/unit_test/runtime/math_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ TEST_CASE("'cbrt()' on quantity changes the value and the dimension accordingly"
REQUIRE(cbrt(8 * isq::volume[m3]) == 2 * isq::length[m]);
}

TEST_CASE("'fma()' on quantity changes the value and the dimension accordingly", "[math][cbrt]")
TEST_CASE("'fma()' on quantity changes the value and the dimension accordingly", "[math][fma]")
{
REQUIRE(fma(1.0 * isq::length[m], 2.0, 2.0 * isq::length[m]) == 4.0 * isq::length[m]);
REQUIRE(fma(1.0 * isq::length[m], 2.0 * one, 2.0 * isq::length[m]) == 4.0 * isq::length[m]);
}


Expand Down
Loading

0 comments on commit a3434c5

Please sign in to comment.