diff --git a/Kernel/include_std/chrono b/Kernel/include_std/chrono index 05cc14dd..35b21a8e 100644 --- a/Kernel/include_std/chrono +++ b/Kernel/include_std/chrono @@ -28,22 +28,25 @@ namespace std class duration { private: - Rep rep_; - std::ratio period_; + Rep _rep; + std::ratio _period; public: + using rep = Rep; + using period = Period; + constexpr duration() = default; duration(const duration &) = default; template - constexpr explicit duration(const Rep2 &r) { rep_ = r; } + constexpr explicit duration(const Rep2 &r) { _rep = r; } template constexpr duration(const duration &d); duration &operator=(const duration &other) = default; - constexpr Rep count() const { return rep_; } + constexpr Rep count() const { return _rep; } static constexpr duration zero() noexcept; static constexpr duration min() noexcept; @@ -51,54 +54,54 @@ namespace std constexpr std::common_type_t operator+() const; constexpr std::common_type_t operator-() const; - constexpr duration operator++(int) { return duration(rep_++); } - constexpr duration operator--(int) { return duration(rep_--); } + constexpr duration operator++(int) { return duration(_rep++); } + constexpr duration operator--(int) { return duration(_rep--); } constexpr duration &operator++() { - ++rep_; + ++_rep; return *this; } constexpr duration &operator--() { - --rep_; + --_rep; return *this; } constexpr duration &operator+=(const duration &d) { - rep_ += d.count(); + _rep += d.count(); return *this; } constexpr duration &operator-=(const duration &d) { - rep_ -= d.count(); + _rep -= d.count(); return *this; } constexpr duration &operator*=(const Rep &rhs) { - rep_ *= rhs; + _rep *= rhs; return *this; } constexpr duration &operator/=(const Rep &rhs) { - rep_ /= rhs; + _rep /= rhs; return *this; } constexpr duration &operator%=(const Rep &rhs) { - rep_ %= rhs; + _rep %= rhs; return *this; } constexpr duration &operator%=(const duration &rhs) { - rep_ %= rhs.count(); + _rep %= rhs.count(); return *this; } }; @@ -120,7 +123,91 @@ namespace std template constexpr ToDuration duration_cast(const std::chrono::duration &d) { - return ToDuration(d.count()); + typedef typename ToDuration::rep ToRep; + typedef typename ToDuration::period ToPeriod; + typedef std::ratio_divide CF; + typedef typename std::common_type::type CR; + CR cr_count = static_cast(d.count()); + CR cr_num = static_cast(CF::num); + CR cr_den = static_cast(CF::den); + + if constexpr (CF::num == 1 && CF::den == 1) + return ToDuration(static_cast(cr_count)); + else if constexpr (CF::den == 1) + return ToDuration(static_cast(cr_count * cr_num)); + else if constexpr (CF::num == 1) + return ToDuration(static_cast(cr_count / cr_den)); + else + return ToDuration(static_cast(cr_count * cr_num / cr_den)); + } + } + + inline namespace literals + { + inline namespace chrono_literals + { +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wliteral-suffix" + constexpr std::chrono::hours operator""h(unsigned long long h) + { + return std::chrono::hours(h); + } + + constexpr std::chrono::duration> operator""h(long double h) + { + return std::chrono::duration>(h); + } + + constexpr std::chrono::minutes operator""min(unsigned long long m) + { + return std::chrono::minutes(m); + } + + constexpr std::chrono::duration> operator""min(long double m) + { + return std::chrono::duration>(m); + } + + constexpr std::chrono::seconds operator""s(unsigned long long s) + { + return std::chrono::seconds(s); + } + + constexpr std::chrono::duration operator""s(long double s) + { + return std::chrono::duration(s); + } + + constexpr std::chrono::milliseconds operator""ms(unsigned long long ms) + { + return std::chrono::milliseconds(ms); + } + + constexpr std::chrono::duration operator""ms(long double ms) + { + return std::chrono::duration(ms); + } + + constexpr std::chrono::microseconds operator""us(unsigned long long us) + { + return std::chrono::microseconds(us); + } + + constexpr std::chrono::duration operator""us(long double us) + { + return std::chrono::duration(us); + } + + constexpr std::chrono::nanoseconds operator""ns(unsigned long long ns) + { + return std::chrono::nanoseconds(ns); + } + + constexpr std::chrono::duration operator""ns(long double ns) + { + return std::chrono::duration(ns); + } +#pragma GCC diagnostic pop } } } diff --git a/Kernel/include_std/ratio b/Kernel/include_std/ratio index eddc96f2..6c905b33 100644 --- a/Kernel/include_std/ratio +++ b/Kernel/include_std/ratio @@ -17,40 +17,173 @@ #pragma once -#include +#include namespace std { + namespace detail + { + template + struct GCD + { + static constexpr intmax_t value = GCD::value; + }; + + template + struct GCD + { + static constexpr intmax_t value = A; + }; + } + template class ratio { + private: + static_assert(Denom != 0, "Denominator cannot be zero"); + static_assert(Num >= -__INTMAX_MAX__ && Denom >= -__INTMAX_MAX__, "Overflow"); + + private: + static constexpr intmax_t __first = Num < 0 ? -Num : Num; + static constexpr intmax_t __second = Denom < 0 ? -Denom : Denom; + static constexpr intmax_t __gcd = detail::GCD<__first, __second>::value; + public: typedef ratio type; - static constexpr intmax_t num = Num; - static constexpr intmax_t denom = Denom; + static constexpr intmax_t num = Denom < 0 ? -Num / __gcd : Num / __gcd; + static constexpr intmax_t den = Denom < 0 ? -Denom / __gcd : Denom / __gcd; + }; + + namespace detail + { + template + constexpr bool __ta_is_ratio = false; + + template + constexpr bool __ta_is_ratio> = true; + + template + constexpr bool __is_equal() + { + return R1::num == R2::num && R1::den == R2::den; + } + + template + constexpr bool __is_less() + { + return R1::num * R2::den < R2::num * R1::den; + } + + template + constexpr bool __is_less_or_equal() + { + return R1::num * R2::den <= R2::num * R1::den; + } + + template + constexpr bool __is_greater() + { + return R1::num * R2::den > R2::num * R1::den; + } + + template + constexpr bool __is_greater_or_equal() + { + return R1::num * R2::den >= R2::num * R1::den; + } }; template - using ratio_add = ratio; - template - using ratio_subtract = ratio; - template - using ratio_multiply = ratio; - template - using ratio_divide = ratio; + struct ratio_add + { + static_assert(detail::__ta_is_ratio && detail::__ta_is_ratio, "Both template arguments must be std::ratio"); + + static constexpr intmax_t num = R1::num * R2::den + R2::num * R1::den; + static constexpr intmax_t den = R1::den * R2::den; + + using type = ratio; + }; template - struct ratio_equal; + struct ratio_subtract + { + static_assert(detail::__ta_is_ratio && detail::__ta_is_ratio, "Both template arguments must be std::ratio"); + + static constexpr intmax_t num = R1::num * R2::den - R2::num * R1::den; + static constexpr intmax_t den = R1::den * R2::den; + + using type = ratio; + }; + template - struct ratio_not_equal; + struct ratio_multiply + { + static_assert(detail::__ta_is_ratio && detail::__ta_is_ratio, "Both templates must be ratios"); + + static constexpr intmax_t num = R1::num * R2::num; + static constexpr intmax_t den = R1::den * R2::den; + + using type = ratio; + }; + template - struct ratio_less; + struct ratio_divide + { + static_assert(R2::num != 0, "Divide by zero"); + + static constexpr intmax_t num = R1::num * R2::den; + static constexpr intmax_t den = R1::den * R2::num; + + using type = ratio; + }; + template - struct ratio_less_equal; + struct ratio_equal : public std::integral_constant()> + { + }; + template - struct ratio_greater; + struct ratio_not_equal : public std::integral_constant()> + { + }; + template - struct ratio_greater_equal; + struct ratio_less : public std::integral_constant()> + { + }; + + template + struct ratio_less_equal : public std::integral_constant()> + { + }; + + template + struct ratio_greater : public std::integral_constant()> + { + }; + + template + struct ratio_greater_equal : public std::integral_constant()> + { + }; + + template + constexpr bool ratio_equal_v = ratio_equal::value; + + template + constexpr bool ratio_not_equal_v = ratio_not_equal::value; + + template + constexpr bool ratio_less_v = ratio_less::value; + + template + constexpr bool ratio_less_equal_v = ratio_less_equal::value; + + template + constexpr bool ratio_greater_v = ratio_greater::value; + + template + constexpr bool ratio_greater_equal_v = ratio_greater_equal::value; // typedef ratio<1, 1000000000000000000000000000000> quecto; // typedef ratio<1, 1000000000000000000000000000> ronto; diff --git a/Kernel/include_std/thread b/Kernel/include_std/thread index 51085018..fe2478d1 100644 --- a/Kernel/include_std/thread +++ b/Kernel/include_std/thread @@ -21,6 +21,7 @@ #include #include #include +#include #include extern Tasking::Task *TaskManager; @@ -84,17 +85,26 @@ namespace std namespace this_thread { - thread::id get_id() noexcept; - void yield() noexcept; - template - void sleep_until(const chrono::time_point &abs_time); + thread::id get_id() noexcept; template - void sleep_for(const chrono::duration &rel_time) + void sleep_for(const chrono::duration &sleep_duration) { - TaskManager->Sleep(chrono::duration_cast(rel_time).count()); + TaskManager->Sleep(chrono::duration_cast(sleep_duration).count()); + } + + template + void sleep_until(const std::chrono::time_point &sleep_time) + { + TaskManager->Sleep(chrono::duration_cast(sleep_time - Clock::now()).count()); } } + + template + std::basic_ostream &operator<<(std::basic_ostream &ost, std::thread::id id) + { + return ost << id; + } }