-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
694 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
#ifndef ZLL_NUMERIC_RATIO_HPP | ||
#define ZLL_NUMERIC_RATIO_HPP | ||
|
||
#include "zll/numeric/ratio/ratio_type.hpp" | ||
#include "zll/numeric/ratio/arithmetic.hpp" | ||
#include "zll/numeric/ratio/comparsion.hpp" | ||
|
||
|
||
namespace zll { | ||
|
||
// clang-format off | ||
typedef ratio<1L, 1000000000000000000L> atto; | ||
typedef ratio<1L, 1000000000000000L> femto; | ||
typedef ratio<1L, 1000000000000L> pico; | ||
typedef ratio<1L, 1000000000L> nano; | ||
typedef ratio<1L, 1000000L> micro; | ||
typedef ratio<1L, 1000L> milli; | ||
typedef ratio<1L, 100L> centi; | ||
typedef ratio<1L, 10L> deci; | ||
typedef ratio< 10L, 1L> deca; | ||
typedef ratio< 100L, 1L> hecto; | ||
typedef ratio< 1000L, 1L> kilo; | ||
typedef ratio< 1000000L, 1L> mega; | ||
typedef ratio< 1000000000L, 1L> giga; | ||
typedef ratio< 1000000000000L, 1L> tera; | ||
typedef ratio< 1000000000000000L, 1L> peta; | ||
typedef ratio<1000000000000000000L, 1L> exa; | ||
// clang-format on | ||
|
||
} // namespace zll | ||
|
||
#endif // ZLL_NUMERIC_RATIO_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
#ifndef ZLL_NUMERIC_RATIO_ARITHMETIC_HPP | ||
#define ZLL_NUMERIC_RATIO_ARITHMETIC_HPP | ||
|
||
#include "zll/numeric/ratio/ratio_type.hpp" | ||
#include "zll/numeric/ratio/helper.hpp" | ||
#include "zll/numeric/ratio/overflow_helper.hpp" | ||
|
||
#include "zll/meta/enable_if.hpp" | ||
#include "zll/meta/integral_constant.hpp" | ||
|
||
#include "zll/cstdint.hpp" | ||
|
||
namespace zll { | ||
namespace detail { | ||
template <typename LHS_T, typename RHS_T> | ||
struct ratio_add_helper { | ||
static const zll::intmax_t gcd = ratio_gcd_helper<LHS_T::den, RHS_T::den>::value; | ||
|
||
static const zll::intmax_t num = safe_addition<safe_multiply<LHS_T::num, (RHS_T::den / gcd)>::value, | ||
safe_multiply<RHS_T::num, (LHS_T::den / gcd)>::value>::value; | ||
static const zll::intmax_t den = safe_multiply<LHS_T::den, (RHS_T::den / gcd)>::value; | ||
|
||
typedef ratio<num, den> ratio_type; | ||
typedef typename ratio_type::type type; | ||
}; | ||
|
||
} // namespace detail | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T, | ||
typename meta::enable_if<is_ratio<LHS_T>::value, bool>::type = true, | ||
typename meta::enable_if<is_ratio<RHS_T>::value, bool>::type = true> | ||
struct ratio_add { | ||
typedef typename detail::ratio_add_helper<LHS_T, RHS_T>::type type; | ||
}; | ||
// clang-format on | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T, | ||
typename meta::enable_if<is_ratio<LHS_T>::value, bool>::type = true, | ||
typename meta::enable_if<is_ratio<RHS_T>::value, bool>::type = true> | ||
struct ratio_subtract { | ||
typedef typename detail::ratio_add_helper< LHS_T, ratio<-RHS_T::num, RHS_T::den> >::type type; | ||
}; | ||
// clang-format on | ||
|
||
namespace detail { | ||
|
||
template <typename LHS_T, typename RHS_T> | ||
struct ratio_multiply_helper { | ||
static const zll::intmax_t gcd_x = ratio_gcd_helper<LHS_T::num, RHS_T::den>::value; | ||
static const zll::intmax_t gcd_y = ratio_gcd_helper<RHS_T::num, LHS_T::den>::value; | ||
|
||
static const zll::intmax_t num = safe_multiply<LHS_T::num / gcd_x, RHS_T::num / gcd_y>::value; | ||
static const zll::intmax_t den = safe_multiply<LHS_T::den / gcd_y, RHS_T::den / gcd_x>::value; | ||
|
||
typedef ratio<num, den> ratio_type; | ||
typedef typename ratio_type::type type; | ||
}; | ||
|
||
} // namespace detail | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T, | ||
typename meta::enable_if<is_ratio<LHS_T>::value, bool>::type = true, | ||
typename meta::enable_if<is_ratio<RHS_T>::value, bool>::type = true> | ||
struct ratio_multiply { | ||
typedef typename detail::ratio_multiply_helper<LHS_T, RHS_T>::type type; | ||
}; | ||
// clang-format on | ||
namespace detail { | ||
|
||
template <typename LHS_T, typename RHS_T> | ||
struct ratio_divide_helper { | ||
static const zll::intmax_t gcd_num = ratio_gcd_helper<LHS_T::num, RHS_T::num>::value; | ||
static const zll::intmax_t gcd_den = ratio_gcd_helper<RHS_T::den, LHS_T::den>::value; | ||
|
||
static const zll::intmax_t num = safe_multiply<LHS_T::num / gcd_num, RHS_T::den / gcd_den>::value; | ||
static const zll::intmax_t den = safe_multiply<RHS_T::num / gcd_num, LHS_T::den / gcd_den>::value; | ||
|
||
typedef ratio<num, den> ratio_type; | ||
typedef typename ratio_type::type type; | ||
}; | ||
|
||
} // namespace detail | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T, | ||
typename meta::enable_if<is_ratio<LHS_T>::value, bool>::type = true, | ||
typename meta::enable_if<is_ratio<RHS_T>::value, bool>::type = true> | ||
struct ratio_divide { | ||
typedef typename detail::ratio_divide_helper<LHS_T, RHS_T>::type type; | ||
}; | ||
// clang-format on | ||
|
||
|
||
} // namespace zll | ||
|
||
#endif // ZLL_NUMERIC_RATIO_ARITHMETIC_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
#ifndef ZLl_NUMERIC_RATIO_COMPARSION_HPP | ||
#define ZLl_NUMERIC_RATIO_COMPARSION_HPP | ||
|
||
#include "zll/numeric/ratio/ratio_type.hpp" | ||
#include "zll/numeric/ratio/helper.hpp" | ||
#include "zll/numeric/ratio/overflow_helper.hpp" | ||
|
||
#include "zll/meta/enable_if.hpp" | ||
#include "zll/meta/integral_constant.hpp" | ||
|
||
namespace zll { | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T, | ||
typename meta::enable_if<is_ratio<LHS_T>::value, bool>::type = true, | ||
typename meta::enable_if<is_ratio<RHS_T>::value, bool>::type = true> | ||
struct ratio_equal : meta::bool_constant<((LHS_T::num == RHS_T::num) && (LHS_T::den == RHS_T::den))> {}; | ||
// clang-format on | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T, | ||
typename meta::enable_if<is_ratio<LHS_T>::value, bool>::type = true, | ||
typename meta::enable_if<is_ratio<RHS_T>::value, bool>::type = true> | ||
struct ratio_not_equal : meta::bool_constant< !(ratio_equal<LHS_T,RHS_T>::value) > {}; | ||
// clang-format on | ||
|
||
namespace detail { | ||
// clang-format off | ||
template <typename LHS_T, typename RHS_T> | ||
struct ratio_less_helper_impl { | ||
static const zll::intmax_t lhs = detail::safe_multiply<LHS_T::num, RHS_T::den>::value; | ||
static const zll::intmax_t rhs = detail::safe_multiply<RHS_T::num, LHS_T::den>::value; | ||
static const bool value = lhs < rhs; | ||
}; | ||
// clang-format on | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T, | ||
zll::intmax_t LHS_SIGN_V = ratio_sign_helper<LHS_T::num>::value, | ||
zll::intmax_t RHS_SIGN_V = ratio_sign_helper<RHS_T::num>::value> | ||
struct ratio_less_helper : meta::bool_constant<(LHS_SIGN_V < RHS_SIGN_V)> {}; | ||
// clang-format on | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T> | ||
struct ratio_less_helper<LHS_T, RHS_T, 1, 1> | ||
: meta::bool_constant<ratio_less_helper_impl<LHS_T, RHS_T>::value> {}; | ||
// clang-format on | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T> | ||
struct ratio_less_helper<LHS_T, RHS_T, -1, -1> | ||
: meta::bool_constant<ratio_less_helper_impl< ratio<-LHS_T::num, LHS_T::den>, | ||
ratio<-RHS_T::num, RHS_T::den> >::value> {}; | ||
// clang-format on | ||
} // namespace detail | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T, | ||
typename meta::enable_if<is_ratio<LHS_T>::value, bool>::type = true, | ||
typename meta::enable_if<is_ratio<RHS_T>::value, bool>::type = true> | ||
struct ratio_less : detail::ratio_less_helper<LHS_T, RHS_T> {}; | ||
// clang-format on | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T, | ||
typename meta::enable_if<is_ratio<LHS_T>::value, bool>::type = true, | ||
typename meta::enable_if<is_ratio<RHS_T>::value, bool>::type = true> | ||
struct ratio_greater : detail::ratio_less_helper<RHS_T, LHS_T> {}; | ||
// clang-format on | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T, | ||
typename meta::enable_if<is_ratio<LHS_T>::value, bool>::type = true, | ||
typename meta::enable_if<is_ratio<RHS_T>::value, bool>::type = true> | ||
struct ratio_less_equal : meta::bool_constant<!(ratio_greater<LHS_T, RHS_T>::value)> {}; | ||
// clang-format on | ||
|
||
// clang-format off | ||
template <typename LHS_T, typename RHS_T, | ||
typename meta::enable_if<is_ratio<LHS_T>::value, bool>::type = true, | ||
typename meta::enable_if<is_ratio<RHS_T>::value, bool>::type = true> | ||
struct ratio_greater_equal : meta::bool_constant<!(ratio_less<LHS_T, RHS_T>::value)> {}; | ||
// clang-format on | ||
|
||
} // namespace zll | ||
|
||
#endif // ZLl_NUMERIC_RATIO_COMPARSION_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
#ifndef ZLL_NUMERIC_RATIO_HELPER_HPP | ||
#define ZLL_NUMERIC_RATIO_HELPER_HPP | ||
|
||
#include "zll/meta/integral_constant.hpp" | ||
|
||
#include "zll/cstdint.hpp" | ||
|
||
namespace zll { | ||
namespace detail { | ||
|
||
template <zll::intmax_t LHS_V, zll::intmax_t RHS_V> | ||
struct ratio_gcd_helper_impl { | ||
static const zll::intmax_t value = ratio_gcd_helper_impl<RHS_V, LHS_V % RHS_V>::value; | ||
}; | ||
|
||
template <zll::intmax_t V> | ||
struct ratio_gcd_helper_impl<V, 0> { | ||
static const zll::intmax_t value = V; | ||
}; | ||
|
||
template <> | ||
struct ratio_gcd_helper_impl<0, 0> { | ||
static const zll::intmax_t value = 1; | ||
}; | ||
|
||
template <zll::intmax_t V> | ||
struct ratio_sign_helper_impl { | ||
static const zll::intmax_t value = (V == 0) ? 0 : ((V < 0) ? -1 : 1); | ||
}; | ||
|
||
template <zll::intmax_t LHS_V, zll::intmax_t RHS_V> | ||
struct ratio_gcd_helper : meta::integral_constant<zll::intmax_t, ratio_gcd_helper_impl<LHS_V, RHS_V>::value> {}; | ||
|
||
template <zll::intmax_t V> | ||
struct ratio_abs_helper : meta::integral_constant<zll::intmax_t, ((V < 0) ? -V : V)> {}; | ||
|
||
template <zll::intmax_t V> | ||
struct ratio_sign_helper : meta::integral_constant<zll::intmax_t, ratio_sign_helper_impl<V>::value> {}; | ||
|
||
} // namespace detail | ||
} // namespace zll | ||
|
||
#endif // ZLL_NUMERIC_RATIO_HELPER_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
#ifndef ZLL_NUMER_RATIO_OVERFLOWHELPER_HPP | ||
#define ZLL_NUMER_RATIO_OVERFLOWHELPER_HPP | ||
|
||
#include "zll/debug/static_assert.hpp" | ||
#include "zll/meta/integral_constant.hpp" | ||
#include "zll/numeric/ratio/helper.hpp" | ||
|
||
#include "zll/cstdint.hpp" | ||
|
||
namespace zll { | ||
namespace detail { | ||
|
||
template <zll::intmax_t LHS_V, zll::intmax_t RHS_V> | ||
struct safe_multiply_helper { | ||
static const zll::intmax_t lhs_abs = ratio_abs_helper<LHS_V>::value; | ||
static const zll::intmax_t rhs_abs = ratio_abs_helper<RHS_V>::value; | ||
|
||
static const bool value = lhs_abs <= (INTMAX_MAX / rhs_abs); | ||
}; | ||
|
||
template <zll::intmax_t V> | ||
struct safe_multiply_helper<V, 0> { | ||
static const bool value = true; | ||
}; | ||
|
||
// clang-format off | ||
template <zll::intmax_t LHS_V, zll::intmax_t RHS_V, | ||
bool NO_OVERFLOW_V = safe_multiply_helper<LHS_V, RHS_V>::value> | ||
struct safe_multiply : meta::integral_constant<zll::intmax_t, (LHS_V * RHS_V)> {}; | ||
// clang-format on | ||
|
||
template <zll::intmax_t LHS_V, zll::intmax_t RHS_V> | ||
struct safe_multiply<LHS_V, RHS_V, false> { | ||
static const bool no_overflow = safe_multiply_helper<LHS_V, RHS_V>::value; | ||
ZLL_STATIC_ASSERT(no_overflow); | ||
}; | ||
|
||
// clang-format off | ||
template <zll::intmax_t LHS_V, zll::intmax_t RHS_V, | ||
zll::intmax_t LHS_SIGN_V = ratio_sign_helper<LHS_V>::value, | ||
zll::intmax_t RHS_SIGN_V = ratio_sign_helper<RHS_V>::value> | ||
struct safe_addition_helper { | ||
static const bool value = true; | ||
}; | ||
// clang-format on | ||
|
||
template <zll::intmax_t LHS_V, zll::intmax_t RHS_V, zll::intmax_t SIGN_V> | ||
struct safe_addition_helper<LHS_V, RHS_V, SIGN_V, SIGN_V> { | ||
static const zll::intmax_t lhs_abs = ratio_abs_helper<LHS_V>::value; | ||
static const zll::intmax_t rhs_abs = ratio_abs_helper<RHS_V>::value; | ||
|
||
static const bool value = lhs_abs <= (INTMAX_MAX - rhs_abs); | ||
}; | ||
|
||
// clang-format off | ||
template <zll::intmax_t LHS_V, zll::intmax_t RHS_V, | ||
bool NO_OVERFLOW_V = safe_addition_helper<LHS_V, RHS_V>::value> | ||
struct safe_addition : meta::integral_constant<zll::intmax_t, (LHS_V + RHS_V)> {}; | ||
// clang-format on | ||
|
||
template <zll::intmax_t LHS_V, zll::intmax_t RHS_V> | ||
struct safe_addition<LHS_V, RHS_V, false> { | ||
static const bool no_overflow = safe_addition_helper<LHS_V, RHS_V>::value; | ||
ZLL_STATIC_ASSERT(no_overflow); | ||
}; | ||
|
||
} // namespace detail | ||
} // namespace zll | ||
|
||
#endif // ZLL_NUMER_RATIO_OVERFLOWHELPER_HPP |
Oops, something went wrong.