Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/building conductance from resistance #11

Merged
merged 3 commits into from
Aug 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## 1.1.1

* Unified usage of template arugments in unit_t
* electric conductance can be built from 1/Ohm (including all ratios)
* electric resistance can be built from 1/S (including all ratios)

## 1.1.0

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ All units that can be built from other units are also decayable to the respectiv
| Acceleration | a | m/s^2 | v / T | none | none |
| Electric charge | Q | C | I \* T | aC to EC | `*_coulomb_t` |
| Electric potential | U | V | P / I, E/Q | aV to EV | `*_volt_t` |
| Electric resistance | O* | Ohm (Ω) | U / I | aOhm to EOhm | `*_ohm_t` |
| Electric conductance | G | S | I / U | aS to ES | `*_siemens_t` |
| Electric resistance | O* | Ohm (Ω) | U / I, 1/G | aOhm to EOhm | `*_ohm_t` |
| Electric conductance | G | S | I / U, 1/R | aS to ES | `*_siemens_t` |
| Electric capacity | C | F | Q / U | aF to EF | `*_farad_t` |
| Force | F | N | M \* a | aN to EN | `*_newton_t` |
| Pressure | p | pa | F / L^2 | apa to Epa | `*_pascal_t` |
Expand Down
2 changes: 1 addition & 1 deletion include/SI/detail/unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ struct unit_with_common_ratio {

/// divide a value of a certain unit with another value of a possibly different
/// type resulting in a new type, the resulting exponent is specified by
/// resultingunit using a variadic template to simplify usage of implentation
/// resulting unit using a variadic template to simplify usage of implentation
/// the internal type of the result is the internal type of lhs
template <template <typename...> typename _resulting_unit, typename _unit_lhs,
typename _unit_rhs>
Expand Down
11 changes: 10 additions & 1 deletion include/SI/electric_conductance.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,18 @@ template <typename _Type>
using exa_siemens_t = electric_conductance_t<_Type, std::exa>;

namespace detail {
/// @todo add building from 1/Ohm

BUILD_UNIT_FROM_DIVISON(electric_conductance_t, electric_current_t,
electric_potential_t)

/// Builds conductance from 1/resistance, to avoid include cycles the base
/// unit_t is used instead of the type alias electric_resistance_t
template <typename _Type, class _Ratio = std::ratio<1>>
constexpr auto operator/(const _Type scalar,
const unit_t<'O', 1, _Type, _Ratio> &resistance) {
return electric_conductance_t<_Type, std::ratio<_Ratio::den, _Ratio::num>>{
scalar / resistance.raw_value()};
}
} // namespace detail

inline namespace literals {
Expand Down
11 changes: 11 additions & 0 deletions include/SI/electric_resistance.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "electric_potential.h"

namespace SI {

/// @todo find a way to use Ohm as dimension symbol
template <typename _Type, class _Ratio = std::ratio<1>>
using electric_resistance_t = detail::unit_t<'O', 1, _Type, _Ratio>;
Expand Down Expand Up @@ -52,6 +53,16 @@ using exa_ohm_t = electric_resistance_t<_Type, std::exa>;
namespace detail {
BUILD_UNIT_FROM_DIVISON(electric_resistance_t, electric_potential_t,
electric_current_t)

/// Builds conductance from 1/conductance, to avoid include cycles the base
/// unit_t is used instead of the type alias electric_conductance_t
template <typename _Type, class _Ratio = std::ratio<1>>
constexpr auto
operator/(const _Type scalar,
const detail::unit_t<'G', 1, _Type, _Ratio> &conductance) {
return electric_resistance_t<_Type, std::ratio<_Ratio::den, _Ratio::num>>{
scalar / conductance.raw_value()};
}
} // namespace detail

inline namespace literals {
Expand Down
2 changes: 2 additions & 0 deletions include/SI/radioactivity.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
namespace SI {

/// @todo check how to make this the same/an alias of hertz
/// @todo think of how this can be built from 1/T (probably goes along with
/// making it an alias of hertz)
template <typename _Type, class _Ratio = std::ratio<1>>
using radioactivity_t = detail::unit_t<'A', 1, _Type, _Ratio>;

Expand Down
2 changes: 0 additions & 2 deletions test/compilation-tests.sh
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#!/bin/bash
# file: test/compilation-tests.sh

# TODO add tests for generated operators

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
ROOT_DIR=$(realpath ${SCRIPT_DIR}/../)
INSTALL_PATH=$(realpath ~/SI-install)
Expand Down
45 changes: 44 additions & 1 deletion test/src/derived_unit_tests/electric_conductance_tests.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <catch.hpp>

#include <SI/electric_conductance.h>
#include <SI/electric_resistance.h>

using namespace SI::literals;
TEST_CASE("GIVEN a value WHEN constructed with literal _aS THEN result is a "
Expand Down Expand Up @@ -198,7 +199,7 @@ TEMPLATE_TEST_CASE("GIVEN a electric_conductance value WHEN multiplied by an "
TEMPLATE_TEST_CASE("GIVEN a electric_current value WHEN divided by a "
"electric_conductance value THEN "
"result is an electric_potential value",
"[electric_current][operator/]", int64_t, long double) {
"[electric_conductance][operator/]", int64_t, long double) {
constexpr SI::electric_current_t<TestType, std::ratio<1>> electric_current{1};
constexpr SI::electric_conductance_t<TestType, std::ratio<1>>
electric_conductance{1};
Expand All @@ -209,3 +210,45 @@ TEMPLATE_TEST_CASE("GIVEN a electric_current value WHEN divided by a "
std::is_same<decltype(result), const SI::electric_potential_t<
TestType, std::ratio<1>>>::value);
}

TEMPLATE_TEST_CASE("GIVEN a scalar WHEN divided by a resistance value THEN "
"result is an electric conductance value",
"[electric_conductance][operator/]", int64_t, long double) {

constexpr SI::electric_resistance_t<TestType, std::ratio<1>> resistance{5};
constexpr TestType scalar{10};

constexpr auto result = scalar / resistance;
constexpr SI::siemens_t<TestType> expected{2};
STATIC_REQUIRE(
std::is_same<decltype(result), const SI::siemens_t<TestType>>::value);
STATIC_REQUIRE(result == expected);
}

namespace {
/// helper struct to faciltate templated testcase
template <typename _ratio_lhs, typename _ratio_rhs> struct ratio_tuple {
using ratio_lhs = _ratio_lhs;
using ratio_rhs = _ratio_rhs;
};

} // namespace

TEMPLATE_TEST_CASE("GIVEN a scalar WHEN divided by a resistance value THEN "
"result is electric_conductance AND ratio is inverse",
"[electric_conductance][operator/]",
(ratio_tuple<std::milli, std::kilo>),
(ratio_tuple<std::kilo, std::milli>),
(ratio_tuple<std::ratio<1>, std::ratio<1>>)) {

constexpr auto resistance =
SI::electric_resistance_t<int64_t, typename TestType::ratio_lhs>{5};
constexpr int64_t scalar{10};

constexpr auto result = scalar / resistance;
constexpr SI::electric_conductance_t<int64_t, typename TestType::ratio_rhs>
expected{2};
STATIC_REQUIRE(std::ratio_equal<typename decltype(result)::ratio,
typename TestType::ratio_rhs>::value);
STATIC_REQUIRE(result == expected);
}
43 changes: 43 additions & 0 deletions test/src/derived_unit_tests/electric_resistance_tests.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <catch.hpp>

#include <SI/electric_conductance.h>
#include <SI/electric_resistance.h>

using namespace SI::literals;
Expand Down Expand Up @@ -217,3 +218,45 @@ TEMPLATE_TEST_CASE("GIVEN a electric_potential value WHEN divided by a "
decltype(result),
const SI::electric_current_t<TestType, std::ratio<1>>>::value);
}

TEMPLATE_TEST_CASE("GIVEN a scalar WHEN divided by a conductance value THEN "
"result is an electric resistance value",
"[electric_resistance][operator/]", int64_t, long double) {

constexpr SI::electric_conductance_t<TestType, std::ratio<1>> conductance{5};
constexpr TestType scalar{10};

constexpr auto result = scalar / conductance;
constexpr SI::ohm_t<TestType> expected{2};
STATIC_REQUIRE(
std::is_same<decltype(result), const SI::ohm_t<TestType>>::value);
STATIC_REQUIRE(result == expected);
}

namespace {
/// helper struct to faciltate templated testcase
template <typename _ratio_lhs, typename _ratio_rhs> struct ratio_tuple {
using ratio_lhs = _ratio_lhs;
using ratio_rhs = _ratio_rhs;
};

} // namespace

TEMPLATE_TEST_CASE("GIVEN a scalar WHEN divided by a conductance value THEN "
"result is electric_resistance AND ratio is inverse",
"[electric_conductance][operator/]",
(ratio_tuple<std::milli, std::kilo>),
(ratio_tuple<std::kilo, std::milli>),
(ratio_tuple<std::ratio<1>, std::ratio<1>>)) {

constexpr auto conductance =
SI::electric_conductance_t<int64_t, typename TestType::ratio_lhs>{5};
constexpr int64_t scalar{10};

constexpr auto result = scalar / conductance;
constexpr SI::electric_resistance_t<int64_t, typename TestType::ratio_rhs>
expected{2};
STATIC_REQUIRE(std::ratio_equal<typename decltype(result)::ratio,
typename TestType::ratio_rhs>::value);
STATIC_REQUIRE(result == expected);
}