A compile-time enabled Modern C++ library that provides compile-time dimensional analysis and unit/quantity manipulation.

Overview

GitHub license Conan CI CMake CI GitHub Workflow Documentation Conan stable Conan testing

mp-units - A Units Library for C++

The mp-units library is the subject of ISO standardization for C++23/26. More on this can be found in ISO C++ paper P1935 and CppCon 2020 talk. We are actively looking for parties interested in field trialing the library.

Documentation

An extensive project documentation including installation instructions and user's guide can be found on mp-units GitHub Pages.

TL;DR

mp-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:

#include <units/isq/si/area.h>
#include <units/isq/si/frequency.h>
#include <units/isq/si/length.h>
#include <units/isq/si/speed.h>
#include <units/isq/si/time.h>

using namespace units::isq::si::references;

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

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

// dimension conversions
inline constexpr auto kmph = km / h;
static_assert(1 * km / (1 * s) == 1000 * (m / s));
static_assert(2 * kmph * (2 * h) == 4 * km);
static_assert(2 * km / (2 * kmph) == 1 * h);

static_assert(2 * m * (3 * m) == 6 * m2);

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

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

Try it on the Compiler Explorer.

This library requires some C++20 features (concepts, classes as NTTPs, ...). Thanks to them the user gets a powerful but still easy to use interface and all unit conversions and dimensional analysis can be performed without sacrificing on accuracy. Please see the below example for a quick preview of basic library features:

#include <units/format.h>
#include <units/isq/si/international/length.h>
#include <units/isq/si/international/speed.h>
#include <units/isq/si/length.h>
#include <units/isq/si/speed.h>
#include <units/isq/si/time.h>
#include <units/quantity_io.h>
#include <iostream>

using namespace units::isq;

constexpr Speed auto avg_speed(Length auto d, Time auto t)
{
  return d / t;
}

int main()
{
  using namespace units::isq::si::literals;
  using namespace units::isq::si::references;
  using namespace units::aliases::isq::si::international;

  constexpr Speed auto v1 = 110 * (km / h);
  constexpr Speed auto v2 = mi_per_h(70.);
  constexpr Speed auto v3 = avg_speed(220_q_km, 2_q_h);
  constexpr Speed auto v4 = avg_speed(si::length<si::international::mile>(140), si::time<si::hour>(2));
#if UNITS_DOWNCAST_MODE == 0
  constexpr Speed auto v5 = quantity_cast<si::speed<si::metre_per_second>>(v3);
  constexpr Speed auto v6 = quantity_cast<si::dim_speed, si::metre_per_second>(v4);
#else
  constexpr Speed auto v5 = quantity_cast<si::speed<si::metre_per_second>>(v3);
  constexpr Speed auto v6 = quantity_cast<si::metre_per_second>(v4);
#endif
  constexpr Speed auto v7 = quantity_cast<int>(v6);

  std::cout << v1 << '\n';                                  // 110 km/h
  std::cout << v2 << '\n';                                  // 70 mi/h
  std::cout << fmt::format("{}", v3) << '\n';               // 110 km/h
  std::cout << fmt::format("{:*^14}", v4) << '\n';          // ***70 mi/h****
  std::cout << fmt::format("{:%Q in %q}", v5) << '\n';      // 30.5556 in m/s
  std::cout << fmt::format("{0:%Q} in {0:%q}", v6) << '\n'; // 31.2928 in m/s
  std::cout << fmt::format("{:%Q}", v7) << '\n';            // 31
}

Try it on the Compiler Explorer.

