diff options
Diffstat (limited to 'src/lib/netlist/plib/ptime.h')
-rw-r--r-- | src/lib/netlist/plib/ptime.h | 186 |
1 files changed, 139 insertions, 47 deletions
diff --git a/src/lib/netlist/plib/ptime.h b/src/lib/netlist/plib/ptime.h index 9668e0cf428..0881f337371 100644 --- a/src/lib/netlist/plib/ptime.h +++ b/src/lib/netlist/plib/ptime.h @@ -1,18 +1,19 @@ -// license:GPL-2.0+ +// license:BSD-3-Clause // copyright-holders:Couriersud -/* - * ptime.h - */ #ifndef PTIME_H_ #define PTIME_H_ +/// +/// \file ptime.h +/// + +#include <type_traits> + #include "pconfig.h" +#include "pmath.h" // std::floor #include "ptypes.h" -#include <cmath> // std::floor -//#include <cstdint> - // ---------------------------------------------------------------------------------------- // netlist_time // ---------------------------------------------------------------------------------------- @@ -20,6 +21,12 @@ namespace plib { + template <typename T, typename U> + struct ptime_le + { + const static bool value = sizeof(T) <= sizeof(U); + }; + template <typename TYPE, TYPE RES> struct ptime final { @@ -28,6 +35,9 @@ namespace plib using internal_type = TYPE; using mult_type = TYPE; + template <typename altTYPE, altTYPE altRES> + friend struct ptime; + constexpr ptime() noexcept : m_time(0) {} ~ptime() noexcept = default; @@ -36,102 +46,184 @@ namespace plib constexpr ptime(ptime &&rhs) noexcept = default; constexpr explicit ptime(const internal_type &time) noexcept : m_time(time) {} constexpr explicit ptime(internal_type &&time) noexcept : m_time(time) {} - C14CONSTEXPR ptime &operator=(const ptime &rhs) noexcept = default; - C14CONSTEXPR ptime &operator=(ptime &&rhs) noexcept = default; + constexpr ptime &operator=(const ptime &rhs) noexcept = default; + constexpr ptime &operator=(ptime &&rhs) noexcept = default; constexpr explicit ptime(const double t) = delete; - //: m_time((internal_type) ( t * (double) resolution)) { } constexpr explicit ptime(const internal_type nom, const internal_type den) noexcept : m_time(nom * (RES / den)) { } - C14CONSTEXPR ptime &operator+=(const ptime rhs) noexcept { m_time += rhs.m_time; return *this; } - C14CONSTEXPR ptime &operator-=(const ptime rhs) noexcept { m_time -= rhs.m_time; return *this; } - C14CONSTEXPR ptime &operator*=(const mult_type factor) noexcept { m_time *= static_cast<internal_type>(factor); return *this; } + template <typename O, typename = std::enable_if_t<ptime_le<ptime<O, RES>, ptime>::value>> + constexpr ptime(const ptime<O, RES> &rhs) noexcept + : m_time(static_cast<TYPE>(rhs.m_time)) + { + } + + template <typename O, typename T = std::enable_if_t<!ptime_le<ptime<O, RES>, ptime>::value, int>> + constexpr explicit ptime(const ptime<O, RES> &rhs, [[maybe_unused]] T dummy = 0) noexcept + : m_time(static_cast<TYPE>(rhs.m_time)) + { + } - friend constexpr const ptime operator-(ptime lhs, const ptime rhs) noexcept + template <typename O> + constexpr ptime &operator+=(const ptime<O, RES> &rhs) noexcept + { + static_assert(ptime_le<ptime<O, RES>, ptime>::value, "Invalid ptime type"); + m_time += rhs.m_time; + return *this; + } + template <typename O> + constexpr ptime &operator-=(const ptime<O, RES> &rhs) noexcept { - return ptime(lhs.m_time - rhs.m_time); + static_assert(ptime_le<ptime<O, RES>, ptime>::value, "Invalid ptime type"); + m_time -= rhs.m_time; + return *this; } - friend constexpr const ptime operator+(ptime lhs, const ptime rhs) noexcept + template <typename M> + constexpr ptime &operator*=(const M &factor) noexcept { - return ptime(lhs.m_time + rhs.m_time); + static_assert(plib::is_integral<M>::value, "Factor must be an integral type"); + m_time *= factor; + return *this; } - friend constexpr const ptime operator*(ptime lhs, const mult_type &factor) noexcept + template <typename O> + constexpr ptime operator-(const ptime<O, RES> &rhs) const noexcept { - return ptime(lhs.m_time * factor); + static_assert(ptime_le<ptime<O, RES>, ptime>::value, "Invalid ptime type"); + return ptime(m_time - rhs.m_time); } - friend constexpr mult_type operator/(const ptime lhs, const ptime rhs) noexcept + template <typename O> + constexpr ptime operator+(ptime<O, RES> rhs) const noexcept { - return static_cast<mult_type>(lhs.m_time / rhs.m_time); + static_assert(ptime_le<ptime<O, RES>, ptime>::value, "Invalid ptime type"); + return ptime(m_time + rhs.m_time); } - friend constexpr bool operator<(const ptime lhs, const ptime rhs) noexcept + template <typename M> + constexpr ptime operator*(const M &factor) const noexcept { - return (lhs.m_time < rhs.m_time); + static_assert(plib::is_integral<M>::value, "Factor must be an integral type"); + return ptime(m_time * static_cast<mult_type>(factor)); } - friend constexpr bool operator>(const ptime lhs, const ptime rhs) noexcept + template <typename O> + constexpr mult_type operator/(const ptime<O, RES> &rhs) const noexcept { - return (rhs < lhs); + static_assert(ptime_le<ptime<O, RES>, ptime>::value, "Invalid ptime type"); + return static_cast<mult_type>(m_time / rhs.m_time); } - friend constexpr bool operator<=(const ptime lhs, const ptime rhs) noexcept + template <typename T> + constexpr std::enable_if_t<std::is_integral<T>::value, ptime> + operator/(const T &rhs) const noexcept + { + return ptime(m_time / rhs); + } + + template <typename O> + friend constexpr bool operator<(const ptime &lhs, const ptime<O, RES> &rhs) noexcept + { + static_assert(ptime_le<ptime<O, RES>, ptime>::value, "Invalid ptime type"); + return (lhs.m_time < rhs.as_raw()); + //return (lhs.m_time < rhs.m_time); + } + + template <typename O> + friend constexpr bool operator>(const ptime &lhs, const ptime<O, RES> &rhs) noexcept + { + static_assert(ptime_le<ptime<O, RES>, ptime>::value, "Invalid ptime type"); + return (lhs.m_time > rhs.as_raw()); + } + + template <typename O> + friend constexpr bool operator<=(const ptime &lhs, const ptime<O, RES> &rhs) noexcept { return !(lhs > rhs); } - friend constexpr bool operator>=(const ptime lhs, const ptime rhs) noexcept + template <typename O> + friend constexpr bool operator>=(const ptime &lhs, const ptime<O, RES> &rhs) noexcept { return !(lhs < rhs); } - friend constexpr bool operator==(const ptime lhs, const ptime rhs) noexcept + template <typename O> + friend constexpr bool operator==(const ptime &lhs, const ptime<O, RES> &rhs) noexcept { - return lhs.m_time == rhs.m_time; + return lhs.m_time == rhs.as_raw(); } - friend constexpr bool operator!=(const ptime lhs, const ptime rhs) noexcept + template <typename O> + friend constexpr bool operator!=(const ptime &lhs, const ptime<O, RES> &rhs) noexcept { return !(lhs == rhs); } constexpr internal_type as_raw() const noexcept { return m_time; } - constexpr double as_double() const noexcept + + template <typename FT, typename = std::enable_if<plib::is_floating_point<FT>::value, FT>> + constexpr FT + as_fp() const noexcept { - return static_cast<double>(m_time) * inv_res; + return static_cast<FT>(m_time) * inv_res<FT>(); } + constexpr double as_double() const noexcept { return as_fp<double>(); } + constexpr float as_float() const noexcept { return as_fp<float>(); } + constexpr long double as_long_double() const noexcept { return as_fp<long double>(); } + + + constexpr ptime shl(unsigned shift) const noexcept { return ptime(m_time << shift); } + constexpr ptime shr(unsigned shift) const noexcept { return ptime(m_time >> shift); } + // for save states .... - C14CONSTEXPR internal_type *get_internaltype_ptr() noexcept { return &m_time; } - static constexpr ptime from_nsec(const internal_type ns) noexcept { return ptime(ns, UINT64_C(1000000000)); } - static constexpr ptime from_usec(const internal_type us) noexcept { return ptime(us, UINT64_C( 1000000)); } - static constexpr ptime from_msec(const internal_type ms) noexcept { return ptime(ms, UINT64_C( 1000)); } - static constexpr ptime from_sec(const internal_type s) noexcept { return ptime(s, UINT64_C( 1)); } - static constexpr ptime from_hz(const internal_type hz) noexcept { return ptime(1 , hz); } - static constexpr ptime from_raw(const internal_type raw) noexcept { return ptime(raw); } - static constexpr ptime from_double(const double t) noexcept { return ptime(static_cast<internal_type>(std::floor(t * static_cast<double>(RES) + 0.5)), RES); } + template <typename ST> + void save_state(ST &&st) + { + st.save_item(m_time, "m_time"); + } + + static constexpr ptime from_nsec(internal_type ns) noexcept { return ptime(ns, UINT64_C(1000000000)); } + static constexpr ptime from_usec(internal_type us) noexcept { return ptime(us, UINT64_C( 1000000)); } + static constexpr ptime from_msec(internal_type ms) noexcept { return ptime(ms, UINT64_C( 1000)); } + static constexpr ptime from_sec(internal_type s) noexcept { return ptime(s, UINT64_C( 1)); } + static constexpr ptime from_hz(internal_type hz) noexcept { return ptime(1 , hz); } + static constexpr ptime from_raw(internal_type raw) noexcept { return ptime(raw); } + + template <typename FT> + static constexpr std::enable_if_t<plib::is_floating_point<FT>::value, ptime> + from_fp(FT t) noexcept { return ptime(static_cast<internal_type>(plib::floor(t * static_cast<FT>(RES) + static_cast<FT>(0.5))), RES); } + + static constexpr ptime from_double(double t) noexcept + { return from_fp<double>(t); } + + static constexpr ptime from_float(float t) noexcept + { return from_fp<float>(t); } + + static constexpr ptime from_long_double(long double t) noexcept + { return from_fp<long double>(t); } static constexpr ptime zero() noexcept { return ptime(0, RES); } static constexpr ptime quantum() noexcept { return ptime(1, RES); } static constexpr ptime never() noexcept { return ptime(plib::numeric_limits<internal_type>::max(), RES); } static constexpr internal_type resolution() noexcept { return RES; } - constexpr internal_type in_nsec() const noexcept { return m_time / (RES / UINT64_C(1000000000)); } - constexpr internal_type in_usec() const noexcept { return m_time / (RES / UINT64_C( 1000000)); } - constexpr internal_type in_msec() const noexcept { return m_time / (RES / UINT64_C( 1000)); } - constexpr internal_type in_sec() const noexcept { return m_time / (RES / UINT64_C( 1)); } + constexpr internal_type in_nsec() const noexcept { return m_time / (RES / INT64_C(1000000000)); } + constexpr internal_type in_usec() const noexcept { return m_time / (RES / INT64_C( 1000000)); } + constexpr internal_type in_msec() const noexcept { return m_time / (RES / INT64_C( 1000)); } + constexpr internal_type in_sec() const noexcept { return m_time / (RES / INT64_C( 1)); } private: - static constexpr const double inv_res = 1.0 / static_cast<double>(RES); + template <typename FT> + static constexpr FT inv_res() noexcept { return static_cast<FT>(1.0) / static_cast<FT>(RES); } internal_type m_time; }; - } // namespace plib -#endif /* PTIME_H_ */ +#endif // PTIME_H_ |