diff --git a/Kernel/core/random.cpp b/Kernel/core/random.cpp index 59449d8c..f71938f6 100644 --- a/Kernel/core/random.cpp +++ b/Kernel/core/random.cpp @@ -25,14 +25,14 @@ namespace Random __constructor void InitRandomSeed() { - if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) != 0) + if (std::strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) != 0) { - if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) + if (std::strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000007_ECX_0 cpuid; RDSEEDFlag = cpuid.EBX.RDSEED; } - else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) + else if (std::strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000007_0 cpuid; RDSEEDFlag = cpuid.EBX.RDSEED; @@ -41,14 +41,14 @@ namespace Random else RDSEEDFlag = false; - if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) != 0) + if (std::strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) != 0) { - if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) + if (std::strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000001 cpuid; RDRANDFlag = cpuid.ECX.RDRAND; } - else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) + else if (std::strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000001 cpuid; RDRANDFlag = cpuid.ECX.RDRAND; @@ -67,8 +67,7 @@ namespace Random if (RDRANDFlag) { uint16_t RDRANDValue = 0; - asmv("1: rdrand %0; jnc 1b" - : "=r"(RDRANDValue)); + asmv("1: rdrand %0; jnc 1b" : "=r"(RDRANDValue)); return RDRANDValue; } @@ -84,8 +83,7 @@ namespace Random if (RDRANDFlag) { uint32_t RDRANDValue = 0; - asmv("1: rdrand %0; jnc 1b" - : "=r"(RDRANDValue)); + asmv("1: rdrand %0; jnc 1b" : "=r"(RDRANDValue)); return RDRANDValue; } @@ -101,8 +99,7 @@ namespace Random if (RDRANDFlag) { uintptr_t RDRANDValue = 0; - asmv("1: rdrand %0; jnc 1b" - : "=r"(RDRANDValue)); + asmv("1: rdrand %0; jnc 1b" : "=r"(RDRANDValue)); return RDRANDValue; } diff --git a/Kernel/include_std/chrono b/Kernel/include_std/chrono new file mode 100644 index 00000000..48d6ab0b --- /dev/null +++ b/Kernel/include_std/chrono @@ -0,0 +1,119 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#pragma once + +#include +#include + +namespace std +{ + namespace chrono + { + template > + class duration + { + private: + Rep rep_; + std::ratio period_; + + public: + constexpr duration() = default; + duration(const duration &) = default; + + template + constexpr explicit duration(const Rep2 &r); + + template + constexpr duration(const duration &d); + + duration &operator=(const duration &other) = default; + + constexpr Rep count() const; + static constexpr duration zero() noexcept; + static constexpr duration min() noexcept; + static constexpr duration max() noexcept; + 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++() + { + ++rep_; + return *this; + } + + constexpr duration &operator--() + { + --rep_; + return *this; + } + + constexpr duration &operator+=(const duration &d) + { + rep_ += d.count(); + return *this; + } + + constexpr duration &operator-=(const duration &d) + { + rep_ -= d.count(); + return *this; + } + + constexpr duration &operator*=(const Rep &rhs) + { + rep_ *= rhs; + return *this; + } + + constexpr duration &operator/=(const Rep &rhs) + { + rep_ /= rhs; + return *this; + } + + constexpr duration &operator%=(const Rep &rhs) + { + rep_ %= rhs; + return *this; + } + + constexpr duration &operator%=(const duration &rhs) + { + rep_ %= rhs.count(); + return *this; + } + }; + + template + class time_point; + + using nanoseconds = std::chrono::duration; + using microseconds = std::chrono::duration; + using milliseconds = std::chrono::duration; + using seconds = std::chrono::duration; + using minutes = std::chrono::duration>; + using hours = std::chrono::duration>; + using days = std::chrono::duration>; + using weeks = std::chrono::duration>; + using months = std::chrono::duration>; + using years = std::chrono::duration>; + } +} diff --git a/Kernel/include_std/cstdint b/Kernel/include_std/cstdint new file mode 100644 index 00000000..27356321 --- /dev/null +++ b/Kernel/include_std/cstdint @@ -0,0 +1,68 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#pragma once + +namespace std +{ + typedef __INT8_TYPE__ int8_t; + typedef __INT16_TYPE__ int16_t; + typedef __INT32_TYPE__ int32_t; + typedef __INT64_TYPE__ int64_t; + + typedef __UINT8_TYPE__ uint8_t; + typedef __UINT16_TYPE__ uint16_t; + typedef __UINT32_TYPE__ uint32_t; + typedef __UINT64_TYPE__ uint64_t; + + typedef __INT_LEAST8_TYPE__ int_least8_t; + typedef __INT_LEAST16_TYPE__ int_least16_t; + typedef __INT_LEAST32_TYPE__ int_least32_t; + typedef __INT_LEAST64_TYPE__ int_least64_t; + + typedef __UINT_LEAST8_TYPE__ uint_least8_t; + typedef __UINT_LEAST16_TYPE__ uint_least16_t; + typedef __UINT_LEAST32_TYPE__ uint_least32_t; + typedef __UINT_LEAST64_TYPE__ uint_least64_t; + + typedef __INT_FAST8_TYPE__ int_fast8_t; + typedef __INT_FAST16_TYPE__ int_fast16_t; + typedef __INT_FAST32_TYPE__ int_fast32_t; + typedef __INT_FAST64_TYPE__ int_fast64_t; + + typedef __UINT_FAST8_TYPE__ uint_fast8_t; + typedef __UINT_FAST16_TYPE__ uint_fast16_t; + typedef __UINT_FAST32_TYPE__ uint_fast32_t; + typedef __UINT_FAST64_TYPE__ uint_fast64_t; + + typedef __INTPTR_TYPE__ intptr_t; + typedef __UINTPTR_TYPE__ uintptr_t; + +#define INT8_C(val) static_cast(val) +#define INT16_C(val) static_cast(val) +#define INT32_C(val) static_cast(val) +#define INT64_C(val) static_cast(val) + +#define INTMAX_C(val) static_cast(val) + +#define UINT8_C(val) static_cast(val) +#define UINT16_C(val) static_cast(val) +#define UINT32_C(val) static_cast(val) +#define UINT64_C(val) static_cast(val) + +#define UINTMAX_C(val) static_cast(val) +} diff --git a/Kernel/include_std/cstring b/Kernel/include_std/cstring index fe0b0b7d..cd917c6e 100644 --- a/Kernel/include_std/cstring +++ b/Kernel/include_std/cstring @@ -16,4 +16,13 @@ */ #pragma once -#include + +namespace std +{ + int strcmp(const char *lhs, const char *rhs) + { + for (; *lhs == *rhs && *lhs; lhs++, rhs++) + ; + return *(unsigned char *)lhs - *(unsigned char *)rhs; + } +} diff --git a/Kernel/include_std/exception b/Kernel/include_std/exception index ae47209f..8562d41e 100644 --- a/Kernel/include_std/exception +++ b/Kernel/include_std/exception @@ -15,8 +15,7 @@ along with Fennix Kernel. If not, see . */ -#ifndef __FENNIX_KERNEL_EXCEPTION_H__ -#define __FENNIX_KERNEL_EXCEPTION_H__ +#pragma once #include @@ -36,12 +35,15 @@ namespace std typedef void (*unexpected_handler)(); [[noreturn]] void terminate() noexcept; - std::terminate_handler set_terminate(std::terminate_handler f) noexcept; - std::terminate_handler get_terminate() noexcept; + terminate_handler set_terminate(terminate_handler f) noexcept; + terminate_handler get_terminate() noexcept; [[noreturn]] void unexpected(); - std::unexpected_handler set_unexpected(std::unexpected_handler f) noexcept; - std::unexpected_handler get_unexpected() noexcept; -} + unexpected_handler set_unexpected(unexpected_handler f) noexcept; + unexpected_handler get_unexpected() noexcept; -#endif // !__FENNIX_KERNEL_EXCEPTION_H__ + using exception_ptr = uintptr_t; + + template + std::exception_ptr make_exception_ptr(E e) noexcept; +} diff --git a/Kernel/include_std/functional b/Kernel/include_std/functional index e58d5588..faa80615 100644 --- a/Kernel/include_std/functional +++ b/Kernel/include_std/functional @@ -259,4 +259,10 @@ namespace std return lhs < rhs; } }; + + template + constexpr typename std::result_of::type bind(F &&f, Args &&...args); + + template + constexpr R bind(F &&f, Args &&...args); } diff --git a/Kernel/include_std/future b/Kernel/include_std/future new file mode 100644 index 00000000..980f07ab --- /dev/null +++ b/Kernel/include_std/future @@ -0,0 +1,276 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace std +{ + enum class future_errc + { + broken_promise = 0, + future_already_retrieved = 1, + promise_already_satisfied = 2, + no_state = 3 + }; + + enum class launch : std::uint_least8_t + { + async = 0, + deferred = 1, + }; + + enum class future_status + { + ready, + timeout, + deferred + }; + + template <> + struct is_error_code_enum : public true_type + { + }; + error_condition make_error_condition(future_errc e) noexcept; + + const error_category &future_category() noexcept + { + static const error_category cat; + return cat; + } + + inline std::error_code make_error_code(future_errc e) noexcept + { + return std::error_code(static_cast(e), future_category()); + } + + class future_error; + + template + class promise; + template + class promise; + template <> + class promise; + + template + void swap(promise &x, promise &y) noexcept; + + template + struct uses_allocator, Alloc>; + + template + class future; + template + class future; + template <> + class future; + + template + class shared_future; + template + class shared_future; + template <> + class shared_future; + + template + class packaged_task; // not defined + + template + class packaged_task; + + template + void swap(packaged_task &, packaged_task &) noexcept; + + template + future::type> async(launch policy, Fn &&fn, Args &&...args) + { + using ReturnType = std::invoke_result_t, std::decay_t...>; + + if (policy == std::launch::async) + { + auto task = std::make_shared>( + std::bind(std::forward(fn), std::forward(args)...)); + + std::future future = task->get_future(); + std::thread([task]() + { (*task)(); }) + .detach(); + + return future; + } + else if (policy == std::launch::deferred) + { + return std::async(std::launch::deferred, std::forward(fn), std::forward(args)...); + } + else + { + throw std::invalid_argument("Invalid launch policy"); + } + } + + template + future::type> async(Fn &&fn, Args &&...args) + { + return async(std::launch::async /* | std::launch::deferred*/, std::forward(fn), std::forward(args)...); + } + + class future_error : public logic_error + { + private: + error_code ec_; + + public: + future_error(const future_error &other) noexcept; + explicit future_error(std::future_errc ec); + future_error &operator=(const future_error &other) noexcept; + const std::error_code &code() const noexcept; + virtual const char *what() const noexcept; + }; + + template + class promise + { + public: + promise(); + template + promise(allocator_arg_t, const Allocator &a); + promise(promise &&rhs) noexcept; + promise(const promise &) = delete; + ~promise(); + + promise &operator=(promise &&rhs) noexcept; + promise &operator=(const promise &) = delete; + void swap(promise &other) noexcept; + + future get_future(); + + void set_value(const R &value); + void set_value(R &&value); + void set_value(R &value); + void set_value(); + + void set_exception(exception_ptr p); + + void set_value_at_thread_exit(/* see description */); + void set_exception_at_thread_exit(exception_ptr p); + }; + + template + void swap(promise &x, promise &y) noexcept; + + template + struct uses_allocator, Alloc>; + + template + class future + { + public: + future() noexcept; + future(future &&) noexcept; + future(const future &) = delete; + ~future(); + future &operator=(const future &) = delete; + future &operator=(future &&) noexcept; + shared_future share() noexcept; + + R get(); + // R &get(); + // void get(); + + bool valid() const noexcept; + + void wait() const; + template + future_status wait_for(const chrono::duration &rel_time) const; + template + future_status wait_until(const chrono::time_point &abs_time) const; + }; + + template + class shared_future + { + public: + shared_future() noexcept; + shared_future(const shared_future &rhs) noexcept; + shared_future(future &&) noexcept; + shared_future(shared_future &&rhs) noexcept; + ~shared_future(); + shared_future &operator=(const shared_future &rhs) noexcept; + shared_future &operator=(shared_future &&rhs) noexcept; + + const R &get() const; + // R &get() const; + // void get() const; + + bool valid() const noexcept; + + void wait() const; + template + future_status wait_for(const chrono::duration &rel_time) const; + template + future_status wait_until(const chrono::time_point &abs_time) const; + }; + + template + class packaged_task; + + template + class packaged_task + { + public: + packaged_task() noexcept; + template + explicit packaged_task(F &&f); + ~packaged_task(); + + packaged_task(const packaged_task &) = delete; + packaged_task &operator=(const packaged_task &) = delete; + + packaged_task(packaged_task &&rhs) noexcept; + packaged_task &operator=(packaged_task &&rhs) noexcept; + void swap(packaged_task &other) noexcept; + + bool valid() const noexcept; + + future get_future(); + + void operator()(ArgTypes...); + void make_ready_at_thread_exit(ArgTypes...); + + void reset(); + }; + + template + packaged_task(R (*)(ArgTypes...)) -> packaged_task; + + // template + // packaged_task(F) -> packaged_task; + + template + void swap(packaged_task &x, packaged_task &y) noexcept; +} diff --git a/Kernel/include_std/memory b/Kernel/include_std/memory index 8fabeeeb..9ec5ca03 100644 --- a/Kernel/include_std/memory +++ b/Kernel/include_std/memory @@ -28,7 +28,7 @@ namespace std { - namespace __memory__detail + namespace detail { template constexpr bool is_unbounded_array_v = false; @@ -516,14 +516,14 @@ namespace std } template - std::enable_if_t<__memory__detail::is_unbounded_array_v, std::unique_ptr> + std::enable_if_t, std::unique_ptr> make_unique(std::size_t n) { return std::unique_ptr(new std::remove_extent_t[n]()); } template - std::enable_if_t<__memory__detail::is_bounded_array_v> make_unique(Args &&...) = delete; + std::enable_if_t> make_unique(Args &&...) = delete; template requires(!std::is_array_v) @@ -603,4 +603,162 @@ namespace std { lhs.swap(rhs); } + + template + struct uses_allocator : std::integral_constant + { + }; + + template + constexpr bool uses_allocator_v = uses_allocator::value; + + struct allocator_arg_t + { + explicit allocator_arg_t() = default; + }; + + constexpr std::allocator_arg_t allocator_arg{}; + + template + class auto_ptr; + + template <> + class auto_ptr; + + template + class weak_ptr; + + template + class shared_ptr + { + public: + using weak_type = std::weak_ptr; + using element_type = std::remove_extent_t; + + constexpr shared_ptr() noexcept; + constexpr shared_ptr(std::nullptr_t) noexcept; + + template + explicit shared_ptr(Y *ptr); + + template + shared_ptr(Y *ptr, Deleter d); + + template + shared_ptr(std::nullptr_t ptr, Deleter d); + + template + shared_ptr(Y *ptr, Deleter d, Alloc alloc); + + template + shared_ptr(std::nullptr_t ptr, Deleter d, Alloc alloc); + + template + shared_ptr(const shared_ptr &r, element_type *ptr) noexcept; + + template + shared_ptr(shared_ptr &&r, element_type *ptr) noexcept; + + shared_ptr(const shared_ptr &r) noexcept; + + template + shared_ptr(const shared_ptr &r) noexcept; + + shared_ptr(shared_ptr &&r) noexcept; + + template + shared_ptr(shared_ptr &&r) noexcept; + + template + explicit shared_ptr(const std::weak_ptr &r); + + template + shared_ptr(std::auto_ptr &&r); + + template + shared_ptr(std::unique_ptr &&r); + + ~shared_ptr(); + + shared_ptr &operator=(const shared_ptr &r) noexcept; + + template + shared_ptr &operator=(const shared_ptr &r) noexcept; + + shared_ptr &operator=(shared_ptr &&r) noexcept; + + template + shared_ptr &operator=(shared_ptr &&r) noexcept; + + template + shared_ptr &operator=(std::auto_ptr &&r); + + template + shared_ptr &operator=(std::unique_ptr &&r); + + void reset() noexcept; + + template + void reset(Y *ptr); + + template + void reset(Y *ptr, Deleter d); + + template + void reset(Y *ptr, Deleter d, Alloc alloc); + + void swap(shared_ptr &r) noexcept; + + T *get() const noexcept; + + // element_type *get() const noexcept; + + T &operator*() const noexcept; + + T *operator->() const noexcept; + + element_type &operator[](std::ptrdiff_t idx) const; + + long use_count() const noexcept; + + bool unique() const noexcept; + + explicit operator bool() const noexcept { return get() != nullptr; } + + template + bool owner_before(const shared_ptr &other) const noexcept; + + template + bool owner_before(const std::weak_ptr &other) const noexcept; + + std::size_t owner_hash() const noexcept; + + template + bool owner_equal(const std::shared_ptr &other) const noexcept; + + template + bool owner_equal(const std::weak_ptr &other) const noexcept; + }; + + template + shared_ptr make_shared(Args &&...args); + + template + shared_ptr make_shared(std::size_t N); + + template + shared_ptr make_shared(); + + template + shared_ptr make_shared(std::size_t N, const std::remove_extent_t &u); + + template + shared_ptr make_shared(const std::remove_extent_t &u); + + template + shared_ptr make_shared_for_overwrite(); + + template + shared_ptr make_shared_for_overwrite(std::size_t N); + } diff --git a/Kernel/include_std/ratio b/Kernel/include_std/ratio new file mode 100644 index 00000000..eddc96f2 --- /dev/null +++ b/Kernel/include_std/ratio @@ -0,0 +1,79 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +#pragma once + +#include + +namespace std +{ + template + class ratio + { + public: + typedef ratio type; + static constexpr intmax_t num = Num; + static constexpr intmax_t denom = Denom; + }; + + template + using ratio_add = ratio; + template + using ratio_subtract = ratio; + template + using ratio_multiply = ratio; + template + using ratio_divide = ratio; + + template + struct ratio_equal; + template + struct ratio_not_equal; + template + struct ratio_less; + template + struct ratio_less_equal; + template + struct ratio_greater; + template + struct ratio_greater_equal; + + // typedef ratio<1, 1000000000000000000000000000000> quecto; + // typedef ratio<1, 1000000000000000000000000000> ronto; + // typedef ratio<1, 1000000000000000000000000> yocto; + // typedef ratio<1, 1000000000000000000000> zepto; + typedef ratio<1, 1000000000000000000> atto; + typedef ratio<1, 1000000000000000> femto; + typedef ratio<1, 1000000000000> pico; + typedef ratio<1, 1000000000> nano; + typedef ratio<1, 1000000> micro; + typedef ratio<1, 1000> milli; + typedef ratio<1, 100> centi; + typedef ratio<1, 10> deci; + typedef ratio<10, 1> deca; + typedef ratio<100, 1> hecto; + typedef ratio<1000, 1> kilo; + typedef ratio<1000000, 1> mega; + typedef ratio<1000000000, 1> giga; + typedef ratio<1000000000000, 1> tera; + typedef ratio<1000000000000000, 1> peta; + typedef ratio<1000000000000000000, 1> exa; + // typedef ratio<1000000000000000000000, 1> zetta; + // typedef ratio<1000000000000000000000000, 1> yotta; + // typedef ratio<1000000000000000000000000000, 1> ronna; + // typedef ratio<1000000000000000000000000000000, 1> quetta; +} diff --git a/Kernel/include_std/stdexcept b/Kernel/include_std/stdexcept index 2c1806e7..dedee3ee 100644 --- a/Kernel/include_std/stdexcept +++ b/Kernel/include_std/stdexcept @@ -19,6 +19,7 @@ #include #include +#include #include namespace std @@ -116,4 +117,13 @@ namespace std out_of_range &operator=(out_of_range &&) = default; virtual ~out_of_range() = default; }; + + class invalid_argument : public logic_error + { + public: + // invalid_argument(const std::string &what_arg) = default; + invalid_argument(const char *what_arg) : logic_error(what_arg) {} + invalid_argument(const invalid_argument &other) = default; + invalid_argument &operator=(const invalid_argument &other) = default; + }; } diff --git a/Kernel/include_std/system_error b/Kernel/include_std/system_error index 0dac7622..40f0b6f2 100644 --- a/Kernel/include_std/system_error +++ b/Kernel/include_std/system_error @@ -17,8 +17,92 @@ #pragma once +#include + namespace std { + enum class errc + { + address_family_not_supported = EAFNOSUPPORT, + address_in_use = EADDRINUSE, + address_not_available = EADDRNOTAVAIL, + already_connected = EISCONN, + argument_list_too_long = E2BIG, + argument_out_of_domain = EDOM, + bad_address = EFAULT, + bad_file_descriptor = EBADF, + bad_message = EBADMSG, + broken_pipe = EPIPE, + connection_aborted = ECONNABORTED, + connection_already_in_progress = EALREADY, + connection_refused = ECONNREFUSED, + connection_reset = ECONNRESET, + cross_device_link = EXDEV, + destination_address_required = EDESTADDRREQ, + device_or_resource_busy = EBUSY, + directory_not_empty = ENOTEMPTY, + executable_format_error = ENOEXEC, + file_exists = EEXIST, + file_too_large = EFBIG, + filename_too_long = ENAMETOOLONG, + function_not_supported = ENOSYS, + host_unreachable = EHOSTUNREACH, + identifier_removed = EIDRM, + illegal_byte_sequence = EILSEQ, + inappropriate_io_control_operation = ENOTTY, + interrupted = EINTR, + invalid_argument = EINVAL, + invalid_seek = ESPIPE, + io_error = EIO, + is_a_directory = EISDIR, + message_size = EMSGSIZE, + network_down = ENETDOWN, + network_reset = ENETRESET, + network_unreachable = ENETUNREACH, + no_buffer_space = ENOBUFS, + no_child_process = ECHILD, + no_link = ENOLINK, + no_lock_available = ENOLCK, + no_message_available = ENODATA, + no_message = ENOMSG, + no_protocol_option = ENOPROTOOPT, + no_space_on_device = ENOSPC, + no_stream_resources = ENOSR, + no_such_device_or_address = ENXIO, + no_such_device = ENODEV, + no_such_file_or_directory = ENOENT, + no_such_process = ESRCH, + not_a_directory = ENOTDIR, + not_a_socket = ENOTSOCK, + not_a_stream = ENOSTR, + not_connected = ENOTCONN, + not_enough_memory = ENOMEM, + not_supported = ENOTSUP, + operation_canceled = ECANCELED, + operation_in_progress = EINPROGRESS, + operation_not_permitted = EPERM, + operation_not_supported = EOPNOTSUPP, + operation_would_block = EWOULDBLOCK, + owner_dead = EOWNERDEAD, + permission_denied = EACCES, + protocol_error = EPROTO, + protocol_not_supported = EPROTONOSUPPORT, + read_only_file_system = EROFS, + resource_deadlock_would_occur = EDEADLK, + resource_unavailable_try_again = EAGAIN, + result_out_of_range = ERANGE, + state_not_recoverable = ENOTRECOVERABLE, + stream_timeout = ETIME, + text_file_busy = ETXTBSY, + timed_out = ETIMEDOUT, + too_many_files_open_in_system = ENFILE, + too_many_files_open = EMFILE, + too_many_links = EMLINK, + too_many_symbolic_link_levels = ELOOP, + value_too_large = EOVERFLOW, + wrong_protocol_type = EPROTOTYPE + }; + class error_category { /* https://en.cppreference.com/w/cpp/error/error_category */ @@ -55,4 +139,14 @@ namespace std /* https://en.cppreference.com/w/cpp/error/error_code */ }; + + class error_condition; + + template + struct is_error_code_enum : std::integral_constant + { + }; + + template + constexpr bool is_error_code_enum_v = is_error_code_enum::value; } diff --git a/Kernel/include_std/type_traits b/Kernel/include_std/type_traits index 5508a9fe..dc610ab2 100644 --- a/Kernel/include_std/type_traits +++ b/Kernel/include_std/type_traits @@ -290,7 +290,7 @@ namespace std reinterpret_cast(t); f(0); p + t; - } > {}; + }>{}; template constexpr bool is_integral_v = is_integral::value; @@ -659,4 +659,38 @@ namespace std template using common_type_t = typename common_type::type; + + namespace detail + { + template + constexpr T &&__result_of_forward(std::remove_reference_t &t) noexcept + { + return static_cast(t); + } + + template + auto INVOKE(F &&f, ArgTypes &&...args) + -> decltype(__result_of_forward(f)(__result_of_forward(args)...)) + { + return __result_of_forward(f)(__result_of_forward(args)...); + } + } + + template + class result_of; + + template + struct result_of + { + using type = decltype(detail::INVOKE(std::declval(), std::declval()...)); + }; + + template + struct invoke_result; + + template + using result_of_t = typename result_of::type; + + // template + // using invoke_result_t = typename invoke_result::type; } diff --git a/Kernel/library/std/future.cpp b/Kernel/library/std/future.cpp new file mode 100644 index 00000000..24c2b2ee --- /dev/null +++ b/Kernel/library/std/future.cpp @@ -0,0 +1,23 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +// #include + +namespace std +{ + +} diff --git a/Kernel/tests/rng.cpp b/Kernel/tests/rng.cpp index f94df401..84ef5df5 100644 --- a/Kernel/tests/rng.cpp +++ b/Kernel/tests/rng.cpp @@ -25,18 +25,18 @@ __constructor void TestRandom() { #if defined(__amd64__) || defined(__i386__) int RDRANDFlag = 0; - if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) + if (std::strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000001 cpuid; RDRANDFlag = cpuid.ECX.RDRAND; } - else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) + else if (std::strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000001 cpuid; RDRANDFlag = cpuid.ECX.RDRAND; } - if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) + if (std::strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) == 0) RDRANDFlag = 0; if (RDRANDFlag) diff --git a/Kernel/tests/stl/future_test.cpp b/Kernel/tests/stl/future_test.cpp new file mode 100644 index 00000000..48e4d825 --- /dev/null +++ b/Kernel/tests/stl/future_test.cpp @@ -0,0 +1,136 @@ +/* + This file is part of Fennix Kernel. + + Fennix Kernel is free software: you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of + the License, or (at your option) any later version. + + Fennix Kernel is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Fennix Kernel. If not, see . +*/ + +// #include +// #include +// #include + +void test_stl_future() +{ + // { + // std::future f = std::async(std::launch::async, [] + // { + // for (uint64_t i = 0; i < 100000; ++i); + // return 1; }); + + // debug("waiting for future"); + // int result = f.get(); + // debug("future result is %d", result); + // } + + // { + // std::promise p; + // std::future f = p.get_future(); + + // assert(f.valid()); + // p.set_value(42); + // assert(f.get() == 42); + + // try + // { + // f.get(); + // assert(false); + // } + // catch (const std::future_error &e) + // { + // // assert(e.code() == std::future_errc::future_already_retrieved); + // } + // } + + // { + // auto future = std::async([]() + // { return 42; }); + // assert(future.get() == 42); + // } + + // { + // std::promise p; + // std::future f = p.get_future(); + // std::shared_future sf = f.share(); + + // p.set_value(42); + + // assert(sf.get() == 42); + // assert(sf.get() == 42); + // } + + // { + // std::promise p; + // std::future f = p.get_future(); + + // auto status = f.wait_for(std::chrono::milliseconds(100)); + // assert(status == std::future_status::timeout); + + // p.set_value(42); + // status = f.wait_for(std::chrono::milliseconds(100)); + // assert(status == std::future_status::ready); + // } + + // { + // auto future = std::async(std::launch::async, []() + // { return 42; }); + // assert(future.get() == 42); + + // auto deferred = std::async(std::launch::deferred, []() + // { return 42; }); + // assert(deferred.get() == 42); + // } + + // { + // std::promise p1, p2; + // std::future f1 = p1.get_future(); + // std::future f2 = p2.get_future(); + + // p1.set_value(42); + // p2.set_value(24); + + // assert(f1.get() == 42); + // assert(f2.get() == 24); + // } + + // { + // std::promise p; + // std::future f1 = p.get_future(); + // std::future f2 = std::move(f1); + + // p.set_value(42); + // assert(f2.get() == 42); + // } + + // { + // std::promise p; + // std::shared_future sf = p.get_future().share(); + + // std::atomic sum{0}; + // std::vector threads; + + // for (int i = 0; i < 10; ++i) + // { + // threads.emplace_back([&sf, &sum]() + // { sum += sf.get(); }); + // } + + // p.set_value(42); + + // for (auto &t : threads) + // { + // t.join(); + // } + + // assert(sum == 420); + // } +} diff --git a/Kernel/tests/stl/stl.cpp b/Kernel/tests/stl/stl.cpp index 68042e4f..d2b200e5 100644 --- a/Kernel/tests/stl/stl.cpp +++ b/Kernel/tests/stl/stl.cpp @@ -25,6 +25,7 @@ void test_stl_vector(); void test_stl_bitset(); void test_stl_string(); void test_stl_unordered_map() {} +void test_stl_future(); void Test_stl() { @@ -36,6 +37,7 @@ void Test_stl() test_stl_bitset(); test_stl_string(); test_stl_unordered_map(); + test_stl_future(); } -#endif // DEBUG \ No newline at end of file +#endif // DEBUG