Comments
  • Poll: Dimensionless quantity (quantity of dimension one)

    Poll: Dimensionless quantity (quantity of dimension one)

    ISO 80000-1:2009(E)

    • Quantity for which all the exponents of the factors corresponding to the base quantities in its quantity dimension are zero.
    • The measurement units and values of quantities of dimension one are numbers, but such quantities convey more information than a number.
    • Some quantities of dimension one are defined as the ratios of two quantities of the same kind.

    Assuming:

    auto q1 = quantity<metre, double>() / quantity<metre, double>();
    auto q2 = quantity<second, double>() / quantity<second, double>();
    

    What the result should be?

    (please vote only once by clicking on the correct bar above)

    • Option 1 (current library design)

      static_assert(std::is_same_v<q1, double>);
      static_assert(std::is_same_v<q2, double>);
      auto q = q1 + q2;
      static_assert(std::is_same_v<q, double>);
      
    • Option 2

      static_assert(std::is_same_v<q1::dimension, dimension<>>);
      static_assert(std::is_same_v<q2::dimension, dimension<>>);
      auto q = q1 + q2;
      static_assert(std::is_same_v<q::dimension, dimension<>>);
      
    • Option 3

      static_assert(std::is_same_v<q1::dimension, dimension<exp<base_dim_length, 0>>>);
      static_assert(std::is_same_v<q2::dimension, dimension<exp<base_dim_time, 0>>>);
      // auto q = q1 + q2;  // does not compile
      

      Please note that in such a case:

      auto q1 = 10mps * 2s;     // length
      auto q2 = q1 / 2m;        // dimensionless<length>
      auto q = 10mps * 2s / 2m; // dimensionless<velocity>
      
    help wanted Polls 
    opened by mpusz 46
  • What are the minimum requirements for a standard units library?

    What are the minimum requirements for a standard units library?

    Q: What are the minimum requirements for a standard units library?

    A: Modelling the S.I. system as closely as possible. The way that is implemented is not really relevant. The S.I is a global standard.

    Problem: Unfortunately the general user has no voice on the c++ committee.

    I worked on a quantity /units library for boost since way back in 2003. I need a library that modelled S.I units.

    My original problem was that I was working on an app to design small wind turbines, using doubles for quantities and getting fed up with checking what units each variable was in, which wasted a lot of time. The library I wrote later solved that issue very nicely. All Si units.

    I see that @mpusz started around the same place except for working on a gliding app. All SI units. https://github.com/mpusz/Condor2Nav I understand the motive exactly.

    Again engineering, not Theoretical Physics. All S.I. Units.

    The library that can (apparently) do all that that Theoretical Phyiscists want is now in Boost but what was created there didn't actually elegantly answer a problem for which there was a general need to be solved - modelling the SI. For the general user, Boost.Units it is way to cumbersome and hard to understand and use. It is time to tell the Physicists to go away and fix their Units library on Boost and to produce their own globally recognised standard, before we spend more of the general users time arguing about their exotic needs.

    That theme of a Physicists making impossible demands about their "essential needs" then disappearing once they are met needs to be remembered. General users need SI units more than they need Natural units. Remember there is no global standard for Natural units. Each physicist enjoys showing why their own version is superior. A library for the general user just doesn't need to support that. And we dont have time to argue about it.

    mp-units should drastically limit its scope so that it caters for the average user who uses SI units, not "smart people", language lawyers or physicists, else there is no way it will or should get in to the C++ standard. What is left will be easier to maintain and certainly more likely to write standard documentation for.

    It would be great if mp_units was a general framework but in practise the minimum is that there needs to be the ability to work with SI quantities, that is simple and intuitive to use. Ultimately the standard is about the interface not the implementation.

    It is time to pare away the std units candidate to the bare minimum requirements

    Just model the SI system, following the docs as closely as possible ( so no angle as dimension for example). Stick to same Rep concept as std::chronos::duration. If anyone complains that the Rep type is no good, tell them to provide a solution fixing it for chrono duration.

    opened by kwikius 28
  • Use Magnitude instead of ratio in unit implementations

    Use Magnitude instead of ratio in unit implementations

    This PR doesn't aim to convert every last use case. Rather, the goal is to perform the smallest "reasonable" change such that the repo still builds.

    We bundle a few auxiliary changes which could have been separate PRs, but which I included here to reduce the total time-to-land. To reduce reviewers' cognitive load, I've retained them as separate "checkpoint commits". Reviewers can start at the first commit and step through for ease of reading. These auxiliary changes include:

    • Supporting subtraction and spaceship operators in ratio

    • Implementing the "common Magnitude" functionality, which is equivalent to the "largest even divisor" logic we've borrowed from std::chrono in every applicable case, but which is simpler for Magnitudes

    • Loosening the requirements on the Rep of a Magnitude, which is necessary to maintain support for non-is_arithmetic Reps. NOTE: there is some remaining work here to express everything in terms of treat_as_floating_point, which we can either do in this PR, or later, as reviewers prefer.

    The "bulk" of the PR simply performs fairly mechanical migrations from ratio to as_magnitude<ratio>() in various template arguments. Some corner cases and concepts (e.g., UnitRatio) simply melt away, because we don't need them in a Magnitude-based world. The only "asterisk" in this migration is a few test cases in the formatting, where the current implementation produces an equivalent but different representation. I've commented these out, and we can deal with them later.

    Follow-on work includes:

    • Hunting down remaining uses of ratio in template arguments
    • Removing exp
    • Making degrees and revolutions for angle units

    Partially addresses #300.

    opened by chiphogg 27
  • Added ASCII-only output support

    Added ASCII-only output support

    Dear Mr. Mateusz Pusz,

    Much of C++ template programming with C++20 features is still a bit overwhelming for me at this point in time.

    I do not fully understand how the library is written, but I can rely on what I already know about it and my intuition to understand certain parts. I think I get the gist of it.

    I am using this library for SPICE circuit generation using custom templates. I have generator classes that are responsible for rendering the custom templates into SPICE circuit text.

    Initializing my generator: RCCircuitGenerator generator {5ns, 2ms, 5V, 1ms, 10kR, 10nF};

    The formatting string for the line starting with "RLOAD" (see below) looks like this: RLOAD 1 2 {:%Q%q}

    The following SPICE RC circuit text would be generated:

    RC_CIRCUIT
    .TRAN 5ns 2ms
    VSRC 1 0 PULSE 0 5V 0 0 0 1ms
    RLOAD 1 2 10kΩ
    CCHARGE 2 0 10nF
    .END
    

    However, the SPICE simulator library I am using, ngspice, expect ASCII encoding. The simulation crashes when this circuit is passed to the library.

    With the changes I have provided, when the formatting string for the line starting with "RLOAD" looks like this: RLOAD 1 2 {:%Q%a}

    Then the following SPICE RC circuit text would be generated:

    RC_CIRCUIT
    .TRAN 5ns 2ms
    VSRC 1 0 PULSE 0 5V 0 0 0 1ms
    RLOAD 1 2 10kohm
    CCHARGE 2 0 10nF
    .END
    

    And the SPICE simulation then works.

    I hope that my modifications adhere to the style and philosophy of this library as closely as possible.

    Please let me know of any modifications you would like to me perform first if you would like to merge this pull request eventually.

    Thank you very much.

    Ramzi Sabra

    opened by yasamoka 27
  • Raise coherent quantity to fractional power doesnt give correct result.

    Raise coherent quantity to fractional power doesnt give correct result.

    Raise coherent quantity to fractional power doesnt give correct result. Personally I am not so bothered about incoherent quantities but for coherent quantities this can be done better.

    Currently doesnt give the correct answer:

    https://godbolt.org/z/6bgkEK

    For coherent quantities the multiplier of the result should remain as one ,and the exponent should be adjusted ( so for square root divide exponent by 2, and in fact for pow<R>(q) the result exponent is simply multiply the exponent by R ( so for square root multiply by 1/2, for cube 1/3, for pow<3/2> multiply by 3/2. If the exponent is a rational number then it can represent the quantity raised to fractional power correctly and exactly .

    bug help wanted 
    opened by kwikius 26
  • Hidden Friends issue

    Hidden Friends issue

    Hidden Friends are good because they help with overload resolution and thus are suggested for usage in a modern C++ design.

    However, for quantity it produces issues with implicit conversions. The second assert of the following code compiles fine even though it shouldn't: https://godbolt.org/z/kSrqHT.

    When non-friend version is used it correctly fails to compile: https://godbolt.org/z/32s4cj

    We could provide template parameters for both arguments of a hidden friend implementation: https://godbolt.org/z/2uMsPB. However, in this case we end up with an ambiguous overload set. So we have to constrain it: https://godbolt.org/z/RKaopR. With this, we achieved what we wanted but with a cost of a more complicated signature.

    Should we provide constrained hidden friend version of the operator or non-friend one with all its overload resolution issues?

    enhancement help wanted 
    opened by mpusz 24
  • Scalar concept should be renamed

    Scalar concept should be renamed

    The 'units::Scalar' concept definition has nothing to do with any external definition of scalar and is very misleading, https://github.com/mpusz/units/blob/master/src/include/units/quantity.h#L63 should be renamed to RegularNotQuantity or something similar especially since Vector is an allowed rep type https://github.com/mpusz/units/blob/master/example/linear_algebra.cpp#L205

    opened by kwikius 21
  • Have you considered to add a dimension-point in the design?

    Have you considered to add a dimension-point in the design?

    std::chrono is based on the difference between a point on the time dimension (time_point) and the difference between two such points, a quantity (a duration for the time dimension).

    Do you plan to add such a dimension-point in your library?

    enhancement question 
    opened by viboes 21
  • Will not compile with -fno-exceptions

    Will not compile with -fno-exceptions

    I am working on a bare metal ARM-cortex M project using this units library.

    I just updated to the head of your main branch and changes in src/core/include/units/magnitude.h are causing compilation errors. Specifically the use of throw statements. I have it working now by guarding each throw with the macro

    #if __has_feature(cxx_exceptions) || defined(__cpp_exceptions) || \
        (defined(_MSC_VER) && defined(_CPPUNWIND)) || \
        defined(__EXCEPTIONS)
    

    EDIT: I think this may not be related to -fno-exceptions, since it does compile if I make some small code changes. I am trying to fins the root cause and will update/close issue when I find out more (see my comments below).

    Compiler: arm-none-eabi-11.3.1-rel1 (latest ARM provided toolchain) arch: ARM-v8M-baseline (M23)

    opened by CrustyAuklet 20
  • Support seamless interop between `ratio` and rational `Magnitude`

    Support seamless interop between `ratio` and rational `Magnitude`

    We provide two new functions, numerator(m) and denominator(m), for a Magnitude m. They fulfill the following conditions:

    1. numerator(m) and denominator(m) are always integer Magnitudes.
    2. If m is rational, then m == numerator(m) / denominator(m).

    If m is not rational, then the numerator and denominator are not especially meaningful (there is no uniquely defined "leftover irrational part"). However, we choose a convention that matches how humans would write a mixed number. For example, sqrt(27/16) would have a numerator of 3, denominator of 4, and a "leftover part" of sqrt(3), matching the "human" way of writing this as [(3 * sqrt(3)) / 4]. This has no use yet, but it may later be useful in printing the Magnitude of an anonymous Unit for end users.

    To further reduce friction for the upcoming migration, we provide a conversion from a Magnitude to a ratio. We restrict this operation to rational Magnitudes, and guard this with a static_assert.

    opened by chiphogg 19
  • Add vector space representation for magnitudes

    Add vector space representation for magnitudes

    This is the beginning of the implementation for #300, laying the first foundations. This seems like a good point to check in and align on direction before we get too far along. For general context:

    Things we include here:

    • Concepts for Magnitude, and BasePower (a Magnitude is made up of a canonicalized parameter pack of BasePowers).
    • End user interfaces for making magnitudes:
      • as_magnitude<ratio>(): the main way to make a Magnitude from a rational number. This handles the "heavy lifting" of converting to a prime factorization.
      • base_power<T>{ratio}: we handle irrational bases by introducing a type T, with a static long double member value which must be positive.
    • Enhanced ratio functionality: addition, negation, and implicit construction.

    Work yet undone:

    • A mechanism for applying a magnitude to a given value. (We'll probably want to break out the rational and irrational parts separately, so we can give exact results as often as possible. We'll also want to think carefully about what types we use in intermediate computations---for example, not everyone will want to use long double, and even double can be problematic for some embedded applications.)
    • Actually migrating existing uses to use Magnitude instead of ratio.

    Once we get to something that looks like the right direction, I can flesh out these other items.

    opened by chiphogg 19
  • Determining the best way to create a quantity

    Determining the best way to create a quantity

    Today, after a code review comment, I added a second syntax that creates a quantity in V2 design:

    static_assert(120 * isq::distance[km] / (2 * isq::duration[h]) == 60 * isq::speed[km / h]);  // #1
    static_assert(isq::distance(120, km) / isq::duration(2, h) == isq::speed(60, km / h));       // #2
    

    You can find diff with more examples here: https://github.com/mpusz/units/pull/391/commits/858cbb472fe320fdb648fb976f5f026145ba8009.

    For now, we have two of those, but I would like to decide which one is better ASAP and remove the other one. Please review the above commit and share your opinion.

    help wanted high priority 
    opened by mpusz 3
  • The behavior of raw data accessors

    The behavior of raw data accessors

    As @JohelEGP noticed in https://github.com/mpusz/units/issues/411#issuecomment-1362809717, current accessors remove all encapsulation. Should we remove lvalue overload so the only remaining would be:

      [[nodiscard]] constexpr const rep& number() const& noexcept { return number_; }
      [[nodiscard]] constexpr rep&& number() && noexcept { return std::move(number_); }
      [[nodiscard]] constexpr const rep&& number() const&& noexcept { return std::move(number_); }
    
    opened by mpusz 0
  • Structural types

    Structural types

    Structural types are the types that can be used as NTTPs. quantity and quantity_point do not satisfy a current definition of a structural type as it requires a class to have public data members. This means that we cannot put them in template parameters which could be really handy in some cases.

    Should we make a data member public (at least until the C++ language will not extend the definition to allow private members as well)?

    opened by mpusz 3
  • Implicit construction of quantities from a value

    Implicit construction of quantities from a value

    With the new design a following change was needed:

    using state = kalman::state<quantity<isq::position_vector[m]>, quantity<isq::velocity[m / s]>>;
    -const state initial = {30 * km, 40 * (m / s)};
    +const state initial = {30 * isq::position_vector[km], 40 * isq::velocity[m / s]};
    

    As @JohelEGP correctly noticed that:

    seems like an unfortunate deviation from the general idea of ISO 80000-1, 7.1.4 “Expression for quantities” and 7.2 “Names and symbols for units”'s 7.2.1 “General”. Since state is already strongly typed, could the previous iterator be made to work? I think it's preferable if C++ code looked like the quantity expression. Strong typing could be added without affecting it.

    The intention seems to be for "30 km" to not be decorated with anything other than the number and the unit. In C++, we use * out of necessity. But this shouldn't be the place to specify the quantity.

    I was thinking of permitting x * km, where x is a function parameter, to initialize any quantity of dimension L (besides the requirements on the representation and the unit).

    Discussion of alternatives

    A number and a unit are not enough to define a quantity. Even adding a dimension was found to be deficient. This was one of the biggest issues with the old "references".

    Regarding function parameters, I am not the biggest fan of this syntax in general. Consider:

    void foo(double a, double b)
    {
      quantity<isq::distance[km]> l = a * m;
      quantity<isq::duration[h]> d = b * s;
      quantity<isq::speed<km / h>> speed = l / d;
    }
    

    This looks really cryptic to me and might be a source of confusion. I would much prefer people to type:

    void foo(double a, double b)
    {
      auto l = a * isq::distance[m];
      auto d = b * isq::duration[s];
      quantity<isq::speed<km / h>> speed = l / d;
    }
    

    So I do not think that there is a problem here. Additionally, to support such a scenario, we will have to introduce yet another type/abstraction that would handle such a scenario and make a quantity implicitly constructible from it. I am not so sure if it is worth it.

    Another point here worth considering is that right now, we do the following to define a scaled unit:

    inline constexpr struct minute : named_unit<"min", mag<60> * second> {} minute;
    

    and I hope that if expression aliases became a part of the C++ language, we will write:

    inline constexpr struct minute : named_unit<"min", 60 * second> {} minute;
    

    so a 60 * s is just yet another scaled unit and not a quantity value.

    Proposed solution

    However, there is another even simpler solution to the problem. For now, the quantity cannot be implicitly constructible from the representation type, so we cannot just leave numbers to initialize the struct.

    I believe that the creation of quantities from raw number arguments is quite rare and happens only on the boundaries of strongly typed engines. On the other hand, the initialization of some quantities from constant values will happen quite often, and sometimes, a quantity will be packed inside of the aggregate. Until now, we were not able to initialize such aggregates in an efficient way, and now with the V2 design it looks like this:

    quantity<isq::length[m]> vec[3] = { 1 * isq::length[m], 2 * isq::length[m], 3 * isq::length[m] };
    std::tuple<quantity<isq::length[m]>, quantity<isq::time[s]>> t = { 1 * isq::length[m], 1 * isq::time[s] };
    

    If we would make the constructor implicit, then the above could be rewritten as:

    quantity<isq::length[m]> vec[3] = { 1, 2, 3 };
    std::tuple<quantity<isq::length[m]>, quantity<isq::time[s]>> t = { 1, 1 };
    

    which I think could be a big improvement here.

    On the other hand, it would allow something like:

    void foo(quantity<isq::length[m]>);
    
    int main()
    {
      foo(3);
    }
    

    which I am not so sure if it is a great idea, although I am ready to discuss and consider it.

    Any ideas, thoughts, or comments are welcome here.

    opened by mpusz 4
  • Division of vector quantities?

    Division of vector quantities?

    Acceleration is a change of velocity over time (a = V / t). Acceleration and velocity are defined as vector quantities, whereas time is scalar.

    If I want to calculate t = V / a, it is impossible if representation types of a and V are linear algebra vectors as it is impossible to divide two vectors. Additionally, the characteristics of a derived quantity of velocity divided by acceleration is vector as well so it will not allow assigning to a scalar time.

    This is a simple and common case but also so complicated now after #405. How to handle that?

    opened by mpusz 3
  • `min()`, `max()`, `epsilon()` and others

    `min()`, `max()`, `epsilon()` and others

    Consider providing a partial specialization for std::numeric_limits to provide all the numeric properties of underlying representation types. Remove min() and max() from quantity and also remove standalone epsilon() from math.h.

    The only problem is what to do with the remaining zero() and one() as those are not provided via std::numeric_limits.

    opened by mpusz 0
Releases(v0.7.0)
  • v0.7.0(May 11, 2021)

    • (!) refactor: ScalableNumber renamed to Representation
    • (!) refactor: output stream operators moved to the units/quantity_io.h header file
    • (!) refactor: Refactored the library file tree
    • (!) refactor: quantity::count() renamed to quantity::number()
    • (!) refactor: data system renamed to isq::iec80000 (quantity names renamed too)
    • (!) refactor: *deduced_unit renamed to *derived_unit
    • (!) refactor: got rid of a noble_derived_unit
    • refactor: quantity (kind) point updated to reflect latest changes to quantity
    • refactor: basic concepts, quantity and quantity_cast refactored
    • refactor: abs() definition refactored to be more explicit about the return type
    • feat: quantity (point) kind support added (thanks @johelegp)
    • feat: quantity references support added (thanks @johelegp)
    • feat: quantity aliases support addded
    • feat: interoperability with std::chrono::duration and other units libraries
    • feat: CTAD for dimensionless quantity added
    • feat: modulation_rate support added (thanks @go2sh)
    • feat: SI prefixes for isq::iec80000 support added (thanks @go2sh)
    • feat: a possibility to disable quantity UDLs support with UNITS_NO_LITERALS preprocessor define
    • feat: a support to define ISQ derived dimensions in terms of different number or order of components
    • perf: preconditions check do not influence the runtime performance of a Release build
    • perf: quantity_cast() generates less assembly instructions
    • perf: temporary string creation removed from quantity::op<<()
    • perf: value initialization for quantity value removed (left with a default initialization)
    • perf: limited the equivalent trait usage
    • perf: limited the C++ Standard Library headers usage
    • perf: rvalue references support added for constructors and getters
    • (!) fix: exp() has sense only for dimensionless quantities
    • (!) fix: dim_torque now properly divides by an angle (instead of multiply) + default unit name change
    • fix: quantity's operators fixed to behave like the underlying types do
    • fix: quantity_cast() fixed to work correctly with representation types not convertible from std::intmax_t
    • fix: ambiguous case for empty type list resolved
    • fix: downcasting facility for non-default-constructible types
    • fix: restore user-warnings within the library implementation
    • fix: the text symbol of foot_pound_force and foot_pound_force_per_second
    • fix: quantity modulo arithmetics fixed
    • (!) build: Conan testing version is now hosted on Artifactory
    • (!) build: Linear Algebra is now hosted on its Artifactory
    • (!) build: BUILD_DOCS CMake option renamed to UNITS_BUILD_DOCS
    • build: doxygen updated to 1.8.20
    • build: catch2 updated to 2.13.4
    • build: fmt updated to 7.1.3
    • build: ms-gsl replaced with gsl-lite/0.38.0
    • build: Conan generator switched to cmake_find_package_multi
    • build: Conan CMakeToolchain support added
    • build: CMake scripts cleanup
    • build: ccache support added
    • ci: CI switched from Travis CI to GitHub Actions
    Source code(tar.gz)
    Source code(zip)
  • v0.6.0(Sep 13, 2020)

    • feat: quantity_point support added (thanks @johelegp)
    • feat: Added angle as SI base dimension (thanks @kwikius)
    • feat: si::angular_velocity support added (thanks @mikeford3)
    • feat: FPS system added (thanks @mikeford3)
    • feat: Added support for mathematical function exp(quantity)
    • feat: Localization support for text output added (thanks @rbrugo)
    • feat: Added STL random number distribution wrappers (thanks @yasamoka)
    • (!) refactor: Refactored and cleaned up the library file tree
    • (!) refactor: q_* UDL renamed to _q_*
    • (!) refactor: UDLs with "per" in name renamed from *p* to *_per_*
    • (!) refactor: ratio changed to the NTTP kind
    • (!) refactor: exp and Exp renamed to exponent and Exponent
    • (!) refactor: Scalar concept renamed to ScalableNumber
    • (!) refactor: Dimensionless quantities redesigned to be of a quantity type
    • refactor: math.h function signatures refactored to use a Quantity concept (thanks @kwikius)
    • refactor: [[nodiscard]] added to many functions
    • fix: si::day unit symbol fixed to d (thanks @komputerwiz)
    • fix: si::mole unit symbol fixed to mol (thanks @mikeford3)
    • (!) build: gcc-9 is no longer supported (at least gcc-10 is required)
    • build: Visual Studio 16.7 support added
    • build: linear_algebra updated to 0.7.0/stable
    • build: fmt updated to 7.0.3
    • build: range-v3 updated to 0.11.0
    • build: catch2 updated to 2.13.0
    • build: doxygen updated to 1.8.18
    • build: ms-gsl 3.1.0 dependency added
    • build: Removed the dependency on a git submodule with common CMake scripts
    Source code(tar.gz)
    Source code(zip)
  • v0.5.0(May 17, 2020)

    • Major refactoring and rewrite of the library
    • Units are now independent from dimensions
    • Dimensions now depend on units (base or coherent units are provided in a class template)
    • Quantity gets a Dimension template parameter again (as unit does not provide information about its dimension anymore)
    • Spaceship operator support added
    • Added official CGS system support
    • Added official data information system support
    • Repository file tree cleanup
    • ratio refactored to contain Exp template parameter (thanks a lot @oschonrock!)
    • SI fundamental constants added
    • q_ prefix applied to all the UDLs (thanks @kwikius)
    • unknown_unit renamed to unknown_coherent_unit
    • Project documentation greatly extended and switched to Sphinx
    • A few more usage examples added
    • ASCII-only output support added (thanks @yasamoka)
    • Representation values formatting extended (thanks @rbrugo)
    • Output streams formatting support added
    • Linear algebra from std::experimental::math support added
    • Named SI units and their dimensions added (thanks @rbrugo
    • libfmt updated to 6.2.0
    • Added absolute functions and epsilon to math.h (thanks @mikeford3)
    • Added a lot of prefixes to named units and introduced alias_unit (thanks @yasamoka)
    • Linking with Conan targets only when they exists (#98)
    • All physical dimensions and units put into physical namespace
    • CMake improvements
    • Velocity renamed to speed

    Many thanks to GitHub users @oschonrock, @kwikius, and @i-ky for their support in drafting a new library design.

    Source code(tar.gz)
    Source code(zip)
  • v0.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
    Source code(tar.gz)
    Source code(zip)
  • v0.3.1(Sep 18, 2019)

  • v0.3.0(Sep 17, 2019)

    • 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
    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Sep 17, 2019)

    • 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)
    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Sep 17, 2019)

Owner
Mateusz Pusz
Software architect, chief engineer, security champion, and C++ trainer with more than 14 years of experience in designing, writing and maintaining C++ code.
Mateusz Pusz
Windows user-land hooks manipulation tool.

MineSweeper Windows user-land hooks manipulation tool. Highlights Supports any x64/x86 Windows DLL (actually, any x64/x86 Windows PE for that matter)

Arsenii Pustovit 130 Dec 9, 2022
cavi is an open-source library that aims to provide performant utilities for closed hierarchies (i.e. all class types of the hierarchy are known at compile time).

cavi cavi is an open-source library that aims to provide performant utilities for closed hierarchies (i.e. all class types of the hierarchy are known

Baber Nawaz 5 Mar 9, 2022
A header only C++ library that provides type safety and user defined literals for physical units

SI - Type safety for physical units A header only c++ library that provides type safety and user defined literals for handling pyhsical values defined

Dominik Berner 399 Dec 25, 2022
Compile and execute C "scripts" in one go!

c "There isn't much that's special about C. That's one of the reasons why it's fast." I love C for its raw speed (although it does have its drawbacks)

Ryan Jacobs 2k Dec 26, 2022
LibOS is a modern C++17 library that makes OS-specific features cross-platform.

LibOS is a modern C++17 library that makes OS-specific features cross-platform. Ever tried to get Windows version after Windows 8? Or to send ke

Gavrilikhin Daniil 27 Sep 13, 2022
The lightweight and modern Map SDK for Android and iOS

Open Mobile Maps The lightweight and modern Map SDK for Android (6.0+) and iOS (10+) openmobilemaps.io Getting started Readme Android Readme iOS Featu

Open Mobile Maps 95 Dec 23, 2022
An attempt to restore and adapt to modern Win10 version the Rootkit Arsenal original code samples

rootkit-arsenal-guacamole An attempt to restore and adapt to modern Win10 version the Rootkit Arsenal original code samples All projects have been por

Matteo Malvica 51 Nov 6, 2022
The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.

Microsoft 7.2k Jan 2, 2023
The most powerful and customizable binary pattern scanner written on modern C++

Sig The most powerful and customizable binary pattern scanner written on modern C++ ✔ Capabilities: Support for all common pattern formats: Pattern +

Александр 153 Dec 21, 2022
A Template Engine for Modern C++

Inja is a template engine for modern C++, loosely inspired by jinja for python. It has an easy and yet powerful template syntax with all variables, lo

pantor 1.2k Jan 8, 2023
Mustache text templates for modern C++

About Mustache implementation for modern C++ (requires C++11) Header only Zero dependencies Templated string type for compatibility with any STL-like

Kevin Wojniak 307 Dec 11, 2022
Pretty Printer for Modern C++

Highlights Single header file Requires C++17 MIT License Quick Start Simply include pprint.hpp and you're good to go. #include <pprint.hpp> To start p

Pranav 879 Dec 22, 2022
The libxo library allows an application to generate text, XML, JSON, and HTML output using a common set of function calls. The application decides at run time which output style should be produced.

libxo libxo - A Library for Generating Text, XML, JSON, and HTML Output The libxo library allows an application to generate text, XML, JSON, and HTML

Juniper Networks 253 Dec 10, 2022
This library support run-time type casting faster than dynamic_cast ( similar to unreal engine's CastTo )

Fast Runtime Type Casting This library give you C++ Fast Runtime Type Casting faster than dynamic_cast ( similar to Unreal Engine's CastTo, IsChildOf

SungJinKang 7 Jun 11, 2022
Sqrt OS is a simulation of an OS scheduler and memory manager using different scheduling algorithms including Highest Priority First (non-preemptive), Shortest Remaining Time Next, and Round Robin.

A CPU scheduler determines an order for the execution of its scheduled processes; it decides which process will run according to a certain data structure that keeps track of the processes in the system and their status. A process, upon creation, has one of the three states: Running, Ready, Blocked (doing I/O, using other resources than CPU or waiting on unavailable resource).

Abdallah Hemdan 18 Apr 15, 2022
Advanced, modular, coupled geomorpohology simulator for real-time procedural terrain generation.

SoilMachine Advanced, modular, coupled geomorpohology simulator for real-time procedural terrain generation in C++. Visualization with TinyEngine. Art

Nick McDonald 149 Dec 28, 2022
provide SFML Time utilities in pure C++20, no dependencies

SFML-Time-utilities-without-SFML provide SFML Time utilities in pure C++20, no dependencies Example int main() { Clock clock; Sleep(1000);

null 1 Apr 28, 2022
DateTime Class to Express Time

Time is an eternal topic. How to express time is very important. The C + + class represents the date and time, which is very easy to use.

null 1 Dec 7, 2021