Uilian Ries 7b19559dfc Update Conan recipe
Signed-off-by: Uilian Ries <uilianries@gmail.com>
2020-02-25 15:32:12 +01:00
2019-11-02 12:55:22 +01:00
2019-11-16 18:30:44 +01:00
2020-02-25 15:32:12 +01:00
2019-11-16 18:29:56 +01:00
2019-05-08 09:53:07 -06:00
2018-10-01 11:44:35 +02:00
2019-05-18 13:20:21 +02:00
2019-10-05 07:30:32 +02:00
2020-02-25 15:32:12 +01:00
2020-02-25 15:32:12 +01:00
2019-11-17 07:40:02 +01:00

GitHub license Travis CI Conan stable Conan testing

mp-units - A Units Library for C++

Summary

Units is a compile-time enabled Modern C++ library that provides compile-time dimensional analysis and unit/quantity manipulation. The basic idea and design heavily bases on std::chrono::duration and extends it to work properly with many dimensions.

Here is a small example of possible operations:

// simple numeric operations
static_assert(10km / 2 == 5km);

// unit conversions
static_assert(1h == 3600s);
static_assert(1km + 1m == 1001m);

// dimension conversions
static_assert(1km / 1s == 1000mps);
static_assert(2kmph * 2h == 4km);
static_assert(2km / 2kmph == 1h);

static_assert(1000 / 1s == 1kHz);

static_assert(10km / 5km == 2);

Usage Overview

The library framework consists of a few concepts: quantities, units, dimensions and their exponents. From the user's point of view the most important is a quantity.

Quantity is a concrete amount of a unit for a specified dimension with a specific representation:

units::quantity<units::kilometre, double> d1(123);
auto d2 = 123km;    // units::quantity<units::kilometre, std::int64_t>

There are C++ concepts provided for each such quantity type:

template<typename T>
concept Length = QuantityOf<T, length>;

With that we can easily write a function template like this:

constexpr units::Velocity auto avg_speed(units::Length auto d, units::Time auto t)
{
  return d / t;
}

Concepts usage in the function above guarantee correctness enforced in compile-time and the guarantee that no unneeded intermediate conversions will ever be applied no matter which units the user will decide to pass to such function template:

using namespace units;

constexpr quantity<kilometre> distance(220);
constexpr quantity<hour> time(2);
constexpr Velocity speed = avg_speed(distance, time);

static_assert(std::same_as<std::remove_cvref_t<decltype(speed)>, quantity<kilometre_per_hour>>);
static_assert(speed.count() == 110);

The units library also tries really hard to printing any quantity in the most user friendly fashion:

std::cout << speed << '\n';
std::cout << quantity_cast<metre_per_second>(speed) << '\n';
std::cout << avg_speed(140.mi, 2h) << '\n';

Try it on Compiler Explorer.

Library design

mp-units library design rationale and documentation can be found in doc/DESIGN.md

Repository structure

That repository contains the following independent cmake-based projects:

  • ./src - header-only project for units
  • . - project used for development needs that wraps ./src project together with usage examples and unit tests
  • ./test_package - library installation and Conan package verification

Please note that the projects depend on cmake git submodule in the ./cmake/common subdirectory.

Building, testing, and installation

For a detailed information on project compilation, testing and reuse please refer to doc/INSTALL.md.

NOTE: This library as of now compiles correctly only with gcc-9.1 and newer.

Release notes

  • 0.4.0 Nov 17, 2019

    • Support for derived dimensions in exp added
    • Added pow() and sqrt() operations on quantities
    • units removed from a std::experimental namespace
    • Downcasting facility refactored so the user does not have to write the boilerplate code anymore
    • From now on base dimensions should inherit from base_dimension class template
    • Added unit symbols definitions to base_dimension and derived units
    • Added support for operator<< on quantity
    • fmt support added
    • Derived unit factory helpers refactored
    • Refactored the way prefixed units are defined
  • 0.3.1 Sep 18, 2019

    • cmcstl2 dependency changed to range-v3 0.9.1
  • 0.3.0 Sep 16, 2019 (CppCon 2019 design)

    • The design as described on CppCon 2019 talk (https://youtu.be/0YW6yxkdhlU)
    • Applied the feedback from the Cologne evening session
      • upcasting_traits renamed to downcasting_traits
      • Dimension template parameter removed from quantity
    • units moved to a std::experimental namespace
    • Leading underscore prefix removed from UDLs
    • Added a few more derived dimensions
    • meter renamed to metre
    • Missing operator* added
    • Predefined dimensions moved to a dedicated directory
    • dimension_ prefix removed from names of derived dimensions
    • cmcstl2 library updated to 2019.09.19
    • base_dimension is a value provided as const& to the exp type
    • integrated with Compiler Explorer
    • gsl-lite dependency removed
    • Fractional dimension exponents support added
    • QuantityOf concept introduced
    • quantity_cast<U, Rep>() support added
  • 0.2.0 July 18, 2019 (C++Now 2019 design)

    • The design as described on C++Now 2019 talk (https://youtu.be/wKchCktZPHU)
    • Added C++20 features supported by gcc-9.1 (std::remove_cvref_t, down with typename, std::type_identity)
    • Compile-time performance optimizations (type_list, common_ratio, ratio, conditional_t)
  • 0.1.0 May 18, 2019

    • Initial library release
    • Begin semantic versioning
    • The last version to work with gcc-8
Languages
C++ 71.3%
CMake 26.9%
C 1%
Python 0.8%