Skip to content

Commit

Permalink
Merge pull request #10 from bernedom/refactoring/cleaning-up-unifying…
Browse files Browse the repository at this point in the history
…-code-style

Refactoring/cleaning up unifying code style
  • Loading branch information
bernedom authored Aug 3, 2019
2 parents 34e049e + 3ac5664 commit 14aa0c6
Show file tree
Hide file tree
Showing 10 changed files with 90 additions and 47 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 1.1.1

* Unified usage of template arugments in unit_t

## 1.1.0

* Implicit / automatic conversions between units of different ratio can be disabled with the preprocessor flag `DISABLE_IMPLICIT_RATIO_CONVERSION`
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.12)
project(
"SI"
VERSION
1.0.1
1.1.1
DESCRIPTION
"A header only c++ library that provides type safety and user defined literals for handling pyhsical values defined in the International System of Units."
HOMEPAGE_URL
Expand Down
72 changes: 33 additions & 39 deletions include/SI/detail/unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ constexpr auto unit_cast(const _rhs_T &rhs);
template <typename _unit_lhs, typename _unit_rhs> struct unit_with_common_ratio;

/// @todo add assignement operator, copy ctor, move ctor
/// @todo add division by primitive type

/**
* @brief base template class for holding values of type _Type to be multiplied
Expand Down Expand Up @@ -60,14 +59,13 @@ struct unit_t {
constexpr unit_t(_Type v) : value_{v} {}

/// returns the stored value as raw type
constexpr internal_type raw_value() const { return value_; }
constexpr _Type raw_value() const { return value_; }

/// Comparison operator takes considers different ratios, i.e. 1000
/// micros === 1 milli
template <typename _rhs_ratio = std::ratio<1>>
constexpr bool
operator==(const unit_t<symbol::value, exponent::value, internal_type,
_rhs_ratio> &rhs) const {
operator==(const unit_t<_Symbol, _Exponent, _Type, _rhs_ratio> &rhs) const {

static_assert(
_SI_ENABLE_IMPLICIT_RATIO_CONVERSION ||
Expand All @@ -76,14 +74,14 @@ struct unit_t {

static_assert(detail::is_ratio<_rhs_ratio>::value,
"_rhs_ratio is a std::ratio");
static_assert(std::is_integral<internal_type>::value ||
std::is_floating_point<internal_type>::value,
static_assert(std::is_integral<_Type>::value ||
std::is_floating_point<_Type>::value,
"Is integral or floating point");
using gcd_unit = typename unit_with_common_ratio<
typename std::remove_reference<decltype(rhs)>::type,
typename std::remove_reference<decltype(*this)>::type>::type;

if constexpr (std::is_integral<internal_type>::value) {
if constexpr (std::is_integral<_Type>::value) {

return unit_cast<gcd_unit>(rhs).raw_value() ==
unit_cast<gcd_unit>(*this).raw_value();
Expand All @@ -96,16 +94,15 @@ struct unit_t {
/// compares two values, considers different ratios.
template <typename _rhs_ratio = std::ratio<1>>
constexpr bool
operator!=(const unit_t<symbol::value, exponent::value, internal_type,
_rhs_ratio> &rhs) const {
operator!=(const unit_t<_Symbol, _Exponent, _Type, _rhs_ratio> &rhs) const {
static_assert(detail::is_ratio<_rhs_ratio>::value,
"_rhs_ratio is a std::ratio");
return !(*this == rhs);
}

template <typename _rhs_ratio>
constexpr bool operator<(const unit_t<symbol::value, exponent::value,
internal_type, _rhs_ratio> &rhs) const {
constexpr bool
operator<(const unit_t<_Symbol, _Exponent, _Type, _rhs_ratio> &rhs) const {
static_assert(detail::is_ratio<_rhs_ratio>::value,
"_rhs_ratio is a std::ratio");
static_assert(
Expand All @@ -121,8 +118,8 @@ struct unit_t {
}

template <typename _rhs_ratio>
constexpr bool operator>(const unit_t<symbol::value, exponent::value,
internal_type, _rhs_ratio> &rhs) const {
constexpr bool
operator>(const unit_t<_Symbol, _Exponent, _Type, _rhs_ratio> &rhs) const {
static_assert(detail::is_ratio<_rhs_ratio>::value,
"_rhs_ratio is a std::ratio");
static_assert(
Expand All @@ -143,21 +140,21 @@ struct unit_t {

/// multiply with an unit of the same ratio
template <char _rhs_Exponent>
constexpr auto operator*(const unit_t<symbol::value, _rhs_Exponent,
internal_type, _Ratio> &rhs) const {
constexpr auto
operator*(const unit_t<_Symbol, _rhs_Exponent, _Type, _Ratio> &rhs) const {

return unit_t<symbol::value, _rhs_Exponent + exponent::value, internal_type,
std::ratio_multiply<ratio, ratio>>{raw_value() *
rhs.raw_value()};
return unit_t<_Symbol, _rhs_Exponent + _Exponent, _Type,
std::ratio_multiply<ratio, _Ratio>>{raw_value() *
rhs.raw_value()};
}

/// multiplication multiply with a same unit, with different exponent
/// and different ratio
/// the exponents this and rhs are added, the resulting ratio the ratio
/// multiplied.
template <char _rhs_exponent, typename _rhs_ratio>
constexpr auto operator*(const unit_t<symbol::value, _rhs_exponent,
internal_type, _rhs_ratio> &rhs) const {
constexpr auto operator*(
const unit_t<_Symbol, _rhs_exponent, _Type, _rhs_ratio> &rhs) const {

static_assert(detail::is_ratio<_rhs_ratio>::value,
"_rhs_ratio is a std::ratio");
Expand All @@ -167,7 +164,7 @@ struct unit_t {
std::ratio_equal<ratio, _rhs_ratio>::value,
"Implicit ratio conversion disabled, convert before comparing");

return unit_t<symbol::value, exponent::value + _rhs_exponent, internal_type,
return unit_t<_Symbol, _Exponent + _rhs_exponent, _Type,
std::ratio_multiply<ratio, _rhs_ratio>>{value_ *
rhs.raw_value()};
}
Expand All @@ -177,25 +174,24 @@ struct unit_t {

/// divide with same unit with same ratio but not the same exponent
/// @returns unit with exponents subtracted from each others
template <char _rhs_exponent,
typename std::enable_if<_rhs_exponent != exponent::value>::type * =
nullptr>
template <
char _rhs_exponent,
typename std::enable_if<_rhs_exponent != _Exponent>::type * = nullptr>
constexpr auto
operator/(const unit_t<_Symbol, _rhs_exponent, _Type, _Ratio> &rhs) const {
static_assert(_rhs_exponent > 0, "_rhs_Exponent is positive");
using rhs_t = typename std::remove_reference<decltype(rhs)>::type;

return unit_t<symbol::value, exponent::value - rhs_t::exponent::value,
internal_type, std::ratio_divide<ratio, ratio>>{
value_ / rhs.raw_value()};
return unit_t<_Symbol, _Exponent - rhs_t::exponent::value, _Type,
std::ratio_divide<ratio, _Ratio>>{value_ / rhs.raw_value()};
}

/// divide with a same unit but different ratios
/// the ratio of the result is the gcd of the two ratios and the exponents are
/// subtracted
template <char _rhs_exponent, typename _rhs_ratio,
typename std::enable_if<_rhs_exponent != exponent::value>::type * =
nullptr>
template <
char _rhs_exponent, typename _rhs_ratio,
typename std::enable_if<_rhs_exponent != _Exponent>::type * = nullptr>
constexpr auto operator/(
const unit_t<_Symbol, _rhs_exponent, _Type, _rhs_ratio> &rhs) const {
static_assert(detail::is_ratio<_rhs_ratio>::value,
Expand All @@ -206,7 +202,7 @@ struct unit_t {
std::ratio_equal<ratio, _rhs_ratio>::value,
"Implicit ratio conversion disabled, convert before dividing");

return unit_t<_Symbol, exponent::value - _rhs_exponent, _Type,
return unit_t<_Symbol, _Exponent - _rhs_exponent, _Type,
std::ratio_divide<ratio, _rhs_ratio>>{value_ /
rhs.raw_value()};
}
Expand All @@ -220,9 +216,9 @@ struct unit_t {

/// if the same units of the same exponent but different ratio are divided
/// then the result is a scalar
template <char _rhs_exponent, typename _rhs_ratio,
typename std::enable_if<_rhs_exponent == exponent::value>::type * =
nullptr>
template <
char _rhs_exponent, typename _rhs_ratio,
typename std::enable_if<_rhs_exponent == _Exponent>::type * = nullptr>
constexpr _Type operator/(
const unit_t<_Symbol, _rhs_exponent, _Type, _rhs_ratio> &rhs) const {
static_assert(_SI_ENABLE_IMPLICIT_RATIO_CONVERSION ||
Expand All @@ -244,8 +240,7 @@ struct unit_t {
/// adds two values, returning type is type of lhs
template <typename _rhs_ratio>
constexpr unit_t
operator+(const unit_t<symbol::value, exponent::value, internal_type,
_rhs_ratio> &rhs) const {
operator+(const unit_t<_Symbol, _Exponent, _Type, _rhs_ratio> &rhs) const {

static_assert(detail::is_ratio<_rhs_ratio>::value,
"_rhs_ratio is a std::ratio");
Expand All @@ -261,8 +256,7 @@ struct unit_t {
/// subtracts two values, returning type is type of lhs
template <typename _rhs_ratio>
constexpr unit_t
operator-(const unit_t<symbol::value, exponent::value, internal_type,
_rhs_ratio> &rhs) const {
operator-(const unit_t<_Symbol, _Exponent, _Type, _rhs_ratio> &rhs) const {

static_assert(detail::is_ratio<_rhs_ratio>::value,
"_rhs_ratio is a std::ratio");
Expand All @@ -280,7 +274,7 @@ struct unit_t {
constexpr unit_t operator-() { return {-value_}; }

private:
internal_type value_;
_Type value_;
}; // namespace SI

/// operator to divide primitive type by unit encapsulating the same type
Expand Down
2 changes: 0 additions & 2 deletions include/SI/length.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

namespace SI {
/// @todo add astronomic units
/// @todo add angle/radiant (l/l)
/// @todo add solid-angle/sterradiant (l^2/L^2)
template <typename _Type, typename _Ratio>
using length_t = detail::unit_t<'L', 1, _Type, _Ratio>;

Expand Down
1 change: 0 additions & 1 deletion include/SI/luminous_flux.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

namespace SI {

/// @todo add building from candela / sterradiant
template <typename _Type, class _Ratio = std::ratio<1>>
using luminous_flux_t = detail::unit_t<'m', 1, _Type, _Ratio>;

Expand Down
2 changes: 0 additions & 2 deletions include/SI/solid_angle.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
#include "detail/number_parser.h"
#include "detail/unit.h"

/// todo add rad and sr as literal operators

namespace SI {

template <typename _Type, typename _Ratio>
Expand Down
14 changes: 13 additions & 1 deletion test/compilation-tests.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#!/bin/bash
# file: test/compilation-tests.sh

# TODO add test for overflow checks
# TODO add tests for generated operators

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
Expand Down Expand Up @@ -192,5 +191,18 @@ testOperatorDivideFromIntegralFailsWhenImplicitConversionDisabled()
buildSingleTarget ${TARGET} FAIL
}

testCompilationFailsWhenNumberparserOverflows()
{
TARGET=CMakeFiles/SI-Compilation-Tests.dir/parsing_overflow_test.cc.o
buildSingleTarget ${TARGET} FAIL
}

testCompilationSucceedsWhenNumberparserDoesNotOverflow()
{
TARGET=CMakeFiles/SI-Compilation-Tests.dir/parsing_overflow_test_pass_compilation.cc.o
buildSingleTarget ${TARGET} PASS
}


# Load shUnit2.
. shunit2
4 changes: 3 additions & 1 deletion test/src/compilation_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ target_sources(${PROJECT_NAME}
operator_add_test.cc
operator_subtract_test.cc
operator_divide_from_integral_test.cc
operator_divide_from_floating_point_test.cc)
operator_divide_from_floating_point_test.cc
parsing_overflow_test.cc
parsing_overflow_test_pass_compilation.cc)
18 changes: 18 additions & 0 deletions test/src/compilation_tests/parsing_overflow_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <SI/detail/number_parser.h>

/// helper literal

namespace {
template <char... _Digits> constexpr int64_t operator""_literal_op() {
return SI::detail::parsing::Number<_Digits...>::value;
}

int overflow_test() {
constexpr auto v = 0xFFFFFFFFFFFFFFFFF_literal_op;
/// needed to avoid unused variable warning
if (v > 0) {
return 1;
}
return 0;
}
} // namespace
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <SI/detail/number_parser.h>

/// helper literal

namespace {
template <char... _Digits> constexpr int64_t operator""_literal_op() {
return SI::detail::parsing::Number<_Digits...>::value;
}

int overflow_test_pass() {
constexpr auto v = 0xFFFFFFFFFFFFFFF_literal_op;
/// needed to avoid unused variable warning
if (v > 0) {
return 1;
}
return 0;
}
} // namespace

0 comments on commit 14aa0c6

Please sign in to comment.