mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-25 22:14:34 +00:00
feat(kernel): update stl headers
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
parent
31181d5b5d
commit
93d897e95c
@ -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;
|
||||
}
|
||||
|
||||
|
119
Kernel/include_std/chrono
Normal file
119
Kernel/include_std/chrono
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ratio>
|
||||
#include <type_traits>
|
||||
|
||||
namespace std
|
||||
{
|
||||
namespace chrono
|
||||
{
|
||||
template <class Rep, class Period = std::ratio<1>>
|
||||
class duration
|
||||
{
|
||||
private:
|
||||
Rep rep_;
|
||||
std::ratio<Period::num, Period::denom> period_;
|
||||
|
||||
public:
|
||||
constexpr duration() = default;
|
||||
duration(const duration &) = default;
|
||||
|
||||
template <class Rep2>
|
||||
constexpr explicit duration(const Rep2 &r);
|
||||
|
||||
template <class Rep2, class Period2>
|
||||
constexpr duration(const duration<Rep2, Period2> &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<duration> operator+() const;
|
||||
constexpr std::common_type_t<duration> 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 Clock, class Duration = typename Clock::duration>
|
||||
class time_point;
|
||||
|
||||
using nanoseconds = std::chrono::duration<int64_t, std::nano>;
|
||||
using microseconds = std::chrono::duration<int64_t, std::micro>;
|
||||
using milliseconds = std::chrono::duration<int64_t, std::milli>;
|
||||
using seconds = std::chrono::duration<int64_t>;
|
||||
using minutes = std::chrono::duration<int64_t, std::ratio<60>>;
|
||||
using hours = std::chrono::duration<int64_t, std::ratio<3600>>;
|
||||
using days = std::chrono::duration<int64_t, std::ratio<86400>>;
|
||||
using weeks = std::chrono::duration<int64_t, std::ratio<604800>>;
|
||||
using months = std::chrono::duration<int64_t, std::ratio<2629746>>;
|
||||
using years = std::chrono::duration<int64_t, std::ratio<31556952>>;
|
||||
}
|
||||
}
|
68
Kernel/include_std/cstdint
Normal file
68
Kernel/include_std/cstdint
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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<int_least8_t>(val)
|
||||
#define INT16_C(val) static_cast<int_least16_t>(val)
|
||||
#define INT32_C(val) static_cast<int_least32_t>(val)
|
||||
#define INT64_C(val) static_cast<int_least64_t>(val)
|
||||
|
||||
#define INTMAX_C(val) static_cast<intmax_t>(val)
|
||||
|
||||
#define UINT8_C(val) static_cast<unsigned int_least8_t>(val)
|
||||
#define UINT16_C(val) static_cast<unsigned int_least16_t>(val)
|
||||
#define UINT32_C(val) static_cast<unsigned int_least32_t>(val)
|
||||
#define UINT64_C(val) static_cast<unsigned int_least64_t>(val)
|
||||
|
||||
#define UINTMAX_C(val) static_cast<uintmax_t>(val)
|
||||
}
|
@ -16,4 +16,13 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <convert.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
int strcmp(const char *lhs, const char *rhs)
|
||||
{
|
||||
for (; *lhs == *rhs && *lhs; lhs++, rhs++)
|
||||
;
|
||||
return *(unsigned char *)lhs - *(unsigned char *)rhs;
|
||||
}
|
||||
}
|
||||
|
@ -15,8 +15,7 @@
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_EXCEPTION_H__
|
||||
#define __FENNIX_KERNEL_EXCEPTION_H__
|
||||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
|
||||
@ -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 <class E>
|
||||
std::exception_ptr make_exception_ptr(E e) noexcept;
|
||||
}
|
||||
|
@ -259,4 +259,10 @@ namespace std
|
||||
return lhs < rhs;
|
||||
}
|
||||
};
|
||||
|
||||
template <class F, class... Args>
|
||||
constexpr typename std::result_of<F()>::type bind(F &&f, Args &&...args);
|
||||
|
||||
template <class R, class F, class... Args>
|
||||
constexpr R bind(F &&f, Args &&...args);
|
||||
}
|
||||
|
276
Kernel/include_std/future
Normal file
276
Kernel/include_std/future
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <exception>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <type_traits>
|
||||
#include <system_error>
|
||||
#include <utility>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
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<future_errc> : 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<int>(e), future_category());
|
||||
}
|
||||
|
||||
class future_error;
|
||||
|
||||
template <class R>
|
||||
class promise;
|
||||
template <class R>
|
||||
class promise<R &>;
|
||||
template <>
|
||||
class promise<void>;
|
||||
|
||||
template <class R>
|
||||
void swap(promise<R> &x, promise<R> &y) noexcept;
|
||||
|
||||
template <class R, class Alloc>
|
||||
struct uses_allocator<promise<R>, Alloc>;
|
||||
|
||||
template <class R>
|
||||
class future;
|
||||
template <class R>
|
||||
class future<R &>;
|
||||
template <>
|
||||
class future<void>;
|
||||
|
||||
template <class R>
|
||||
class shared_future;
|
||||
template <class R>
|
||||
class shared_future<R &>;
|
||||
template <>
|
||||
class shared_future<void>;
|
||||
|
||||
template <class>
|
||||
class packaged_task; // not defined
|
||||
|
||||
template <class R, class... ArgTypes>
|
||||
class packaged_task<R(ArgTypes...)>;
|
||||
|
||||
template <class R, class... ArgTypes>
|
||||
void swap(packaged_task<R(ArgTypes...)> &, packaged_task<R(ArgTypes...)> &) noexcept;
|
||||
|
||||
template <class Fn, class... Args>
|
||||
future<typename result_of<Fn(Args...)>::type> async(launch policy, Fn &&fn, Args &&...args)
|
||||
{
|
||||
using ReturnType = std::invoke_result_t<std::decay_t<Fn>, std::decay_t<Args>...>;
|
||||
|
||||
if (policy == std::launch::async)
|
||||
{
|
||||
auto task = std::make_shared<std::packaged_task<ReturnType()>>(
|
||||
std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...));
|
||||
|
||||
std::future<ReturnType> 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>(fn), std::forward<Args>(args)...);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::invalid_argument("Invalid launch policy");
|
||||
}
|
||||
}
|
||||
|
||||
template <class Fn, class... Args>
|
||||
future<typename result_of<Fn(Args...)>::type> async(Fn &&fn, Args &&...args)
|
||||
{
|
||||
return async(std::launch::async /* | std::launch::deferred*/, std::forward<Fn>(fn), std::forward<Args>(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 R>
|
||||
class promise
|
||||
{
|
||||
public:
|
||||
promise();
|
||||
template <class Allocator>
|
||||
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<R> 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 <class R>
|
||||
void swap(promise<R> &x, promise<R> &y) noexcept;
|
||||
|
||||
template <class R, class Alloc>
|
||||
struct uses_allocator<promise<R>, Alloc>;
|
||||
|
||||
template <class R>
|
||||
class future
|
||||
{
|
||||
public:
|
||||
future() noexcept;
|
||||
future(future &&) noexcept;
|
||||
future(const future &) = delete;
|
||||
~future();
|
||||
future &operator=(const future &) = delete;
|
||||
future &operator=(future &&) noexcept;
|
||||
shared_future<R> share() noexcept;
|
||||
|
||||
R get();
|
||||
// R &get();
|
||||
// void get();
|
||||
|
||||
bool valid() const noexcept;
|
||||
|
||||
void wait() const;
|
||||
template <class Rep, class Period>
|
||||
future_status wait_for(const chrono::duration<Rep, Period> &rel_time) const;
|
||||
template <class Clock, class Duration>
|
||||
future_status wait_until(const chrono::time_point<Clock, Duration> &abs_time) const;
|
||||
};
|
||||
|
||||
template <class R>
|
||||
class shared_future
|
||||
{
|
||||
public:
|
||||
shared_future() noexcept;
|
||||
shared_future(const shared_future &rhs) noexcept;
|
||||
shared_future(future<R> &&) 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 <class Rep, class Period>
|
||||
future_status wait_for(const chrono::duration<Rep, Period> &rel_time) const;
|
||||
template <class Clock, class Duration>
|
||||
future_status wait_until(const chrono::time_point<Clock, Duration> &abs_time) const;
|
||||
};
|
||||
|
||||
template <class>
|
||||
class packaged_task;
|
||||
|
||||
template <class R, class... ArgTypes>
|
||||
class packaged_task<R(ArgTypes...)>
|
||||
{
|
||||
public:
|
||||
packaged_task() noexcept;
|
||||
template <class F>
|
||||
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<R> get_future();
|
||||
|
||||
void operator()(ArgTypes...);
|
||||
void make_ready_at_thread_exit(ArgTypes...);
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
template <class R, class... ArgTypes>
|
||||
packaged_task(R (*)(ArgTypes...)) -> packaged_task<R(ArgTypes...)>;
|
||||
|
||||
// template <class F>
|
||||
// packaged_task(F) -> packaged_task<???>;
|
||||
|
||||
template <class R, class... ArgTypes>
|
||||
void swap(packaged_task<R(ArgTypes...)> &x, packaged_task<R(ArgTypes...)> &y) noexcept;
|
||||
}
|
@ -28,7 +28,7 @@
|
||||
|
||||
namespace std
|
||||
{
|
||||
namespace __memory__detail
|
||||
namespace detail
|
||||
{
|
||||
template <class>
|
||||
constexpr bool is_unbounded_array_v = false;
|
||||
@ -516,14 +516,14 @@ namespace std
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::enable_if_t<__memory__detail::is_unbounded_array_v<T>, std::unique_ptr<T>>
|
||||
std::enable_if_t<detail::is_unbounded_array_v<T>, std::unique_ptr<T>>
|
||||
make_unique(std::size_t n)
|
||||
{
|
||||
return std::unique_ptr<T>(new std::remove_extent_t<T>[n]());
|
||||
}
|
||||
|
||||
template <class T, class... Args>
|
||||
std::enable_if_t<__memory__detail::is_bounded_array_v<T>> make_unique(Args &&...) = delete;
|
||||
std::enable_if_t<detail::is_bounded_array_v<T>> make_unique(Args &&...) = delete;
|
||||
|
||||
template <class T>
|
||||
requires(!std::is_array_v<T>)
|
||||
@ -603,4 +603,162 @@ namespace std
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
template <class T, class Alloc>
|
||||
struct uses_allocator : std::integral_constant<bool, false>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T, class Alloc>
|
||||
constexpr bool uses_allocator_v = uses_allocator<T, Alloc>::value;
|
||||
|
||||
struct allocator_arg_t
|
||||
{
|
||||
explicit allocator_arg_t() = default;
|
||||
};
|
||||
|
||||
constexpr std::allocator_arg_t allocator_arg{};
|
||||
|
||||
template <class T>
|
||||
class auto_ptr;
|
||||
|
||||
template <>
|
||||
class auto_ptr<void>;
|
||||
|
||||
template <class T>
|
||||
class weak_ptr;
|
||||
|
||||
template <class T>
|
||||
class shared_ptr
|
||||
{
|
||||
public:
|
||||
using weak_type = std::weak_ptr<T>;
|
||||
using element_type = std::remove_extent_t<T>;
|
||||
|
||||
constexpr shared_ptr() noexcept;
|
||||
constexpr shared_ptr(std::nullptr_t) noexcept;
|
||||
|
||||
template <class Y>
|
||||
explicit shared_ptr(Y *ptr);
|
||||
|
||||
template <class Y, class Deleter>
|
||||
shared_ptr(Y *ptr, Deleter d);
|
||||
|
||||
template <class Deleter>
|
||||
shared_ptr(std::nullptr_t ptr, Deleter d);
|
||||
|
||||
template <class Y, class Deleter, class Alloc>
|
||||
shared_ptr(Y *ptr, Deleter d, Alloc alloc);
|
||||
|
||||
template <class Deleter, class Alloc>
|
||||
shared_ptr(std::nullptr_t ptr, Deleter d, Alloc alloc);
|
||||
|
||||
template <class Y>
|
||||
shared_ptr(const shared_ptr<Y> &r, element_type *ptr) noexcept;
|
||||
|
||||
template <class Y>
|
||||
shared_ptr(shared_ptr<Y> &&r, element_type *ptr) noexcept;
|
||||
|
||||
shared_ptr(const shared_ptr &r) noexcept;
|
||||
|
||||
template <class Y>
|
||||
shared_ptr(const shared_ptr<Y> &r) noexcept;
|
||||
|
||||
shared_ptr(shared_ptr &&r) noexcept;
|
||||
|
||||
template <class Y>
|
||||
shared_ptr(shared_ptr<Y> &&r) noexcept;
|
||||
|
||||
template <class Y>
|
||||
explicit shared_ptr(const std::weak_ptr<Y> &r);
|
||||
|
||||
template <class Y>
|
||||
shared_ptr(std::auto_ptr<Y> &&r);
|
||||
|
||||
template <class Y, class Deleter>
|
||||
shared_ptr(std::unique_ptr<Y, Deleter> &&r);
|
||||
|
||||
~shared_ptr();
|
||||
|
||||
shared_ptr &operator=(const shared_ptr &r) noexcept;
|
||||
|
||||
template <class Y>
|
||||
shared_ptr &operator=(const shared_ptr<Y> &r) noexcept;
|
||||
|
||||
shared_ptr &operator=(shared_ptr &&r) noexcept;
|
||||
|
||||
template <class Y>
|
||||
shared_ptr &operator=(shared_ptr<Y> &&r) noexcept;
|
||||
|
||||
template <class Y>
|
||||
shared_ptr &operator=(std::auto_ptr<Y> &&r);
|
||||
|
||||
template <class Y, class Deleter>
|
||||
shared_ptr &operator=(std::unique_ptr<Y, Deleter> &&r);
|
||||
|
||||
void reset() noexcept;
|
||||
|
||||
template <class Y>
|
||||
void reset(Y *ptr);
|
||||
|
||||
template <class Y, class Deleter>
|
||||
void reset(Y *ptr, Deleter d);
|
||||
|
||||
template <class Y, class Deleter, class Alloc>
|
||||
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 <class Y>
|
||||
bool owner_before(const shared_ptr<Y> &other) const noexcept;
|
||||
|
||||
template <class Y>
|
||||
bool owner_before(const std::weak_ptr<Y> &other) const noexcept;
|
||||
|
||||
std::size_t owner_hash() const noexcept;
|
||||
|
||||
template <class Y>
|
||||
bool owner_equal(const std::shared_ptr<Y> &other) const noexcept;
|
||||
|
||||
template <class Y>
|
||||
bool owner_equal(const std::weak_ptr<Y> &other) const noexcept;
|
||||
};
|
||||
|
||||
template <class T, class... Args>
|
||||
shared_ptr<T> make_shared(Args &&...args);
|
||||
|
||||
template <class T>
|
||||
shared_ptr<T> make_shared(std::size_t N);
|
||||
|
||||
template <class T>
|
||||
shared_ptr<T> make_shared();
|
||||
|
||||
template <class T>
|
||||
shared_ptr<T> make_shared(std::size_t N, const std::remove_extent_t<T> &u);
|
||||
|
||||
template <class T>
|
||||
shared_ptr<T> make_shared(const std::remove_extent_t<T> &u);
|
||||
|
||||
template <class T>
|
||||
shared_ptr<T> make_shared_for_overwrite();
|
||||
|
||||
template <class T>
|
||||
shared_ptr<T> make_shared_for_overwrite(std::size_t N);
|
||||
|
||||
}
|
||||
|
79
Kernel/include_std/ratio
Normal file
79
Kernel/include_std/ratio
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template <intmax_t Num, intmax_t Denom = 1>
|
||||
class ratio
|
||||
{
|
||||
public:
|
||||
typedef ratio<Num, Denom> type;
|
||||
static constexpr intmax_t num = Num;
|
||||
static constexpr intmax_t denom = Denom;
|
||||
};
|
||||
|
||||
template <class R1, class R2>
|
||||
using ratio_add = ratio<R1::num * R2::denom + R2::num * R1::denom, R1::denom * R2::denom>;
|
||||
template <class R1, class R2>
|
||||
using ratio_subtract = ratio<R1::num * R2::denom - R2::num * R1::denom, R1::denom * R2::denom>;
|
||||
template <class R1, class R2>
|
||||
using ratio_multiply = ratio<R1::num * R2::num, R1::denom * R2::denom>;
|
||||
template <class R1, class R2>
|
||||
using ratio_divide = ratio<R1::num * R2::denom, R1::denom * R2::num>;
|
||||
|
||||
template <class R1, class R2>
|
||||
struct ratio_equal;
|
||||
template <class R1, class R2>
|
||||
struct ratio_not_equal;
|
||||
template <class R1, class R2>
|
||||
struct ratio_less;
|
||||
template <class R1, class R2>
|
||||
struct ratio_less_equal;
|
||||
template <class R1, class R2>
|
||||
struct ratio_greater;
|
||||
template <class R1, class R2>
|
||||
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;
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <convert.h>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <new>
|
||||
|
||||
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;
|
||||
};
|
||||
}
|
||||
|
@ -17,8 +17,92 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <interface/errno.h>
|
||||
|
||||
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 <class T>
|
||||
struct is_error_code_enum : std::integral_constant<bool, false>
|
||||
{
|
||||
};
|
||||
|
||||
template <class T>
|
||||
constexpr bool is_error_code_enum_v = is_error_code_enum<T>::value;
|
||||
}
|
||||
|
@ -290,7 +290,7 @@ namespace std
|
||||
reinterpret_cast<T>(t);
|
||||
f(0);
|
||||
p + t;
|
||||
} > {};
|
||||
}>{};
|
||||
|
||||
template <class T>
|
||||
constexpr bool is_integral_v = is_integral<T>::value;
|
||||
@ -659,4 +659,38 @@ namespace std
|
||||
|
||||
template <class... T>
|
||||
using common_type_t = typename common_type<T...>::type;
|
||||
|
||||
namespace detail
|
||||
{
|
||||
template <class T>
|
||||
constexpr T &&__result_of_forward(std::remove_reference_t<T> &t) noexcept
|
||||
{
|
||||
return static_cast<T &&>(t);
|
||||
}
|
||||
|
||||
template <class F, class... ArgTypes>
|
||||
auto INVOKE(F &&f, ArgTypes &&...args)
|
||||
-> decltype(__result_of_forward<F>(f)(__result_of_forward<ArgTypes>(args)...))
|
||||
{
|
||||
return __result_of_forward<F>(f)(__result_of_forward<ArgTypes>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template <class>
|
||||
class result_of;
|
||||
|
||||
template <class F, class... ArgTypes>
|
||||
struct result_of<F(ArgTypes...)>
|
||||
{
|
||||
using type = decltype(detail::INVOKE(std::declval<F>(), std::declval<ArgTypes>()...));
|
||||
};
|
||||
|
||||
template <class F, class... ArgTypes>
|
||||
struct invoke_result;
|
||||
|
||||
template <class T>
|
||||
using result_of_t = typename result_of<T>::type;
|
||||
|
||||
// template <class F, class... ArgTypes>
|
||||
// using invoke_result_t = typename invoke_result<F, ArgTypes...>::type;
|
||||
}
|
||||
|
23
Kernel/library/std/future.cpp
Normal file
23
Kernel/library/std/future.cpp
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// #include <future>
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
}
|
@ -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)
|
||||
|
136
Kernel/tests/stl/future_test.cpp
Normal file
136
Kernel/tests/stl/future_test.cpp
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// #include <future>
|
||||
// #include <thread>
|
||||
// #include <assert.h>
|
||||
|
||||
void test_stl_future()
|
||||
{
|
||||
// {
|
||||
// std::future<int> 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<int> p;
|
||||
// std::future<int> 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<int> p;
|
||||
// std::future<int> f = p.get_future();
|
||||
// std::shared_future<int> sf = f.share();
|
||||
|
||||
// p.set_value(42);
|
||||
|
||||
// assert(sf.get() == 42);
|
||||
// assert(sf.get() == 42);
|
||||
// }
|
||||
|
||||
// {
|
||||
// std::promise<int> p;
|
||||
// std::future<int> 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<int> p1, p2;
|
||||
// std::future<int> f1 = p1.get_future();
|
||||
// std::future<int> f2 = p2.get_future();
|
||||
|
||||
// p1.set_value(42);
|
||||
// p2.set_value(24);
|
||||
|
||||
// assert(f1.get() == 42);
|
||||
// assert(f2.get() == 24);
|
||||
// }
|
||||
|
||||
// {
|
||||
// std::promise<int> p;
|
||||
// std::future<int> f1 = p.get_future();
|
||||
// std::future<int> f2 = std::move(f1);
|
||||
|
||||
// p.set_value(42);
|
||||
// assert(f2.get() == 42);
|
||||
// }
|
||||
|
||||
// {
|
||||
// std::promise<int> p;
|
||||
// std::shared_future<int> sf = p.get_future().share();
|
||||
|
||||
// std::atomic<int> sum{0};
|
||||
// std::vector<std::thread> 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);
|
||||
// }
|
||||
}
|
@ -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
|
||||
#endif // DEBUG
|
||||
|
Loading…
x
Reference in New Issue
Block a user