Skip to content

loliGothicK/mitama-dimensional

Repository files navigation

logo

CircleCI

Build status

What is mitama-dimensional?

Header-only C++17 library provides dimensional analysis based on variadic Phantom-Type. Please refer to the document for more details.

Features

  • quantity_t, which is a dimensionful value wrapper
  • arithmetic operators for quantity
  • automated unit conversions
  • math functions for quantity
  • pre defined SI derived units
  • USER DEFINED DIMENSION
  • formatted output

Examples

#include <dimensional/quantity.hpp>
#include <dimensional/arithmetic.hpp>
#include <dimensional/systems/si/all.hpp>
#include <dimensional/systems/si/derived_units/area.hpp>

int main() {
    namespace si = mitama::systems::si;
    // width = 2 m
    mitama::quantity_t<si::meter_t, int> width = 2;
    // height = 3 m
    mitama::quantity_t<si::meter_t, int> height = 3;
    // area = 6 m^2
    mitama::quantity_t<si::area_t, int> area = width * height;
}

Here is a dimensional sanity check example:

#include <dimensional/quantity.hpp>
#include <dimensional/arithmetic.hpp>
#include <dimensional/systems/si/all.hpp>
#include <dimensional/systems/si/derived_units/area.hpp>

int main() {
    namespace si = mitama::systems::si;
    // width = 2 m
    mitama::quantity_t<si::meter_t, int> width = 2;
    // height = 3 m
    mitama::quantity_t<si::meter_t, int> height = 3;
    // ERROR!
    mitama::quantity_t<si::area_t, int> area = width + height;
    //                                               ^ oops!!
}
#include <dimensional/quantity.hpp>
#include <dimensional/arithmetic.hpp>
#include <dimensional/systems/si/all.hpp>
#include <dimensional/systems/si/derived_units/area.hpp>

int main() {
    namespace si = mitama::systems::si;
    // width = 2 m
    mitama::quantity_t width = 2 | si::meters;
    // height = 3 m
    mitama::quantity_t height = 3 | si::meters;
    // area = 6 m^2
    mitama::quantity_t<si::area_t, int> area = width * height;
}
#include <dimensional/quantity.hpp>
#include <dimensional/arithmetic.hpp>
#include <dimensional/systems/si/all.hpp>
#include <dimensional/systems/si/derived_units/area.hpp>

int main() {
    namespace si = mitama::systems::si;
    // width = 2 m
    mitama::quantity_t<si::meter_t, int> width = 2;
    // height = 3 mm
    mitama::quantity_t<si::millimeter_t, int> height = 3;
    // area = 6000 mm^2
    mitama::quantity_t area = width * height;
}
// wizarding.hpp
#include <dimensional/quantity.hpp>
#include <dimensional/io.hpp>
/*
Here's an example how to implement user extension dimensions
by taking the currency of the wizarding world of Harry Potter.
*/
namespace wizarding {
    // (1) - define base dimension type.
    struct wizarding_currency {
        // required: meta tag type `is_base_dimension`
        using is_base_dimension = void;
    };
    // (2) - define base unit type using `mitama::make_unit_t`.
    using knut_t = mitama::make_unit_t<wizarding_currency>;
    // (3) - define scaled unit aliasing using `mitama::scaled_unit_t<UnitType, Ratio>`.
    // [ - Note:
    //     In Wizarding World of Harry Potter, 1 sickle = 29 knuts and 1 galleon = 17 sickles.
    //   - end note ]
    using sickle_t = mitama::scaled_unit_t<knut_t, std::ratio<29>>;
    using galleon_t = mitama::scaled_unit_t<sickle_t, std::ratio<17>>;

    // (4) - define inline constexpr variables [optional].
    // for operator |
    // [ - Example:
    //     auto x = 42 | knuts; // x: quantity_t<knut_t, int>
    //   - end example ]
    inline constexpr knut_t knuts{};
    inline constexpr knut_t knut{};

    inline constexpr sickle_t sickles{};
    inline constexpr sickle_t sickle{};

    inline constexpr galleon_t galleons{};
    inline constexpr galleon_t galleon{};
}

namespace mitama {
    // (5) - define partial specialization class `abbreviation` for pretty printing [optional].
    template <> struct abbreviation_<wizarding::knut_t> { static constexpr char str[] = "knuts"; };
    template <> struct abbreviation_<wizarding::sickle_t> { static constexpr char str[] = "sickles"; };
    template <> struct abbreviation_<wizarding::galleon_t> { static constexpr char str[] = "galleons"; };
}
// main.cpp
#include <dimensional/quantity.hpp>
#include "wizarding_currency.hpp"
#include <iostream>

int main() {
    using mitama::quantity;
    using namespace wizarding;

    quantity<galleon_t> g = 1;
    quantity<sickle_t> s = 1|galleon;
    quantity<knut_t> k = 1|sickle;

    std::cout << g << std::endl; // 1 [galleons]
    std::cout << s << std::endl; // 17 [sickles]
    std::cout << k << std::endl; // 29 [knuts]
}

Integration

You should add include directory include/.

Compiler compatibility

  • Clang/LLVM >= 6.0
  • GCC >= 8
  • Visual C++ >= 16.0.0 / Visual Studio >= 2019

Licensed under the MIT License