// license:BSD-3-Clause // copyright-holders:Couriersud #ifndef PTIME_H_ #define PTIME_H_ /// /// \file ptime.h /// #include #include "pconfig.h" #include "pmath.h" // std::floor #include "ptypes.h" // ---------------------------------------------------------------------------------------- // netlist_time // ---------------------------------------------------------------------------------------- namespace plib { template struct ptime_le { const static bool value = sizeof(T) <= sizeof(U); }; template struct ptime final { public: using internal_type = TYPE; using mult_type = TYPE; template friend struct ptime; constexpr ptime() noexcept : m_time(0) {} ~ptime() noexcept = default; constexpr ptime(const ptime &rhs) noexcept = default; 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) {} constexpr ptime &operator=(const ptime &rhs) noexcept = default; constexpr ptime &operator=(ptime &&rhs) noexcept = default; constexpr explicit ptime(const double t) = delete; constexpr explicit ptime(const internal_type nom, const internal_type den) noexcept : m_time(nom * (RES / den)) { } template , ptime>::value>> constexpr ptime(const ptime &rhs) noexcept : m_time(static_cast(rhs.m_time)) { } template , ptime>::value, int>> constexpr explicit ptime(const ptime &rhs, [[maybe_unused]] T dummy = 0) noexcept : m_time(static_cast(rhs.m_time)) { } template constexpr ptime &operator+=(const ptime &rhs) noexcept { static_assert(ptime_le, ptime>::value, "Invalid ptime type"); m_time += rhs.m_time; return *this; } template constexpr ptime &operator-=(const ptime &rhs) noexcept { static_assert(ptime_le, ptime>::value, "Invalid ptime type"); m_time -= rhs.m_time; return *this; } template constexpr ptime &operator*=(const M &factor) noexcept { static_assert(plib::is_integral::value, "Factor must be an integral type"); m_time *= factor; return *this; } template constexpr ptime operator-(const ptime &rhs) const noexcept { static_assert(ptime_le, ptime>::value, "Invalid ptime type"); return ptime(m_time - rhs.m_time); } template constexpr ptime operator+(ptime rhs) const noexcept { static_assert(ptime_le, ptime>::value, "Invalid ptime type"); return ptime(m_time + rhs.m_time); } template constexpr ptime operator*(const M &factor) const noexcept { static_assert(plib::is_integral::value, "Factor must be an integral type"); return ptime(m_time * static_cast(factor)); } template constexpr mult_type operator/(const ptime &rhs) const noexcept { static_assert(ptime_le, ptime>::value, "Invalid ptime type"); return static_cast(m_time / rhs.m_time); } template constexpr std::enable_if_t::value, ptime> operator/(const T &rhs) const noexcept { return ptime(m_time / rhs); } template friend constexpr bool operator<(const ptime &lhs, const ptime &rhs) noexcept { static_assert(ptime_le, ptime>::value, "Invalid ptime type"); return (lhs.m_time < rhs.as_raw()); //return (lhs.m_time < rhs.m_time); } template friend constexpr bool operator>(const ptime &lhs, const ptime &rhs) noexcept { static_assert(ptime_le, ptime>::value, "Invalid ptime type"); return (lhs.m_time > rhs.as_raw()); } template friend constexpr bool operator<=(const ptime &lhs, const ptime &rhs) noexcept { return !(lhs > rhs); } template friend constexpr bool operator>=(const ptime &lhs, const ptime &rhs) noexcept { return !(lhs < rhs); } template friend constexpr bool operator==(const ptime &lhs, const ptime &rhs) noexcept { return lhs.m_time == rhs.as_raw(); } template friend constexpr bool operator!=(const ptime &lhs, const ptime &rhs) noexcept { return !(lhs == rhs); } constexpr internal_type as_raw() const noexcept { return m_time; } template ::value, FT>> constexpr FT as_fp() const noexcept { return static_cast(m_time) * inv_res(); } constexpr double as_double() const noexcept { return as_fp(); } constexpr float as_float() const noexcept { return as_fp(); } constexpr long double as_long_double() const noexcept { return as_fp(); } 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 .... template 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 static constexpr std::enable_if_t::value, ptime> from_fp(FT t) noexcept { return ptime(static_cast(plib::floor(t * static_cast(RES) + static_cast(0.5))), RES); } static constexpr ptime from_double(double t) noexcept { return from_fp(t); } static constexpr ptime from_float(float t) noexcept { return from_fp(t); } static constexpr ptime from_long_double(long double t) noexcept { return from_fp(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::max(), RES); } static constexpr internal_type resolution() noexcept { return RES; } 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: template static constexpr FT inv_res() noexcept { return static_cast(1.0) / static_cast(RES); } internal_type m_time; }; } // namespace plib #endif // PTIME_H_