Added support for completely disabling noexcept using MIJIN_TEST_NO_NOEXCEPT (for testing).
This commit is contained in:
parent
a43f92fb58
commit
9ba097fc2f
6
SModule
6
SModule
@ -34,6 +34,12 @@ if env.get('MIJIN_ENABLE_OPENSSL'):
|
||||
source/mijin/net/ssl.cpp
|
||||
"""))
|
||||
|
||||
# CURL libs
|
||||
if env.get('MIJIN_ENABLE_CURL'):
|
||||
cppdefines.append('MIJIN_ENABLE_CURL=1')
|
||||
mijin_sources.extend(Split("""
|
||||
source/mijin/net/request.cpp
|
||||
"""))
|
||||
|
||||
lib_mijin = env.UnityStaticLibrary(
|
||||
target = env['LIB_DIR'] + '/mijin',
|
||||
|
@ -10,5 +10,9 @@
|
||||
"openssl":
|
||||
{
|
||||
"condition": "getenv('MIJIN_ENABLE_OPENSSL')"
|
||||
},
|
||||
"curl":
|
||||
{
|
||||
"condition": "getenv('MIJIN_ENABLE_CURL')"
|
||||
}
|
||||
}
|
||||
|
@ -135,7 +135,7 @@ void MultiThreadedTaskLoop::workerThread(std::stop_token stopToken, std::size_t
|
||||
// public functions
|
||||
//
|
||||
|
||||
void SimpleTaskLoop::transferCurrentTask(TaskLoop& otherLoop) noexcept
|
||||
void SimpleTaskLoop::transferCurrentTask(TaskLoop& otherLoop) MIJIN_NOEXCEPT
|
||||
{
|
||||
assertCorrectThread();
|
||||
|
||||
@ -153,7 +153,7 @@ void SimpleTaskLoop::transferCurrentTask(TaskLoop& otherLoop) noexcept
|
||||
otherLoop.addStoredTask(std::move(storedTask));
|
||||
}
|
||||
|
||||
void SimpleTaskLoop::addStoredTask(StoredTask&& storedTask) noexcept
|
||||
void SimpleTaskLoop::addStoredTask(StoredTask&& storedTask) MIJIN_NOEXCEPT
|
||||
{
|
||||
storedTask.task->setLoop(this);
|
||||
if (threadId_ == std::thread::id() || threadId_ == std::this_thread::get_id())
|
||||
@ -174,7 +174,7 @@ void SimpleTaskLoop::addStoredTask(StoredTask&& storedTask) noexcept
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t SimpleTaskLoop::getActiveTasks() const noexcept
|
||||
std::size_t SimpleTaskLoop::getActiveTasks() const MIJIN_NOEXCEPT
|
||||
{
|
||||
std::size_t sum = 0;
|
||||
for (const StoredTask& task : mijin::chain(tasks_, newTasks_))
|
||||
@ -188,7 +188,7 @@ std::size_t SimpleTaskLoop::getActiveTasks() const noexcept
|
||||
return sum;
|
||||
}
|
||||
|
||||
void MultiThreadedTaskLoop::transferCurrentTask(TaskLoop& otherLoop) noexcept
|
||||
void MultiThreadedTaskLoop::transferCurrentTask(TaskLoop& otherLoop) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (&otherLoop == this) {
|
||||
return;
|
||||
@ -204,7 +204,7 @@ void MultiThreadedTaskLoop::transferCurrentTask(TaskLoop& otherLoop) noexcept
|
||||
otherLoop.addStoredTask(std::move(storedTask));
|
||||
}
|
||||
|
||||
void MultiThreadedTaskLoop::addStoredTask(StoredTask&& storedTask) noexcept
|
||||
void MultiThreadedTaskLoop::addStoredTask(StoredTask&& storedTask) MIJIN_NOEXCEPT
|
||||
{
|
||||
storedTask.task->setLoop(this);
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "./future.hpp"
|
||||
#include "./message_queue.hpp"
|
||||
#include "../container/optional.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
#include "../util/flag.hpp"
|
||||
#include "../util/iterators.hpp"
|
||||
#include "../util/traits.hpp"
|
||||
@ -68,28 +69,28 @@ private:
|
||||
std::weak_ptr<struct TaskSharedState> state_;
|
||||
public:
|
||||
TaskHandle() = default;
|
||||
explicit TaskHandle(std::weak_ptr<TaskSharedState> state) noexcept : state_(std::move(state)) {}
|
||||
explicit TaskHandle(std::weak_ptr<TaskSharedState> state) MIJIN_NOEXCEPT : state_(std::move(state)) {}
|
||||
TaskHandle(const TaskHandle&) = default;
|
||||
TaskHandle(TaskHandle&&) = default;
|
||||
|
||||
TaskHandle& operator=(const TaskHandle&) = default;
|
||||
TaskHandle& operator=(TaskHandle&&) = default;
|
||||
|
||||
bool operator==(const TaskHandle& other) const noexcept {
|
||||
bool operator==(const TaskHandle& other) const MIJIN_NOEXCEPT {
|
||||
return !state_.owner_before(other.state_) && !other.state_.owner_before(state_);
|
||||
}
|
||||
bool operator!=(const TaskHandle& other) const noexcept {
|
||||
bool operator!=(const TaskHandle& other) const MIJIN_NOEXCEPT {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool isValid() const noexcept
|
||||
[[nodiscard]] bool isValid() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return !state_.expired();
|
||||
}
|
||||
|
||||
inline void cancel() const noexcept;
|
||||
inline void cancel() const MIJIN_NOEXCEPT;
|
||||
#if MIJIN_COROUTINE_ENABLE_DEBUG_INFO
|
||||
inline Optional<Stacktrace> getCreationStack() const noexcept;
|
||||
inline Optional<Stacktrace> getCreationStack() const MIJIN_NOEXCEPT;
|
||||
#endif
|
||||
};
|
||||
struct TaskSharedState
|
||||
@ -110,11 +111,11 @@ struct TaskState
|
||||
|
||||
TaskState() = default;
|
||||
TaskState(const TaskState&) = default;
|
||||
TaskState(TaskState&&) noexcept = default;
|
||||
inline TaskState(T _value, TaskStatus _status) noexcept : value(std::move(_value)), status(_status) {}
|
||||
inline TaskState(std::exception_ptr _exception) noexcept : exception(std::move(_exception)), status(TaskStatus::FINISHED) {}
|
||||
TaskState(TaskState&&) MIJIN_NOEXCEPT = default;
|
||||
inline TaskState(T _value, TaskStatus _status) MIJIN_NOEXCEPT : value(std::move(_value)), status(_status) {}
|
||||
inline TaskState(std::exception_ptr _exception) MIJIN_NOEXCEPT : exception(std::move(_exception)), status(TaskStatus::FINISHED) {}
|
||||
TaskState& operator=(const TaskState&) = default;
|
||||
TaskState& operator=(TaskState&&) noexcept = default;
|
||||
TaskState& operator=(TaskState&&) MIJIN_NOEXCEPT = default;
|
||||
};
|
||||
|
||||
template<>
|
||||
@ -125,11 +126,11 @@ struct TaskState<void>
|
||||
|
||||
TaskState() = default;
|
||||
TaskState(const TaskState&) = default;
|
||||
TaskState(TaskState&&) noexcept = default;
|
||||
inline TaskState(TaskStatus _status) noexcept : status(_status) {}
|
||||
inline TaskState(std::exception_ptr _exception) noexcept : exception(std::move(_exception)), status(TaskStatus::FINISHED) {}
|
||||
TaskState(TaskState&&) MIJIN_NOEXCEPT = default;
|
||||
inline TaskState(TaskStatus _status) MIJIN_NOEXCEPT : status(_status) {}
|
||||
inline TaskState(std::exception_ptr _exception) MIJIN_NOEXCEPT : exception(std::move(_exception)), status(TaskStatus::FINISHED) {}
|
||||
TaskState& operator=(const TaskState&) = default;
|
||||
TaskState& operator=(TaskState&&) noexcept = default;
|
||||
TaskState& operator=(TaskState&&) MIJIN_NOEXCEPT = default;
|
||||
};
|
||||
|
||||
namespace impl
|
||||
@ -138,15 +139,15 @@ template<typename TReturn, typename TPromise>
|
||||
struct TaskReturn
|
||||
{
|
||||
template<typename... TArgs>
|
||||
constexpr void return_value(TArgs&&... args) noexcept {
|
||||
constexpr void return_value(TArgs&&... args) MIJIN_NOEXCEPT {
|
||||
(static_cast<TPromise&>(*this).state_) = TaskState<TReturn>(TReturn(std::forward<TArgs>(args)...), TaskStatus::FINISHED);
|
||||
}
|
||||
|
||||
constexpr void return_value(TReturn value) noexcept {
|
||||
constexpr void return_value(TReturn value) MIJIN_NOEXCEPT {
|
||||
(static_cast<TPromise&>(*this).state_) = TaskState<TReturn>(TReturn(std::move(value)), TaskStatus::FINISHED);
|
||||
}
|
||||
|
||||
constexpr void unhandled_exception() noexcept {
|
||||
constexpr void unhandled_exception() MIJIN_NOEXCEPT {
|
||||
(static_cast<TPromise&>(*this).state_) = TaskState<TReturn>(std::current_exception());
|
||||
}
|
||||
};
|
||||
@ -154,11 +155,11 @@ struct TaskReturn
|
||||
template<typename TPromise>
|
||||
struct TaskReturn<void, TPromise>
|
||||
{
|
||||
constexpr void return_void() noexcept {
|
||||
constexpr void return_void() MIJIN_NOEXCEPT {
|
||||
static_cast<TPromise&>(*this).state_.status = TaskStatus::FINISHED;
|
||||
}
|
||||
|
||||
constexpr void unhandled_exception() noexcept {
|
||||
constexpr void unhandled_exception() MIJIN_NOEXCEPT {
|
||||
(static_cast<TPromise&>(*this).state_) = TaskState<void>(std::current_exception());
|
||||
}
|
||||
};
|
||||
@ -169,8 +170,8 @@ struct TaskAwaitableFuture
|
||||
{
|
||||
FuturePtr<TValue> future;
|
||||
|
||||
[[nodiscard]] constexpr bool await_ready() const noexcept { return future->ready(); }
|
||||
constexpr void await_suspend(std::coroutine_handle<>) const noexcept {}
|
||||
[[nodiscard]] constexpr bool await_ready() const MIJIN_NOEXCEPT { return future->ready(); }
|
||||
constexpr void await_suspend(std::coroutine_handle<>) const MIJIN_NOEXCEPT {}
|
||||
constexpr TValue await_resume() const
|
||||
{
|
||||
impl::throwIfCancelled();
|
||||
@ -188,8 +189,8 @@ struct TaskAwaitableSignal
|
||||
{
|
||||
std::shared_ptr<std::tuple<TArgs...>> data;
|
||||
|
||||
[[nodiscard]] constexpr bool await_ready() const noexcept { return false; }
|
||||
constexpr void await_suspend(std::coroutine_handle<>) const noexcept {}
|
||||
[[nodiscard]] constexpr bool await_ready() const MIJIN_NOEXCEPT { return false; }
|
||||
constexpr void await_suspend(std::coroutine_handle<>) const MIJIN_NOEXCEPT {}
|
||||
inline auto& await_resume() const
|
||||
{
|
||||
impl::throwIfCancelled();
|
||||
@ -202,8 +203,8 @@ struct TaskAwaitableSignal<TSingleArg>
|
||||
{
|
||||
std::shared_ptr<TSingleArg> data;
|
||||
|
||||
[[nodiscard]] constexpr bool await_ready() const noexcept { return false; }
|
||||
constexpr void await_suspend(std::coroutine_handle<>) const noexcept {}
|
||||
[[nodiscard]] constexpr bool await_ready() const MIJIN_NOEXCEPT { return false; }
|
||||
constexpr void await_suspend(std::coroutine_handle<>) const MIJIN_NOEXCEPT {}
|
||||
constexpr auto& await_resume() const
|
||||
{
|
||||
impl::throwIfCancelled();
|
||||
@ -214,8 +215,8 @@ struct TaskAwaitableSignal<TSingleArg>
|
||||
template<>
|
||||
struct TaskAwaitableSignal<>
|
||||
{
|
||||
[[nodiscard]] constexpr bool await_ready() const noexcept { return false; }
|
||||
constexpr void await_suspend(std::coroutine_handle<>) const noexcept {}
|
||||
[[nodiscard]] constexpr bool await_ready() const MIJIN_NOEXCEPT { return false; }
|
||||
constexpr void await_suspend(std::coroutine_handle<>) const MIJIN_NOEXCEPT {}
|
||||
inline void await_resume() const {
|
||||
impl::throwIfCancelled();
|
||||
}
|
||||
@ -223,8 +224,8 @@ struct TaskAwaitableSignal<>
|
||||
|
||||
struct TaskAwaitableSuspend
|
||||
{
|
||||
[[nodiscard]] constexpr bool await_ready() const noexcept { return false; }
|
||||
constexpr void await_suspend(std::coroutine_handle<>) const noexcept {}
|
||||
[[nodiscard]] constexpr bool await_ready() const MIJIN_NOEXCEPT { return false; }
|
||||
constexpr void await_suspend(std::coroutine_handle<>) const MIJIN_NOEXCEPT {}
|
||||
inline void await_resume() const {
|
||||
impl::throwIfCancelled();
|
||||
}
|
||||
@ -241,22 +242,22 @@ struct TaskPromise : impl::TaskReturn<typename TTraits::result_t, TaskPromise<TT
|
||||
std::shared_ptr<TaskSharedState> sharedState_ = std::make_shared<TaskSharedState>();
|
||||
TaskLoop* loop_ = nullptr;
|
||||
|
||||
constexpr task_t get_return_object() noexcept { return task_t(handle_t::from_promise(*this)); }
|
||||
constexpr TaskAwaitableSuspend initial_suspend() noexcept { return {}; }
|
||||
constexpr std::suspend_always final_suspend() noexcept { return {}; }
|
||||
constexpr task_t get_return_object() MIJIN_NOEXCEPT { return task_t(handle_t::from_promise(*this)); }
|
||||
constexpr TaskAwaitableSuspend initial_suspend() MIJIN_NOEXCEPT { return {}; }
|
||||
constexpr std::suspend_always final_suspend() noexcept { return {}; } // note: this must always be noexcept, no matter what
|
||||
|
||||
// template<typename TValue>
|
||||
// constexpr std::suspend_always yield_value(TValue value) noexcept {
|
||||
// constexpr std::suspend_always yield_value(TValue value) MIJIN_NOEXCEPT {
|
||||
// *state_ = TaskState<result_t>(std::move(value), TaskStatus::YIELDED);
|
||||
// return {};
|
||||
// }
|
||||
|
||||
// TODO: implement yielding (can't use futures for this)
|
||||
|
||||
// constexpr void unhandled_exception() noexcept {}
|
||||
// constexpr void unhandled_exception() MIJIN_NOEXCEPT {}
|
||||
|
||||
template<typename TValue>
|
||||
auto await_transform(FuturePtr<TValue> future) noexcept
|
||||
auto await_transform(FuturePtr<TValue> future) MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(loop_ != nullptr, "Cannot await future outside of a loop!");
|
||||
TaskAwaitableFuture<TValue> awaitable{future};
|
||||
@ -272,7 +273,7 @@ struct TaskPromise : impl::TaskReturn<typename TTraits::result_t, TaskPromise<TT
|
||||
}
|
||||
|
||||
template<typename TResultOther>
|
||||
auto await_transform(TaskBase<TResultOther> task) noexcept
|
||||
auto await_transform(TaskBase<TResultOther> task) MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(loop_ != nullptr, "Cannot await another task outside of a loop!"); // NOLINT(clang-analyzer-core.UndefinedBinaryOperatorResult)
|
||||
auto future = delayEvaluation<TResultOther>(loop_)->addTask(std::move(task), &sharedState_->subTask); // hackidyhack: delay evaluation of the type of loop_ as it is only forward-declared here
|
||||
@ -280,7 +281,7 @@ struct TaskPromise : impl::TaskReturn<typename TTraits::result_t, TaskPromise<TT
|
||||
}
|
||||
|
||||
template<typename TFirstArg, typename TSecondArg, typename... TArgs>
|
||||
auto await_transform(Signal<TFirstArg, TSecondArg, TArgs...>& signal) noexcept
|
||||
auto await_transform(Signal<TFirstArg, TSecondArg, TArgs...>& signal) MIJIN_NOEXCEPT
|
||||
{
|
||||
auto data = std::make_shared<std::tuple<TFirstArg, TSecondArg, TArgs...>>();
|
||||
signal.connect([this, data](TFirstArg arg0, TSecondArg arg1, TArgs... args) mutable
|
||||
@ -294,7 +295,7 @@ struct TaskPromise : impl::TaskReturn<typename TTraits::result_t, TaskPromise<TT
|
||||
}
|
||||
|
||||
template<typename TFirstArg>
|
||||
auto await_transform(Signal<TFirstArg>& signal) noexcept
|
||||
auto await_transform(Signal<TFirstArg>& signal) MIJIN_NOEXCEPT
|
||||
{
|
||||
auto data = std::make_shared<TFirstArg>();
|
||||
signal.connect([this, data](TFirstArg arg0) mutable
|
||||
@ -307,7 +308,7 @@ struct TaskPromise : impl::TaskReturn<typename TTraits::result_t, TaskPromise<TT
|
||||
return awaitable;
|
||||
}
|
||||
|
||||
auto await_transform(Signal<>& signal) noexcept
|
||||
auto await_transform(Signal<>& signal) MIJIN_NOEXCEPT
|
||||
{
|
||||
signal.connect([this]()
|
||||
{
|
||||
@ -318,17 +319,17 @@ struct TaskPromise : impl::TaskReturn<typename TTraits::result_t, TaskPromise<TT
|
||||
return awaitable;
|
||||
}
|
||||
|
||||
std::suspend_always await_transform(std::suspend_always) noexcept
|
||||
std::suspend_always await_transform(std::suspend_always) MIJIN_NOEXCEPT
|
||||
{
|
||||
state_.status = TaskStatus::SUSPENDED;
|
||||
return std::suspend_always();
|
||||
}
|
||||
|
||||
std::suspend_never await_transform(std::suspend_never) noexcept {
|
||||
std::suspend_never await_transform(std::suspend_never) MIJIN_NOEXCEPT {
|
||||
return std::suspend_never();
|
||||
}
|
||||
|
||||
TaskAwaitableSuspend await_transform(TaskAwaitableSuspend) noexcept
|
||||
TaskAwaitableSuspend await_transform(TaskAwaitableSuspend) MIJIN_NOEXCEPT
|
||||
{
|
||||
state_.status = TaskStatus::SUSPENDED;
|
||||
return TaskAwaitableSuspend();
|
||||
@ -352,7 +353,7 @@ public:
|
||||
private:
|
||||
handle_t handle_;
|
||||
public:
|
||||
constexpr explicit TaskBase(handle_t handle) noexcept : handle_(handle) {
|
||||
constexpr explicit TaskBase(handle_t handle) MIJIN_NOEXCEPT : handle_(handle) {
|
||||
#if MIJIN_COROUTINE_ENABLE_DEBUG_INFO
|
||||
if (Result<Stacktrace> stacktrace = captureStacktrace(2); stacktrace.isSuccess())
|
||||
{
|
||||
@ -361,12 +362,12 @@ public:
|
||||
#endif
|
||||
}
|
||||
TaskBase(const TaskBase&) = delete;
|
||||
TaskBase(TaskBase&& other) noexcept : handle_(std::exchange(other.handle_, nullptr))
|
||||
TaskBase(TaskBase&& other) MIJIN_NOEXCEPT : handle_(std::exchange(other.handle_, nullptr))
|
||||
{}
|
||||
~TaskBase() noexcept;
|
||||
~TaskBase() MIJIN_NOEXCEPT;
|
||||
public:
|
||||
TaskBase& operator=(const TaskBase&) = delete;
|
||||
TaskBase& operator=(TaskBase&& other) noexcept
|
||||
TaskBase& operator=(TaskBase&& other) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (handle_) {
|
||||
handle_.destroy();
|
||||
@ -376,13 +377,13 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool operator==(const TaskBase& other) const noexcept { return handle_ == other.handle_; }
|
||||
constexpr bool operator==(const TaskBase& other) const MIJIN_NOEXCEPT { return handle_ == other.handle_; }
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool operator!=(const TaskBase& other) const noexcept { return handle_ != other.handle_; }
|
||||
constexpr bool operator!=(const TaskBase& other) const MIJIN_NOEXCEPT { return handle_ != other.handle_; }
|
||||
public:
|
||||
[[nodiscard]]
|
||||
constexpr TaskState<TResult>& state() noexcept
|
||||
constexpr TaskState<TResult>& state() MIJIN_NOEXCEPT
|
||||
{
|
||||
return handle_.promise().state_;
|
||||
}
|
||||
@ -392,19 +393,19 @@ public:
|
||||
handle_.resume();
|
||||
return state();
|
||||
}
|
||||
constexpr std::shared_ptr<TaskSharedState>& sharedState() noexcept
|
||||
constexpr std::shared_ptr<TaskSharedState>& sharedState() MIJIN_NOEXCEPT
|
||||
{
|
||||
return handle_.promise().sharedState_;
|
||||
}
|
||||
private:
|
||||
[[nodiscard]]
|
||||
constexpr handle_t handle() const noexcept { return handle_; }
|
||||
constexpr handle_t handle() const MIJIN_NOEXCEPT { return handle_; }
|
||||
[[nodiscard]]
|
||||
constexpr TaskLoop* getLoop() noexcept
|
||||
constexpr TaskLoop* getLoop() MIJIN_NOEXCEPT
|
||||
{
|
||||
return handle_.promise().loop_;
|
||||
}
|
||||
constexpr void setLoop(TaskLoop* loop) noexcept
|
||||
constexpr void setLoop(TaskLoop* loop) MIJIN_NOEXCEPT
|
||||
{
|
||||
// MIJIN_ASSERT(handle_.promise().loop_ == nullptr
|
||||
// || handle_.promise().loop_ == loop
|
||||
@ -423,14 +424,14 @@ class WrappedTaskBase
|
||||
public:
|
||||
virtual ~WrappedTaskBase() = default;
|
||||
public:
|
||||
virtual TaskStatus status() noexcept = 0;
|
||||
virtual std::exception_ptr exception() noexcept = 0;
|
||||
// virtual std::any result() noexcept = 0;
|
||||
virtual TaskStatus status() MIJIN_NOEXCEPT = 0;
|
||||
virtual std::exception_ptr exception() MIJIN_NOEXCEPT = 0;
|
||||
// virtual std::any result() MIJIN_NOEXCEPT = 0;
|
||||
virtual void resume() = 0;
|
||||
virtual void* raw() noexcept = 0;
|
||||
virtual std::coroutine_handle<> handle() noexcept = 0;
|
||||
virtual void setLoop(TaskLoop* loop) noexcept = 0;
|
||||
virtual std::shared_ptr<TaskSharedState>& sharedState() noexcept = 0;
|
||||
virtual void* raw() MIJIN_NOEXCEPT = 0;
|
||||
virtual std::coroutine_handle<> handle() MIJIN_NOEXCEPT = 0;
|
||||
virtual void setLoop(TaskLoop* loop) MIJIN_NOEXCEPT = 0;
|
||||
virtual std::shared_ptr<TaskSharedState>& sharedState() MIJIN_NOEXCEPT = 0;
|
||||
|
||||
[[nodiscard]] inline bool canResume() {
|
||||
const TaskStatus stat = status();
|
||||
@ -444,16 +445,16 @@ class WrappedTask : public WrappedTaskBase
|
||||
private:
|
||||
TTask task_;
|
||||
public:
|
||||
constexpr explicit WrappedTask(TTask&& task) noexcept : task_(std::move(task)) {}
|
||||
constexpr explicit WrappedTask(TTask&& task) MIJIN_NOEXCEPT : task_(std::move(task)) {}
|
||||
WrappedTask(const WrappedTask&) = delete;
|
||||
WrappedTask(WrappedTask&&) noexcept = default;
|
||||
WrappedTask(WrappedTask&&) MIJIN_NOEXCEPT = default;
|
||||
public:
|
||||
WrappedTask& operator=(const WrappedTask&) = delete;
|
||||
WrappedTask& operator=(WrappedTask&&) noexcept = default;
|
||||
WrappedTask& operator=(WrappedTask&&) MIJIN_NOEXCEPT = default;
|
||||
public:
|
||||
TaskStatus status() noexcept override { return task_.state().status; }
|
||||
std::exception_ptr exception() noexcept override { return task_.state().exception; }
|
||||
// std::any result() noexcept override
|
||||
TaskStatus status() MIJIN_NOEXCEPT override { return task_.state().status; }
|
||||
std::exception_ptr exception() MIJIN_NOEXCEPT override { return task_.state().exception; }
|
||||
// std::any result() MIJIN_NOEXCEPT
|
||||
// {
|
||||
// if constexpr (std::is_same_v<typename TTask::result_t, void>) {
|
||||
// return {};
|
||||
@ -463,14 +464,14 @@ public:
|
||||
// }
|
||||
// }
|
||||
void resume() override { task_.resume(); }
|
||||
void* raw() noexcept override { return &task_; }
|
||||
std::coroutine_handle<> handle() noexcept override { return task_.handle(); }
|
||||
void setLoop(TaskLoop* loop) noexcept override { task_.setLoop(loop); }
|
||||
virtual std::shared_ptr<TaskSharedState>& sharedState() noexcept override { return task_.sharedState(); }
|
||||
void* raw() MIJIN_NOEXCEPT override { return &task_; }
|
||||
std::coroutine_handle<> handle() MIJIN_NOEXCEPT override { return task_.handle(); }
|
||||
void setLoop(TaskLoop* loop) MIJIN_NOEXCEPT override { task_.setLoop(loop); }
|
||||
virtual std::shared_ptr<TaskSharedState>& sharedState() MIJIN_NOEXCEPT override { return task_.sharedState(); }
|
||||
};
|
||||
|
||||
template<typename TTask>
|
||||
std::unique_ptr<WrappedTask<TTask>> wrapTask(TTask&& task) noexcept
|
||||
std::unique_ptr<WrappedTask<TTask>> wrapTask(TTask&& task) MIJIN_NOEXCEPT
|
||||
{
|
||||
return std::make_unique<WrappedTask<TTask>>(std::forward<TTask>(task));
|
||||
}
|
||||
@ -499,29 +500,29 @@ protected:
|
||||
|
||||
exception_handler_t uncaughtExceptionHandler_;
|
||||
public:
|
||||
TaskLoop() = default;
|
||||
TaskLoop() MIJIN_NOEXCEPT = default;
|
||||
TaskLoop(const TaskLoop&) = delete;
|
||||
TaskLoop(TaskLoop&&) = delete;
|
||||
virtual ~TaskLoop() = default;
|
||||
virtual ~TaskLoop() MIJIN_NOEXCEPT = default;
|
||||
|
||||
TaskLoop& operator=(const TaskLoop&) = delete;
|
||||
TaskLoop& operator=(TaskLoop&&) = delete;
|
||||
|
||||
void setUncaughtExceptionHandler(exception_handler_t handler) noexcept { uncaughtExceptionHandler_ = std::move(handler); }
|
||||
void setUncaughtExceptionHandler(exception_handler_t handler) MIJIN_NOEXCEPT { uncaughtExceptionHandler_ = std::move(handler); }
|
||||
|
||||
template<typename TResult>
|
||||
inline FuturePtr<TResult> addTask(TaskBase<TResult> task, TaskHandle* outHandle = nullptr) noexcept;
|
||||
inline FuturePtr<TResult> addTask(TaskBase<TResult> task, TaskHandle* outHandle = nullptr) MIJIN_NOEXCEPT;
|
||||
|
||||
virtual void transferCurrentTask(TaskLoop& otherLoop) noexcept = 0;
|
||||
virtual void addStoredTask(StoredTask&& storedTask) noexcept = 0;
|
||||
virtual void transferCurrentTask(TaskLoop& otherLoop) MIJIN_NOEXCEPT = 0;
|
||||
virtual void addStoredTask(StoredTask&& storedTask) MIJIN_NOEXCEPT = 0;
|
||||
|
||||
[[nodiscard]] static TaskLoop& current() noexcept;
|
||||
[[nodiscard]] static TaskLoop& current() MIJIN_NOEXCEPT;
|
||||
protected:
|
||||
inline TaskStatus tickTask(StoredTask& task);
|
||||
protected:
|
||||
static inline TaskLoop*& currentLoopStorage() noexcept;
|
||||
static inline TaskLoop*& currentLoopStorage() MIJIN_NOEXCEPT;
|
||||
template<typename TResult>
|
||||
static inline void setFutureHelper(StoredTask& storedTask) noexcept;
|
||||
static inline void setFutureHelper(StoredTask& storedTask) MIJIN_NOEXCEPT;
|
||||
};
|
||||
|
||||
template<typename TResult = void>
|
||||
@ -537,17 +538,17 @@ private:
|
||||
std::thread::id threadId_;
|
||||
|
||||
public: // TaskLoop implementation
|
||||
void transferCurrentTask(TaskLoop& otherLoop) noexcept override;
|
||||
void addStoredTask(StoredTask&& storedTask) noexcept override;
|
||||
void transferCurrentTask(TaskLoop& otherLoop) MIJIN_NOEXCEPT override;
|
||||
void addStoredTask(StoredTask&& storedTask) MIJIN_NOEXCEPT override;
|
||||
|
||||
public: // public interface
|
||||
[[nodiscard]] constexpr bool empty() const noexcept { return tasks_.empty() && newTasks_.empty(); }
|
||||
[[nodiscard]] constexpr std::size_t getNumTasks() const noexcept { return tasks_.size() + newTasks_.size(); }
|
||||
[[nodiscard]] std::size_t getActiveTasks() const noexcept;
|
||||
[[nodiscard]] constexpr bool empty() const MIJIN_NOEXCEPT { return tasks_.empty() && newTasks_.empty(); }
|
||||
[[nodiscard]] constexpr std::size_t getNumTasks() const MIJIN_NOEXCEPT { return tasks_.size() + newTasks_.size(); }
|
||||
[[nodiscard]] std::size_t getActiveTasks() const MIJIN_NOEXCEPT;
|
||||
inline CanContinue tick();
|
||||
inline void runUntilDone(IgnoreWaiting ignoreWaiting = IgnoreWaiting::NO);
|
||||
inline void cancelAllTasks() noexcept;
|
||||
[[nodiscard]] inline std::vector<TaskHandle> getAllTasks() const noexcept;
|
||||
inline void cancelAllTasks() MIJIN_NOEXCEPT;
|
||||
[[nodiscard]] inline std::vector<TaskHandle> getAllTasks() const MIJIN_NOEXCEPT;
|
||||
private:
|
||||
inline void assertCorrectThread() { MIJIN_ASSERT(threadId_ == std::thread::id() || threadId_ == std::this_thread::get_id(), "Unsafe to TaskLoop from different thread!"); }
|
||||
};
|
||||
@ -563,8 +564,8 @@ private:
|
||||
std::vector<std::jthread> workerThreads_;
|
||||
|
||||
public: // TaskLoop implementation
|
||||
void transferCurrentTask(TaskLoop& otherLoop) noexcept override;
|
||||
void addStoredTask(StoredTask&& storedTask) noexcept override;
|
||||
void transferCurrentTask(TaskLoop& otherLoop) MIJIN_NOEXCEPT override;
|
||||
void addStoredTask(StoredTask&& storedTask) MIJIN_NOEXCEPT override;
|
||||
|
||||
public: // public interface
|
||||
void start(std::size_t numWorkerThreads);
|
||||
@ -591,7 +592,7 @@ inline void throwIfCancelled()
|
||||
}
|
||||
}
|
||||
|
||||
void TaskHandle::cancel() const noexcept
|
||||
void TaskHandle::cancel() const MIJIN_NOEXCEPT
|
||||
{
|
||||
if (std::shared_ptr<TaskSharedState> state = state_.lock())
|
||||
{
|
||||
@ -601,7 +602,7 @@ void TaskHandle::cancel() const noexcept
|
||||
}
|
||||
|
||||
#if MIJIN_COROUTINE_ENABLE_DEBUG_INFO
|
||||
Optional<Stacktrace> TaskHandle::getCreationStack() const noexcept
|
||||
Optional<Stacktrace> TaskHandle::getCreationStack() const MIJIN_NOEXCEPT
|
||||
{
|
||||
if (std::shared_ptr<TaskSharedState> state = state_.lock())
|
||||
{
|
||||
@ -612,7 +613,7 @@ Optional<Stacktrace> TaskHandle::getCreationStack() const noexcept
|
||||
#endif // MIJIN_COROUTINE_ENABLE_DEBUG_INFO
|
||||
|
||||
template<typename TResult>
|
||||
TaskBase<TResult>::~TaskBase() noexcept
|
||||
TaskBase<TResult>::~TaskBase() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (handle_)
|
||||
{
|
||||
@ -621,7 +622,7 @@ TaskBase<TResult>::~TaskBase() noexcept
|
||||
}
|
||||
|
||||
template<typename TResult>
|
||||
inline FuturePtr<TResult> TaskLoop::addTask(TaskBase<TResult> task, TaskHandle* outHandle) noexcept
|
||||
inline FuturePtr<TResult> TaskLoop::addTask(TaskBase<TResult> task, TaskHandle* outHandle) MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(!task.getLoop(), "Attempting to add task that already has a loop!");
|
||||
task.setLoop(this);
|
||||
@ -685,20 +686,20 @@ inline TaskStatus TaskLoop::tickTask(StoredTask& task)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* static */ inline auto TaskLoop::current() noexcept -> TaskLoop&
|
||||
/* static */ inline auto TaskLoop::current() MIJIN_NOEXCEPT -> TaskLoop&
|
||||
{
|
||||
MIJIN_ASSERT(currentLoopStorage() != nullptr, "Attempting to fetch current loop while no coroutine is running!");
|
||||
return *currentLoopStorage();
|
||||
}
|
||||
|
||||
/* static */ auto TaskLoop::currentLoopStorage() noexcept -> TaskLoop*&
|
||||
/* static */ auto TaskLoop::currentLoopStorage() MIJIN_NOEXCEPT -> TaskLoop*&
|
||||
{
|
||||
static thread_local TaskLoop* storage = nullptr;
|
||||
return storage;
|
||||
}
|
||||
|
||||
template<typename TResult>
|
||||
/* static */ inline void TaskLoop::setFutureHelper(StoredTask& storedTask) noexcept
|
||||
/* static */ inline void TaskLoop::setFutureHelper(StoredTask& storedTask) MIJIN_NOEXCEPT
|
||||
{
|
||||
TaskBase<TResult>& task = *static_cast<TaskBase<TResult>*>(storedTask.task->raw());
|
||||
auto future = std::any_cast<FuturePtr<TResult>>(storedTask.resultData);
|
||||
@ -801,7 +802,7 @@ inline void SimpleTaskLoop::runUntilDone(IgnoreWaiting ignoreWaiting)
|
||||
}
|
||||
}
|
||||
|
||||
inline void SimpleTaskLoop::cancelAllTasks() noexcept
|
||||
inline void SimpleTaskLoop::cancelAllTasks() MIJIN_NOEXCEPT
|
||||
{
|
||||
for (StoredTask& task : mijin::chain(tasks_, newTasks_))
|
||||
{
|
||||
@ -814,7 +815,7 @@ inline void SimpleTaskLoop::cancelAllTasks() noexcept
|
||||
}
|
||||
}
|
||||
|
||||
inline std::vector<TaskHandle> SimpleTaskLoop::getAllTasks() const noexcept
|
||||
inline std::vector<TaskHandle> SimpleTaskLoop::getAllTasks() const MIJIN_NOEXCEPT
|
||||
{
|
||||
std::vector<TaskHandle> result;
|
||||
for (const StoredTask& task : mijin::chain(tasks_, newTasks_))
|
||||
@ -848,7 +849,7 @@ Task<> c_allDone(const TCollection<FuturePtr<TType>, TTemplateArgs...>& futures)
|
||||
} while (!allDone);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline TaskHandle getCurrentTask() noexcept
|
||||
[[nodiscard]] inline TaskHandle getCurrentTask() MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(impl::gCurrentTask != nullptr, "Attempt to call getCurrentTask() outside of task.");
|
||||
return TaskHandle(impl::gCurrentTask->task->sharedState());
|
||||
|
@ -8,8 +8,9 @@
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include "./signal.hpp"
|
||||
#include "../debug/assert.hpp"
|
||||
#include "../container/optional.hpp"
|
||||
#include "../debug/assert.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
@ -36,8 +37,8 @@ struct FutureStorage
|
||||
{
|
||||
Optional<TValue> value;
|
||||
|
||||
void setValue(TValue value_) noexcept { value = std::move(value_); }
|
||||
[[nodiscard]] TValue& getValue() noexcept { return value.get(); }
|
||||
void setValue(TValue value_) MIJIN_NOEXCEPT { value = std::move(value_); }
|
||||
[[nodiscard]] TValue& getValue() MIJIN_NOEXCEPT { return value.get(); }
|
||||
|
||||
};
|
||||
|
||||
@ -46,8 +47,8 @@ struct FutureStorage
|
||||
// {
|
||||
// Optional<TValue*> value;
|
||||
//
|
||||
// void setValue(TValue& value_) noexcept { value = &value_; }
|
||||
// [[nodiscard]] TValue& getValue() const noexcept { return *value.get(); }
|
||||
// void setValue(TValue& value_) MIJIN_NOEXCEPT { value = &value_; }
|
||||
// [[nodiscard]] TValue& getValue() const MIJIN_NOEXCEPT { return *value.get(); }
|
||||
// };
|
||||
|
||||
template<>
|
||||
@ -65,19 +66,19 @@ private:
|
||||
public:
|
||||
Future() = default;
|
||||
Future(const Future&) = delete;
|
||||
Future(Future&&) noexcept = default;
|
||||
Future(Future&&) MIJIN_NOEXCEPT = default;
|
||||
public:
|
||||
Future& operator=(const Future&) = delete;
|
||||
Future& operator=(Future&&) noexcept = default;
|
||||
Future& operator=(Future&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr explicit operator bool() const noexcept { return ready(); }
|
||||
constexpr explicit operator bool() const MIJIN_NOEXCEPT { return ready(); }
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool operator!() const noexcept { return !ready(); }
|
||||
constexpr bool operator!() const MIJIN_NOEXCEPT { return !ready(); }
|
||||
public: // access
|
||||
[[nodiscard]]
|
||||
constexpr decltype(auto) get() noexcept
|
||||
constexpr decltype(auto) get() MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(isSet_, "Attempting to get from future that is not ready.");
|
||||
if constexpr(std::is_same_v<TValue, void>) {
|
||||
@ -88,7 +89,7 @@ public: // access
|
||||
}
|
||||
}
|
||||
[[nodiscard]]
|
||||
constexpr decltype(auto) get() const noexcept
|
||||
constexpr decltype(auto) get() const MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(isSet_, "Attempting to get from future that is not ready.");
|
||||
if constexpr(std::is_same_v<TValue, void>) {
|
||||
@ -99,20 +100,20 @@ public: // access
|
||||
}
|
||||
}
|
||||
[[nodiscard]]
|
||||
constexpr bool ready() const noexcept
|
||||
constexpr bool ready() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return isSet_;
|
||||
}
|
||||
public: // modification
|
||||
template<typename TArg> requires (!std::is_same_v<TValue, void>)
|
||||
constexpr void set(TArg&& value) noexcept
|
||||
constexpr void set(TArg&& value) MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(!isSet_, "Trying to set a future twice!");
|
||||
value_.setValue(std::move(value));
|
||||
isSet_ = true;
|
||||
sigSet.emit();
|
||||
}
|
||||
constexpr void set() noexcept
|
||||
constexpr void set() MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(!isSet_, "Trying to set a future twice!");
|
||||
isSet_ = true;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <atomic>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
#include "../internal/common.hpp"
|
||||
#include "../util/bitarray.hpp"
|
||||
|
||||
namespace mijin
|
||||
@ -37,7 +38,7 @@ private:
|
||||
std::optional<value_type> message_;
|
||||
public:
|
||||
MessageQueueIterator() = default;
|
||||
explicit MessageQueueIterator(TMessageQueue& queue) noexcept : queue_(&queue) {
|
||||
explicit MessageQueueIterator(TMessageQueue& queue) MIJIN_NOEXCEPT : queue_(&queue) {
|
||||
message_ = queue_->tryPop();
|
||||
}
|
||||
MessageQueueIterator(const MessageQueueIterator&) = delete;
|
||||
@ -46,26 +47,26 @@ public:
|
||||
MessageQueueIterator& operator=(const MessageQueueIterator&) = delete;
|
||||
MessageQueueIterator& operator=(MessageQueueIterator&&) = default;
|
||||
|
||||
bool operator==(const MessageQueueIterator& other) noexcept
|
||||
bool operator==(const MessageQueueIterator& other) MIJIN_NOEXCEPT
|
||||
{
|
||||
return message_.has_value() == other.message_.has_value();
|
||||
}
|
||||
bool operator!=(const MessageQueueIterator& other) noexcept
|
||||
bool operator!=(const MessageQueueIterator& other) MIJIN_NOEXCEPT
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
reference operator*() noexcept
|
||||
reference operator*() MIJIN_NOEXCEPT
|
||||
{
|
||||
return message_.value();
|
||||
}
|
||||
|
||||
pointer operator->() noexcept
|
||||
pointer operator->() MIJIN_NOEXCEPT
|
||||
{
|
||||
return &message_.value();
|
||||
}
|
||||
|
||||
MessageQueueIterator& operator++() noexcept
|
||||
MessageQueueIterator& operator++() MIJIN_NOEXCEPT
|
||||
{
|
||||
message_ = queue_->tryPop();
|
||||
return *this;
|
||||
@ -86,10 +87,10 @@ private:
|
||||
public:
|
||||
MessageQueue() = default;
|
||||
MessageQueue(const MessageQueue&) = delete;
|
||||
MessageQueue(MessageQueue&&) noexcept = delete;
|
||||
MessageQueue(MessageQueue&&) = delete;
|
||||
|
||||
MessageQueue& operator=(const MessageQueue&) = delete;
|
||||
MessageQueue& operator=(MessageQueue&&) noexcept = delete;
|
||||
MessageQueue& operator=(MessageQueue&&) = delete;
|
||||
|
||||
[[nodiscard]] bool tryPushMaybeMove(TMessage& message);
|
||||
[[nodiscard]] bool tryPush(TMessage message) {
|
||||
@ -99,8 +100,8 @@ public:
|
||||
[[nodiscard]] std::optional<TMessage> tryPop();
|
||||
[[nodiscard]] TMessage wait();
|
||||
|
||||
iterator_t begin() noexcept { return iterator_t(*this); }
|
||||
iterator_t end() noexcept { return iterator_t(); }
|
||||
iterator_t begin() MIJIN_NOEXCEPT { return iterator_t(*this); }
|
||||
iterator_t end() MIJIN_NOEXCEPT { return iterator_t(); }
|
||||
};
|
||||
|
||||
template<typename TRequest, typename TResponse, std::size_t requestBufferSize = 32, std::size_t responseBufferSize = 32>
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include "../internal/common.hpp"
|
||||
#include "../util/flag.hpp"
|
||||
|
||||
namespace mijin
|
||||
@ -54,17 +55,17 @@ private:
|
||||
public:
|
||||
Signal() = default;
|
||||
Signal(const Signal&) = delete;
|
||||
Signal(Signal&&) noexcept = default;
|
||||
Signal(Signal&&) MIJIN_NOEXCEPT = default;
|
||||
public:
|
||||
Signal& operator=(const Signal&) = delete;
|
||||
Signal& operator=(Signal&&) noexcept = default;
|
||||
Signal& operator=(Signal&&) MIJIN_NOEXCEPT = default;
|
||||
public:
|
||||
template<typename THandler, typename TWeak = void>
|
||||
inline token_t connect(THandler handler, Oneshot oneshot = Oneshot::NO, std::weak_ptr<TWeak> referenced = std::weak_ptr<TWeak>()) noexcept;
|
||||
inline token_t connect(THandler handler, Oneshot oneshot = Oneshot::NO, std::weak_ptr<TWeak> referenced = std::weak_ptr<TWeak>()) MIJIN_NOEXCEPT;
|
||||
template<typename TObject, typename TWeak = void>
|
||||
inline token_t connect(TObject& object, void (TObject::* handler)(TArgs...), Oneshot oneshot = Oneshot::NO, std::weak_ptr<TWeak> referenced = std::weak_ptr<TWeak>()) noexcept;
|
||||
inline void disconnect(token_t token) noexcept;
|
||||
inline void emit(TArgs&&... args) noexcept;
|
||||
inline token_t connect(TObject& object, void (TObject::* handler)(TArgs...), Oneshot oneshot = Oneshot::NO, std::weak_ptr<TWeak> referenced = std::weak_ptr<TWeak>()) MIJIN_NOEXCEPT;
|
||||
inline void disconnect(token_t token) MIJIN_NOEXCEPT;
|
||||
inline void emit(TArgs&&... args) MIJIN_NOEXCEPT;
|
||||
};
|
||||
|
||||
//
|
||||
@ -73,7 +74,7 @@ public:
|
||||
|
||||
template<typename... TArgs>
|
||||
template<typename THandler, typename TWeak>
|
||||
inline auto Signal<TArgs...>::connect(THandler handler, Oneshot oneshot, std::weak_ptr<TWeak> referenced) noexcept -> token_t
|
||||
inline auto Signal<TArgs...>::connect(THandler handler, Oneshot oneshot, std::weak_ptr<TWeak> referenced) MIJIN_NOEXCEPT -> token_t
|
||||
{
|
||||
std::lock_guard lock(handlersMutex_);
|
||||
|
||||
@ -90,7 +91,7 @@ inline auto Signal<TArgs...>::connect(THandler handler, Oneshot oneshot, std::we
|
||||
|
||||
template<typename... TArgs>
|
||||
template<typename TObject, typename TWeak>
|
||||
inline auto Signal<TArgs...>::connect(TObject& object, void (TObject::* handler)(TArgs...), Oneshot oneshot, std::weak_ptr<TWeak> referenced) noexcept -> token_t
|
||||
inline auto Signal<TArgs...>::connect(TObject& object, void (TObject::* handler)(TArgs...), Oneshot oneshot, std::weak_ptr<TWeak> referenced) MIJIN_NOEXCEPT -> token_t
|
||||
{
|
||||
std::lock_guard lock(handlersMutex_);
|
||||
|
||||
@ -109,7 +110,7 @@ inline auto Signal<TArgs...>::connect(TObject& object, void (TObject::* handler)
|
||||
}
|
||||
|
||||
template<typename... TArgs>
|
||||
inline void Signal<TArgs...>::disconnect(token_t token) noexcept
|
||||
inline void Signal<TArgs...>::disconnect(token_t token) MIJIN_NOEXCEPT
|
||||
{
|
||||
std::lock_guard lock(handlersMutex_);
|
||||
|
||||
@ -121,7 +122,7 @@ inline void Signal<TArgs...>::disconnect(token_t token) noexcept
|
||||
}
|
||||
|
||||
template<typename... TArgs>
|
||||
inline void Signal<TArgs...>::emit(TArgs&&... args) noexcept
|
||||
inline void Signal<TArgs...>::emit(TArgs&&... args) MIJIN_NOEXCEPT
|
||||
{
|
||||
std::lock_guard lock(handlersMutex_);
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#define MIJIN_ASYNC_TASK_MUTEX_HPP_INCLUDED 1
|
||||
|
||||
#include "./coroutine.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
@ -14,13 +15,13 @@ private:
|
||||
class TaskMutex* mutex_;
|
||||
|
||||
public:
|
||||
explicit TaskMutexLock(class TaskMutex* mutex) noexcept : mutex_(mutex) {}
|
||||
explicit TaskMutexLock(class TaskMutex* mutex) MIJIN_NOEXCEPT : mutex_(mutex) {}
|
||||
TaskMutexLock(const TaskMutexLock&) = delete;
|
||||
TaskMutexLock(TaskMutexLock&& other) noexcept : mutex_(std::exchange(other.mutex_, nullptr)) {}
|
||||
TaskMutexLock(TaskMutexLock&& other) MIJIN_NOEXCEPT : mutex_(std::exchange(other.mutex_, nullptr)) {}
|
||||
|
||||
TaskMutexLock& operator=(const TaskMutexLock&) = delete;
|
||||
inline TaskMutexLock& operator=(TaskMutexLock&& other) noexcept;
|
||||
inline ~TaskMutexLock() noexcept;
|
||||
inline TaskMutexLock& operator=(TaskMutexLock&& other) MIJIN_NOEXCEPT;
|
||||
inline ~TaskMutexLock() MIJIN_NOEXCEPT;
|
||||
};
|
||||
|
||||
class TaskMutex
|
||||
@ -37,12 +38,12 @@ public:
|
||||
locked_ = true;
|
||||
co_return TaskMutexLock(this);
|
||||
}
|
||||
[[nodiscard]] inline bool isLocked() const noexcept { return locked_; }
|
||||
[[nodiscard]] inline bool isLocked() const MIJIN_NOEXCEPT { return locked_; }
|
||||
|
||||
friend class TaskMutexLock;
|
||||
};
|
||||
|
||||
TaskMutexLock::~TaskMutexLock() noexcept
|
||||
TaskMutexLock::~TaskMutexLock() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (mutex_)
|
||||
{
|
||||
@ -50,7 +51,7 @@ TaskMutexLock::~TaskMutexLock() noexcept
|
||||
}
|
||||
}
|
||||
|
||||
TaskMutexLock& TaskMutexLock::operator=(TaskMutexLock&& other) noexcept
|
||||
TaskMutexLock& TaskMutexLock::operator=(TaskMutexLock&& other) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (mutex_)
|
||||
{
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <cstdlib>
|
||||
#include <source_location>
|
||||
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma comment(lib, "kernel32")
|
||||
extern "C" __declspec(dllimport) void __stdcall DebugBreak();
|
||||
@ -139,7 +141,7 @@ constexpr AssertionResult handleAssert(const char* /* condition */,
|
||||
#ifdef MIJIN_USE_CUSTOM_ERROR_HANDLER
|
||||
ErrorHandling handleError(const char* message, const std::source_location& location);
|
||||
#else
|
||||
inline ErrorHandling handleError(const char* message, const std::source_location& location) noexcept
|
||||
inline ErrorHandling handleError(const char* message, const std::source_location& location) MIJIN_NOEXCEPT
|
||||
{
|
||||
std::puts(message);
|
||||
std::printf("Function: %s\n", location.function_name());
|
||||
|
@ -75,7 +75,7 @@ thread_local backtrace_state* gBacktraceState = nullptr;
|
||||
// public functions
|
||||
//
|
||||
|
||||
Result<Stacktrace> captureStacktrace(unsigned skipFrames) noexcept
|
||||
Result<Stacktrace> captureStacktrace(unsigned skipFrames) MIJIN_NOEXCEPT
|
||||
{
|
||||
#if MIJIN_USE_LIBBACKTRACE
|
||||
BacktraceData btData;
|
||||
@ -104,7 +104,7 @@ Result<Stacktrace> captureStacktrace(unsigned skipFrames) noexcept
|
||||
#endif // MIJIN_USE_LIBBACKTRACE
|
||||
}
|
||||
|
||||
const Optional<Stacktrace>& getExceptionStacktrace() noexcept
|
||||
const Optional<Stacktrace>& getExceptionStacktrace() MIJIN_NOEXCEPT
|
||||
{
|
||||
return gCurrentExceptionStackTrace;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
# include <fmt/format.h>
|
||||
#endif
|
||||
#include "./symbol_info.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
#include "../types/result.hpp"
|
||||
#include "../util/iterators.hpp"
|
||||
|
||||
@ -45,20 +46,20 @@ public:
|
||||
Stacktrace() = default;
|
||||
Stacktrace(const Stacktrace&) = default;
|
||||
Stacktrace(Stacktrace&&) = default;
|
||||
explicit Stacktrace(std::vector<Stackframe> frames) noexcept : frames_(std::move(frames)) {}
|
||||
explicit Stacktrace(std::vector<Stackframe> frames) MIJIN_NOEXCEPT : frames_(std::move(frames)) {}
|
||||
|
||||
Stacktrace& operator=(const Stacktrace&) = default;
|
||||
Stacktrace& operator=(Stacktrace&&) = default;
|
||||
|
||||
[[nodiscard]] const std::vector<Stackframe>& getFrames() const noexcept { return frames_; }
|
||||
[[nodiscard]] const std::vector<Stackframe>& getFrames() const MIJIN_NOEXCEPT { return frames_; }
|
||||
};
|
||||
|
||||
//
|
||||
// public functions
|
||||
//
|
||||
|
||||
[[nodiscard]] Result<Stacktrace> captureStacktrace(unsigned skipFrames = 0) noexcept;
|
||||
[[nodiscard]] const Optional<Stacktrace>& getExceptionStacktrace() noexcept;
|
||||
[[nodiscard]] Result<Stacktrace> captureStacktrace(unsigned skipFrames = 0) MIJIN_NOEXCEPT;
|
||||
[[nodiscard]] const Optional<Stacktrace>& getExceptionStacktrace() MIJIN_NOEXCEPT;
|
||||
|
||||
template<typename TStream>
|
||||
TStream& operator<<(TStream& stream, const Stackframe& stackframe)
|
||||
|
4
source/mijin/internal/common.hpp
Normal file
4
source/mijin/internal/common.hpp
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "./exception.hpp"
|
31
source/mijin/internal/exception.hpp
Normal file
31
source/mijin/internal/exception.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(MIJIN_INTERNAL_EXCEPTION_HPP_INCLUDED)
|
||||
#define MIJIN_INTERNAL_EXCEPTION_HPP_INCLUDED 1
|
||||
|
||||
#if !defined(MIJIN_WITH_EXCEPTIONS)
|
||||
#define MIJIN_WITH_EXCEPTIONS 0
|
||||
#endif
|
||||
|
||||
#if MIJIN_WITH_EXCEPTIONS
|
||||
#error "Maybe someday"
|
||||
#else
|
||||
#if defined(MIJIN_TEST_NO_NOEXCEPT) // only use for testing
|
||||
#define MIJIN_NOEXCEPT
|
||||
#define MIJIN_THROWS
|
||||
#define MIJIN_CONDITIONAL_NOEXCEPT(...)
|
||||
#else
|
||||
#define MIJIN_NOEXCEPT noexcept
|
||||
#define MIJIN_THROWS noexcept
|
||||
#define MIJIN_CONDITIONAL_NOEXCEPT(...) noexcept(__VA_ARGS__)
|
||||
#endif
|
||||
#define MIJIN_EXCEPT_CHOOSE(noexceptType, exceptType) noexceptType
|
||||
#define MIJIN_THROW_OR_RETURN(value, exception) return (value)
|
||||
#define MIJIN_RETURN_SUCCESS(value) return (value)
|
||||
#endif
|
||||
|
||||
#define MIJIN_ERROR_BOOL MIJIN_EXCEPT_CHOOSE([[nodiscard]] bool, void)
|
||||
#define MIJIN_THROW_OR_RETURN_STD(value, message) MIJIN_THROW_OR_RETURN(value, std::runtime_error(message))
|
||||
|
||||
#endif // !defined(MIJIN_INTERNAL_EXCEPTION_HPP_INCLUDED)
|
@ -140,7 +140,7 @@ StreamFeatures ProcessStream::getFeatures()
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string shellEscape(const std::string& arg) noexcept
|
||||
std::string shellEscape(const std::string& arg) MIJIN_NOEXCEPT
|
||||
{
|
||||
std::ostringstream oss;
|
||||
const bool requiresQuotes = std::any_of(arg.begin(), arg.end(), [&](const char chr) { return std::isspace(chr); });
|
||||
@ -168,7 +168,7 @@ std::string shellEscape(const std::string& arg) noexcept
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string makeShellCommand(const std::vector<std::string>& args) noexcept
|
||||
std::string makeShellCommand(const std::vector<std::string>& args) MIJIN_NOEXCEPT
|
||||
{
|
||||
using namespace mijin::pipe;
|
||||
return args
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include "./stream.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
@ -35,8 +36,8 @@ public:
|
||||
StreamFeatures getFeatures() override;
|
||||
};
|
||||
|
||||
[[nodiscard]] std::string shellEscape(const std::string& arg) noexcept;
|
||||
[[nodiscard]] std::string makeShellCommand(const std::vector<std::string>& args) noexcept;
|
||||
[[nodiscard]] std::string shellEscape(const std::string& arg) MIJIN_NOEXCEPT;
|
||||
[[nodiscard]] std::string makeShellCommand(const std::vector<std::string>& args) MIJIN_NOEXCEPT;
|
||||
|
||||
StreamError ProcessStream::open(const std::vector<std::string>& args, FileOpenMode mode_)
|
||||
{
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <string>
|
||||
#include "../async/coroutine.hpp"
|
||||
#include "../container/typeless_buffer.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
#include "../types/result.hpp"
|
||||
#include "../util/exception.hpp"
|
||||
|
||||
@ -421,7 +422,7 @@ mijin::Task<StreamError> Stream::c_readAsString(std::basic_string<TChar>& outStr
|
||||
}
|
||||
|
||||
|
||||
inline const char* errorName(StreamError error) noexcept
|
||||
inline const char* errorName(StreamError error) MIJIN_NOEXCEPT
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../detect.hpp"
|
||||
#include "../../internal/common.hpp"
|
||||
|
||||
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
||||
#include <fcntl.h>
|
||||
@ -18,9 +19,9 @@
|
||||
namespace mijin::detail
|
||||
{
|
||||
#if MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
|
||||
bool initWSA() noexcept;
|
||||
StreamError translateWSAError() noexcept;
|
||||
StreamError translateWinError(DWORD error) noexcept;
|
||||
StreamError translateWinError() noexcept;
|
||||
bool initWSA() MIJIN_NOEXCEPT;
|
||||
StreamError translateWSAError() MIJIN_NOEXCEPT;
|
||||
StreamError translateWinError(DWORD error) MIJIN_NOEXCEPT;
|
||||
StreamError translateWinError() MIJIN_NOEXCEPT;
|
||||
#endif // MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
|
||||
}// namespace mijin::detail
|
||||
|
@ -35,7 +35,7 @@ namespace mijin
|
||||
namespace
|
||||
{
|
||||
inline constexpr std::size_t CONTENT_LENGTH_LIMIT = 100 << 20; // 100MiB
|
||||
bool parseHTTPVersion(std::string_view version, HTTPVersion& outVersion) noexcept
|
||||
bool parseHTTPVersion(std::string_view version, HTTPVersion& outVersion) MIJIN_NOEXCEPT
|
||||
{
|
||||
std::vector<std::string_view> parts = split(version, ".");
|
||||
if (parts.size() != 2)
|
||||
@ -46,7 +46,7 @@ bool parseHTTPVersion(std::string_view version, HTTPVersion& outVersion) noexcep
|
||||
}
|
||||
}
|
||||
|
||||
Task<StreamResult<HTTPResponse>> HTTPStream::c_request(HTTPRequest request) noexcept
|
||||
Task<StreamResult<HTTPResponse>> HTTPStream::c_request(HTTPRequest request) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (const StreamError error = co_await c_writeRequest(request); error != StreamError::SUCCESS)
|
||||
{
|
||||
@ -55,7 +55,7 @@ Task<StreamResult<HTTPResponse>> HTTPStream::c_request(HTTPRequest request) noex
|
||||
co_return co_await c_readResponse();
|
||||
}
|
||||
|
||||
Task<StreamError> HTTPStream::c_writeRequest(const mijin::HTTPRequest& request) noexcept
|
||||
Task<StreamError> HTTPStream::c_writeRequest(const mijin::HTTPRequest& request) MIJIN_NOEXCEPT
|
||||
{
|
||||
std::map<std::string, std::string> moreHeaders;
|
||||
if (!request.body.empty())
|
||||
@ -94,7 +94,7 @@ Task<StreamError> HTTPStream::c_writeRequest(const mijin::HTTPRequest& request)
|
||||
co_return StreamError::SUCCESS;
|
||||
}
|
||||
|
||||
Task<StreamResult<HTTPResponse>> HTTPStream::c_readResponse() noexcept
|
||||
Task<StreamResult<HTTPResponse>> HTTPStream::c_readResponse() MIJIN_NOEXCEPT
|
||||
{
|
||||
std::string line;
|
||||
MIJIN_HTTP_READLINE(line);
|
||||
@ -162,7 +162,7 @@ Task<StreamResult<HTTPResponse>> HTTPStream::c_readResponse() noexcept
|
||||
}
|
||||
|
||||
Task<StreamResult<HTTPResponse>> HTTPClient::c_request(ip_address_t address, std::uint16_t port, bool https,
|
||||
HTTPRequest request) noexcept
|
||||
HTTPRequest request) MIJIN_NOEXCEPT
|
||||
{
|
||||
std::string hostname;
|
||||
if (auto it = request.headers.find("host"); it != request.headers.end())
|
||||
@ -190,7 +190,7 @@ Task<StreamResult<HTTPResponse>> HTTPClient::c_request(ip_address_t address, std
|
||||
co_return response;
|
||||
}
|
||||
|
||||
Task<StreamResult<HTTPResponse>> HTTPClient::c_request(const URL& url, HTTPRequest request) noexcept
|
||||
Task<StreamResult<HTTPResponse>> HTTPClient::c_request(const URL& url, HTTPRequest request) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (url.getHost().empty())
|
||||
{
|
||||
@ -241,7 +241,7 @@ Task<StreamResult<HTTPResponse>> HTTPClient::c_request(const URL& url, HTTPReque
|
||||
co_return co_await c_request(*ipAddress, port, https, std::move(request));
|
||||
}
|
||||
|
||||
void HTTPClient::disconnect() noexcept
|
||||
void HTTPClient::disconnect() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (socket_ == nullptr)
|
||||
{
|
||||
@ -251,7 +251,7 @@ void HTTPClient::disconnect() noexcept
|
||||
socket_ = nullptr;
|
||||
}
|
||||
|
||||
StreamError HTTPClient::createSocket(ip_address_t address, const std::string& hostname, std::uint16_t port, bool https) noexcept
|
||||
StreamError HTTPClient::createSocket(ip_address_t address, const std::string& hostname, std::uint16_t port, bool https) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (socket_ != nullptr && address == lastIP_ && port == lastPort_ && https == lastWasHttps_)
|
||||
{
|
||||
@ -282,6 +282,7 @@ StreamError HTTPClient::createSocket(ip_address_t address, const std::string& ho
|
||||
sslStream_ = std::move(sslStream);
|
||||
stream_.construct(*sslStream_);
|
||||
#else
|
||||
(void) hostname;
|
||||
return StreamError::NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "./socket.hpp"
|
||||
#include "./url.hpp"
|
||||
#include "../container/boxed_object.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
#include "../io/stream.hpp"
|
||||
|
||||
namespace mijin
|
||||
@ -43,14 +44,14 @@ class HTTPStream
|
||||
private:
|
||||
Stream* base_;
|
||||
public:
|
||||
HTTPStream(Stream& base) noexcept : base_(&base)
|
||||
HTTPStream(Stream& base) MIJIN_NOEXCEPT : base_(&base)
|
||||
{
|
||||
MIJIN_ASSERT(base_ != nullptr, "Invalid parameter for base.");
|
||||
}
|
||||
Task<StreamResult<HTTPResponse>> c_request(HTTPRequest request) noexcept;
|
||||
Task<StreamResult<HTTPResponse>> c_request(HTTPRequest request) MIJIN_NOEXCEPT;
|
||||
private:
|
||||
Task<StreamError> c_writeRequest(const HTTPRequest& request) noexcept;
|
||||
Task<StreamResult<HTTPResponse>> c_readResponse() noexcept;
|
||||
Task<StreamError> c_writeRequest(const HTTPRequest& request) MIJIN_NOEXCEPT;
|
||||
Task<StreamResult<HTTPResponse>> c_readResponse() MIJIN_NOEXCEPT;
|
||||
};
|
||||
|
||||
class HTTPClient
|
||||
@ -63,12 +64,12 @@ private:
|
||||
std::uint16_t lastPort_ = 0;
|
||||
bool lastWasHttps_ = false;
|
||||
public:
|
||||
~HTTPClient() noexcept { disconnect(); }
|
||||
Task<StreamResult<HTTPResponse>> c_request(ip_address_t address, std::uint16_t port, bool https, HTTPRequest request) noexcept;
|
||||
Task<StreamResult<HTTPResponse>> c_request(const URL& url, HTTPRequest request = {}) noexcept;
|
||||
void disconnect() noexcept;
|
||||
~HTTPClient() MIJIN_NOEXCEPT { disconnect(); }
|
||||
Task<StreamResult<HTTPResponse>> c_request(ip_address_t address, std::uint16_t port, bool https, HTTPRequest request) MIJIN_NOEXCEPT;
|
||||
Task<StreamResult<HTTPResponse>> c_request(const URL& url, HTTPRequest request = {}) MIJIN_NOEXCEPT;
|
||||
void disconnect() MIJIN_NOEXCEPT;
|
||||
private:
|
||||
StreamError createSocket(ip_address_t address, const std::string& hostname, std::uint16_t port, bool https) noexcept;
|
||||
StreamError createSocket(ip_address_t address, const std::string& hostname, std::uint16_t port, bool https) MIJIN_NOEXCEPT;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ StreamError translateGAIError(int error)
|
||||
return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
StreamError osBeginResolve(const std::string& hostname, os_resolve_handle_t& handle) noexcept
|
||||
StreamError osBeginResolve(const std::string& hostname, os_resolve_handle_t& handle) MIJIN_NOEXCEPT
|
||||
{
|
||||
handle.item = {.ar_name = hostname.c_str()};
|
||||
|
||||
@ -44,12 +44,12 @@ StreamError osBeginResolve(const std::string& hostname, os_resolve_handle_t& han
|
||||
return StreamError::SUCCESS;
|
||||
}
|
||||
|
||||
bool osResolveDone(os_resolve_handle_t& handle) noexcept
|
||||
bool osResolveDone(os_resolve_handle_t& handle) MIJIN_NOEXCEPT
|
||||
{
|
||||
return gai_error(&handle.item) != EAI_INPROGRESS;
|
||||
}
|
||||
|
||||
StreamResult<std::vector<ip_address_t>> osResolveResult(os_resolve_handle_t& handle) noexcept
|
||||
StreamResult<std::vector<ip_address_t>> osResolveResult(os_resolve_handle_t& handle) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (const int error = gai_error(&handle.item); error != 0)
|
||||
{
|
||||
@ -112,7 +112,7 @@ struct WSAQueryContext
|
||||
};
|
||||
using os_resolve_handle_t = WSAQueryContext;
|
||||
|
||||
void WINAPI getAddrComplete(DWORD error, DWORD bytes, LPOVERLAPPED overlapped) noexcept
|
||||
void WINAPI getAddrComplete(DWORD error, DWORD bytes, LPOVERLAPPED overlapped) MIJIN_NOEXCEPT
|
||||
{
|
||||
(void) bytes;
|
||||
|
||||
@ -153,7 +153,7 @@ void WINAPI getAddrComplete(DWORD error, DWORD bytes, LPOVERLAPPED overlapped) n
|
||||
queryContext.result = std::move(resultAddresses);
|
||||
}
|
||||
|
||||
StreamError osBeginResolve(const std::string& hostname, os_resolve_handle_t& queryContext) noexcept
|
||||
StreamError osBeginResolve(const std::string& hostname, os_resolve_handle_t& queryContext) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (!detail::initWSA())
|
||||
{
|
||||
@ -181,12 +181,12 @@ StreamError osBeginResolve(const std::string& hostname, os_resolve_handle_t& que
|
||||
return StreamError::SUCCESS;
|
||||
}
|
||||
|
||||
bool osResolveDone(os_resolve_handle_t& queryContext) noexcept
|
||||
bool osResolveDone(os_resolve_handle_t& queryContext) MIJIN_NOEXCEPT
|
||||
{
|
||||
return !queryContext.result.isEmpty();
|
||||
}
|
||||
|
||||
StreamResult<std::vector<ip_address_t>> osResolveResult(os_resolve_handle_t& queryContext) noexcept
|
||||
StreamResult<std::vector<ip_address_t>> osResolveResult(os_resolve_handle_t& queryContext) MIJIN_NOEXCEPT
|
||||
{
|
||||
return queryContext.result;
|
||||
}
|
||||
@ -204,7 +204,7 @@ std::string IPv6Address::toString() const
|
||||
hextets[5], hextets[6], hextets[7]);
|
||||
}
|
||||
|
||||
Optional<IPv4Address> IPv4Address::fromString(std::string_view stringView) noexcept
|
||||
Optional<IPv4Address> IPv4Address::fromString(std::string_view stringView) MIJIN_NOEXCEPT
|
||||
{
|
||||
std::vector<std::string_view> parts = split(stringView, ".", {.limitParts = 4});
|
||||
if (parts.size() != 4) {
|
||||
@ -221,7 +221,7 @@ Optional<IPv4Address> IPv4Address::fromString(std::string_view stringView) noexc
|
||||
return address;
|
||||
}
|
||||
|
||||
Optional<IPv6Address> IPv6Address::fromString(std::string_view stringView) noexcept
|
||||
Optional<IPv6Address> IPv6Address::fromString(std::string_view stringView) MIJIN_NOEXCEPT
|
||||
{
|
||||
// very specific edge case
|
||||
if (stringView.contains(":::"))
|
||||
@ -275,7 +275,7 @@ Optional<IPv6Address> IPv6Address::fromString(std::string_view stringView) noexc
|
||||
return address;
|
||||
}
|
||||
|
||||
Task<StreamResult<std::vector<ip_address_t>>> c_resolveHostname(std::string hostname) noexcept
|
||||
Task<StreamResult<std::vector<ip_address_t>>> c_resolveHostname(std::string hostname) MIJIN_NOEXCEPT
|
||||
{
|
||||
os_resolve_handle_t resolveHandle;
|
||||
if (StreamError error = osBeginResolve(hostname, resolveHandle); error != StreamError::SUCCESS)
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <variant>
|
||||
#include "../async/coroutine.hpp"
|
||||
#include "../container/optional.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
#include "../io/stream.hpp" // TODO: rename Stream{Error,Result} to IO{*}
|
||||
|
||||
namespace mijin
|
||||
@ -15,29 +16,29 @@ struct IPv4Address
|
||||
{
|
||||
std::array<std::uint8_t, 4> octets;
|
||||
|
||||
auto operator<=>(const IPv4Address&) const noexcept = default;
|
||||
auto operator<=>(const IPv4Address&) const MIJIN_NOEXCEPT = default;
|
||||
|
||||
[[nodiscard]] std::string toString() const;
|
||||
|
||||
[[nodiscard]]
|
||||
static Optional<IPv4Address> fromString(std::string_view stringView) noexcept;
|
||||
static Optional<IPv4Address> fromString(std::string_view stringView) MIJIN_NOEXCEPT;
|
||||
};
|
||||
|
||||
struct IPv6Address
|
||||
{
|
||||
std::array<std::uint16_t, 8> hextets;
|
||||
|
||||
auto operator<=>(const IPv6Address&) const noexcept = default;
|
||||
auto operator<=>(const IPv6Address&) const MIJIN_NOEXCEPT = default;
|
||||
|
||||
[[nodiscard]] std::string toString() const;
|
||||
|
||||
[[nodiscard]]
|
||||
static Optional<IPv6Address> fromString(std::string_view stringView) noexcept;
|
||||
static Optional<IPv6Address> fromString(std::string_view stringView) MIJIN_NOEXCEPT;
|
||||
};
|
||||
using ip_address_t = std::variant<IPv4Address, IPv6Address>;
|
||||
|
||||
[[nodiscard]]
|
||||
inline std::string ipAddressToString(const ip_address_t& address) noexcept
|
||||
inline std::string ipAddressToString(const ip_address_t& address) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (address.valueless_by_exception())
|
||||
{
|
||||
@ -47,7 +48,7 @@ inline std::string ipAddressToString(const ip_address_t& address) noexcept
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline Optional<ip_address_t> ipAddressFromString(std::string_view stringView) noexcept
|
||||
inline Optional<ip_address_t> ipAddressFromString(std::string_view stringView) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (Optional<IPv4Address> ipv4Address = IPv4Address::fromString(stringView); !ipv4Address.empty())
|
||||
{
|
||||
@ -61,16 +62,16 @@ inline Optional<ip_address_t> ipAddressFromString(std::string_view stringView) n
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Task<StreamResult<std::vector<ip_address_t>>> c_resolveHostname(std::string hostname) noexcept;
|
||||
Task<StreamResult<std::vector<ip_address_t>>> c_resolveHostname(std::string hostname) MIJIN_NOEXCEPT;
|
||||
|
||||
[[nodiscard]]
|
||||
inline Task<StreamResult<std::vector<ip_address_t>>> c_resolveHostname(std::string_view hostname) noexcept
|
||||
inline Task<StreamResult<std::vector<ip_address_t>>> c_resolveHostname(std::string_view hostname) MIJIN_NOEXCEPT
|
||||
{
|
||||
return c_resolveHostname(std::string(hostname.begin(), hostname.end()));
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline Task<StreamResult<std::vector<ip_address_t>>> c_resolveHostname(const char* hostname) noexcept
|
||||
inline Task<StreamResult<std::vector<ip_address_t>>> c_resolveHostname(const char* hostname) MIJIN_NOEXCEPT
|
||||
{
|
||||
return c_resolveHostname(std::string(hostname));
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <openssl/x509_vfy.h>
|
||||
|
||||
#include "../debug/assert.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
#include "../types/result.hpp"
|
||||
|
||||
namespace ossl
|
||||
@ -34,10 +35,10 @@ struct [[nodiscard]] Error
|
||||
std::vector<ErrorFrame> frames;
|
||||
|
||||
[[nodiscard]]
|
||||
bool isSuccess() const noexcept { return sslError == SSL_ERROR_NONE; }
|
||||
bool isSuccess() const MIJIN_NOEXCEPT { return sslError == SSL_ERROR_NONE; }
|
||||
|
||||
static inline Error current(int sslError = -1) noexcept;
|
||||
static inline Error current(SSL* handle, int result) noexcept { return current(SSL_get_error(handle, result)); }
|
||||
static inline Error current(int sslError = -1) MIJIN_NOEXCEPT;
|
||||
static inline Error current(SSL* handle, int result) MIJIN_NOEXCEPT { return current(SSL_get_error(handle, result)); }
|
||||
};
|
||||
template<typename TSuccess>
|
||||
using Result = mijin::ResultBase<TSuccess, Error>;
|
||||
@ -53,24 +54,24 @@ protected:
|
||||
|
||||
THandle handle_ = nullptr;
|
||||
protected:
|
||||
explicit Base(THandle handle) noexcept : handle_(handle) {}
|
||||
explicit Base(THandle handle) MIJIN_NOEXCEPT : handle_(handle) {}
|
||||
public:
|
||||
Base() noexcept = default;
|
||||
Base(const Base& other) noexcept : handle_(other.handle_)
|
||||
Base() MIJIN_NOEXCEPT = default;
|
||||
Base(const Base& other) MIJIN_NOEXCEPT : handle_(other.handle_)
|
||||
{
|
||||
if (handle_)
|
||||
{
|
||||
TActual::upReferences(handle_);
|
||||
}
|
||||
}
|
||||
Base(Base&& other) noexcept : handle_(std::exchange(other.handle_, {})) {}
|
||||
Base(Base&& other) MIJIN_NOEXCEPT : handle_(std::exchange(other.handle_, {})) {}
|
||||
|
||||
~Base() noexcept
|
||||
~Base() MIJIN_NOEXCEPT
|
||||
{
|
||||
static_cast<TActual&>(*this).free();
|
||||
}
|
||||
|
||||
TActual& operator=(const Base& other) noexcept
|
||||
TActual& operator=(const Base& other) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (this == &other)
|
||||
{
|
||||
@ -85,7 +86,7 @@ public:
|
||||
return static_cast<TActual&>(*this);
|
||||
}
|
||||
|
||||
TActual& operator=(Base&& other) noexcept
|
||||
TActual& operator=(Base&& other) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (this == &other)
|
||||
{
|
||||
@ -95,22 +96,22 @@ public:
|
||||
handle_ = std::exchange(other.handle_, {});
|
||||
return static_cast<TActual&>(*this);
|
||||
}
|
||||
auto operator<=>(const Base&) const noexcept = default;
|
||||
operator bool() const noexcept { return static_cast<bool>(handle_); }
|
||||
bool operator!() const noexcept { return !static_cast<bool>(handle_); }
|
||||
auto operator<=>(const Base&) const MIJIN_NOEXCEPT = default;
|
||||
operator bool() const MIJIN_NOEXCEPT { return static_cast<bool>(handle_); }
|
||||
bool operator!() const MIJIN_NOEXCEPT { return !static_cast<bool>(handle_); }
|
||||
|
||||
[[nodiscard]]
|
||||
THandle getHandle() const noexcept { return handle_; }
|
||||
THandle getHandle() const MIJIN_NOEXCEPT { return handle_; }
|
||||
|
||||
[[nodiscard]]
|
||||
THandle releaseHandle() noexcept { return std::exchange(handle_, nullptr); }
|
||||
THandle releaseHandle() MIJIN_NOEXCEPT { return std::exchange(handle_, nullptr); }
|
||||
};
|
||||
|
||||
class X509Store : public Base<X509Store, X509_STORE*>
|
||||
{
|
||||
public:
|
||||
using Base::Base;
|
||||
Error create() noexcept
|
||||
Error create() MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(handle_ == nullptr, "X509 Store already created.");
|
||||
ERR_clear_error();
|
||||
@ -122,7 +123,7 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
void free() noexcept
|
||||
void free() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (handle_ != nullptr)
|
||||
{
|
||||
@ -131,7 +132,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Error loadFile(const char* file) const noexcept
|
||||
Error loadFile(const char* file) const MIJIN_NOEXCEPT
|
||||
{
|
||||
ERR_clear_error();
|
||||
if (!X509_STORE_load_file(handle_, file))
|
||||
@ -141,7 +142,7 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
static void upReferences(X509_STORE* handle) noexcept
|
||||
static void upReferences(X509_STORE* handle) MIJIN_NOEXCEPT
|
||||
{
|
||||
X509_STORE_up_ref(handle);
|
||||
}
|
||||
@ -150,7 +151,7 @@ public:
|
||||
class Context : public Base<Context, SSL_CTX*>
|
||||
{
|
||||
public:
|
||||
Error create(const SSL_METHOD* method) noexcept
|
||||
Error create(const SSL_METHOD* method) MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(handle_ == nullptr, "Context already created.");
|
||||
ERR_clear_error();
|
||||
@ -162,7 +163,7 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
void free() noexcept
|
||||
void free() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (handle_ == nullptr)
|
||||
{
|
||||
@ -172,17 +173,17 @@ public:
|
||||
handle_ = nullptr;
|
||||
}
|
||||
|
||||
void setVerify(int mode, verify_callback_t callback = nullptr) const noexcept
|
||||
void setVerify(int mode, verify_callback_t callback = nullptr) const MIJIN_NOEXCEPT
|
||||
{
|
||||
SSL_CTX_set_verify(handle_, mode, callback);
|
||||
}
|
||||
|
||||
void setCertStore(X509Store store) const noexcept
|
||||
void setCertStore(X509Store store) const MIJIN_NOEXCEPT
|
||||
{
|
||||
SSL_CTX_set_cert_store(handle_, store.releaseHandle());
|
||||
}
|
||||
|
||||
Error setMinProtoVersion(int version) const noexcept
|
||||
Error setMinProtoVersion(int version) const MIJIN_NOEXCEPT
|
||||
{
|
||||
ERR_clear_error();
|
||||
if (!SSL_CTX_set_min_proto_version(handle_, version))
|
||||
@ -192,7 +193,7 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
static void upReferences(SSL_CTX* handle) noexcept
|
||||
static void upReferences(SSL_CTX* handle) MIJIN_NOEXCEPT
|
||||
{
|
||||
SSL_CTX_up_ref(handle);
|
||||
}
|
||||
@ -201,7 +202,7 @@ public:
|
||||
class Bio : public Base<Bio, BIO*>
|
||||
{
|
||||
public:
|
||||
Error createPair(Bio& otherBio, std::size_t writeBuf = 0, std::size_t otherWriteBuf = 0) noexcept
|
||||
Error createPair(Bio& otherBio, std::size_t writeBuf = 0, std::size_t otherWriteBuf = 0) MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(handle_ == nullptr, "Ssl already created.");
|
||||
MIJIN_ASSERT(otherBio.handle_ == nullptr, "Ssl already created.");
|
||||
@ -213,7 +214,7 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
void free() noexcept
|
||||
void free() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (handle_ == nullptr)
|
||||
{
|
||||
@ -224,18 +225,18 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
std::size_t ctrlPending() const noexcept
|
||||
std::size_t ctrlPending() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return BIO_ctrl_pending(handle_);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
std::size_t ctrlWPending() const noexcept
|
||||
std::size_t ctrlWPending() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return BIO_ctrl_wpending(handle_);
|
||||
}
|
||||
|
||||
Result<int> write(const void* data, int length) const noexcept
|
||||
Result<int> write(const void* data, int length) const MIJIN_NOEXCEPT
|
||||
{
|
||||
ERR_clear_error();
|
||||
const int result = BIO_write(handle_, data, length);
|
||||
@ -246,7 +247,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
Result<int> read(void* data, int length) const noexcept
|
||||
Result<int> read(void* data, int length) const MIJIN_NOEXCEPT
|
||||
{
|
||||
ERR_clear_error();
|
||||
const int result = BIO_read(handle_, data, length);
|
||||
@ -258,24 +259,24 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
int getReadRequest() const noexcept
|
||||
int getReadRequest() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return BIO_get_read_request(handle_);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
int getWriteGuarantee() const noexcept
|
||||
int getWriteGuarantee() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return BIO_get_write_guarantee(handle_);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
int getWritePending() const noexcept
|
||||
int getWritePending() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return BIO_wpending(handle_);
|
||||
}
|
||||
|
||||
Error flush() const noexcept
|
||||
Error flush() const MIJIN_NOEXCEPT
|
||||
{
|
||||
ERR_clear_error();
|
||||
if (!BIO_flush(handle_))
|
||||
@ -285,7 +286,7 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
static void upReferences(BIO* handle) noexcept
|
||||
static void upReferences(BIO* handle) MIJIN_NOEXCEPT
|
||||
{
|
||||
BIO_up_ref(handle);
|
||||
}
|
||||
@ -294,7 +295,7 @@ public:
|
||||
class Ssl : public Base<Ssl, SSL*>
|
||||
{
|
||||
public:
|
||||
Error create(const Context& context) noexcept
|
||||
Error create(const Context& context) MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(handle_ == nullptr, "Ssl already created.");
|
||||
ERR_clear_error();
|
||||
@ -306,7 +307,7 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
void free() noexcept
|
||||
void free() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (handle_ == nullptr)
|
||||
{
|
||||
@ -316,18 +317,18 @@ public:
|
||||
handle_ = nullptr;
|
||||
}
|
||||
|
||||
void setBio(Bio readBio, Bio writeBio) const noexcept
|
||||
void setBio(Bio readBio, Bio writeBio) const MIJIN_NOEXCEPT
|
||||
{
|
||||
SSL_set_bio(handle_, readBio.releaseHandle(), writeBio.releaseHandle());
|
||||
}
|
||||
|
||||
void setBio(Bio&& bio) const noexcept
|
||||
void setBio(Bio&& bio) const MIJIN_NOEXCEPT
|
||||
{
|
||||
BIO* bioHandle = bio.releaseHandle();
|
||||
SSL_set_bio(handle_, bioHandle, bioHandle);
|
||||
}
|
||||
|
||||
Error setTLSExtHostname(const char* hostname) const noexcept
|
||||
Error setTLSExtHostname(const char* hostname) const MIJIN_NOEXCEPT
|
||||
{
|
||||
ERR_clear_error();
|
||||
if (const int result = SSL_set_tlsext_host_name(handle_, hostname); result != 1)
|
||||
@ -337,7 +338,7 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
Error setHost(const char* hostname) const noexcept
|
||||
Error setHost(const char* hostname) const MIJIN_NOEXCEPT
|
||||
{
|
||||
ERR_clear_error();
|
||||
if (const int result = SSL_set1_host(handle_, hostname); result != 1)
|
||||
@ -347,7 +348,7 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
Error connect() const noexcept
|
||||
Error connect() const MIJIN_NOEXCEPT
|
||||
{
|
||||
ERR_clear_error();
|
||||
if (const int result = SSL_connect(handle_); result != 1)
|
||||
@ -357,7 +358,7 @@ public:
|
||||
return {};
|
||||
}
|
||||
|
||||
Error shutdown() const noexcept
|
||||
Error shutdown() const MIJIN_NOEXCEPT
|
||||
{
|
||||
ERR_clear_error();
|
||||
if (const int result = SSL_shutdown(handle_); result != 1)
|
||||
@ -372,12 +373,12 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
long getVerifyResult() const noexcept
|
||||
long getVerifyResult() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return SSL_get_verify_result(handle_);
|
||||
}
|
||||
|
||||
Result<int> write(const void* data, int length) const noexcept
|
||||
Result<int> write(const void* data, int length) const MIJIN_NOEXCEPT
|
||||
{
|
||||
ERR_clear_error();
|
||||
const int result = SSL_write(handle_, data, length);
|
||||
@ -388,7 +389,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
Result<int> read(void* data, int length) const noexcept
|
||||
Result<int> read(void* data, int length) const MIJIN_NOEXCEPT
|
||||
{
|
||||
ERR_clear_error();
|
||||
const int result = SSL_read(handle_, data, length);
|
||||
@ -400,18 +401,18 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
int pending() const noexcept
|
||||
int pending() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return SSL_pending(handle_);
|
||||
}
|
||||
|
||||
static void upReferences(SSL* handle) noexcept
|
||||
static void upReferences(SSL* handle) MIJIN_NOEXCEPT
|
||||
{
|
||||
SSL_up_ref(handle);
|
||||
}
|
||||
};
|
||||
|
||||
Error Error::current(int sslError_) noexcept
|
||||
Error Error::current(int sslError_) MIJIN_NOEXCEPT
|
||||
{
|
||||
Error error = {
|
||||
.sslError = sslError_
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "./detail/net_common.hpp"
|
||||
#include "../detect.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
#include "../util/variant.hpp"
|
||||
|
||||
namespace mijin
|
||||
@ -10,7 +11,7 @@ namespace mijin
|
||||
namespace
|
||||
{
|
||||
inline constexpr int LISTEN_BACKLOG = 3;
|
||||
StreamError translateErrno() noexcept
|
||||
StreamError translateErrno() MIJIN_NOEXCEPT
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
@ -30,7 +31,7 @@ int readFlags(const ReadOptions& options)
|
||||
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
||||
const int SOCKOPT_ONE = 1;
|
||||
|
||||
bool appendSocketFlags(int handle, int flags) noexcept
|
||||
bool appendSocketFlags(int handle, int flags) MIJIN_NOEXCEPT
|
||||
{
|
||||
const int currentFlags = fcntl(handle, F_GETFL);
|
||||
if (currentFlags < 0)
|
||||
@ -40,7 +41,7 @@ bool appendSocketFlags(int handle, int flags) noexcept
|
||||
return fcntl(handle, F_SETFL, currentFlags | flags) >= 0;
|
||||
}
|
||||
|
||||
bool removeSocketFlags(int handle, int flags) noexcept
|
||||
bool removeSocketFlags(int handle, int flags) MIJIN_NOEXCEPT
|
||||
{
|
||||
const int currentFlags = fcntl(handle, F_GETFL);
|
||||
if (currentFlags < 0)
|
||||
@ -50,32 +51,32 @@ bool removeSocketFlags(int handle, int flags) noexcept
|
||||
return fcntl(handle, F_SETFL, currentFlags & ~flags) >= 0;
|
||||
}
|
||||
|
||||
long osRecv(int socket, std::span<std::uint8_t> buffer, int flags)
|
||||
long osRecv(int socket, std::span<std::uint8_t> buffer, int flags) MIJIN_NOEXCEPT
|
||||
{
|
||||
return static_cast<long>(recv(socket, buffer.data(), buffer.size(), flags));
|
||||
}
|
||||
|
||||
long osSend(int socket, std::span<const std::uint8_t> buffer, int flags)
|
||||
long osSend(int socket, std::span<const std::uint8_t> buffer, int flags) MIJIN_NOEXCEPT
|
||||
{
|
||||
return static_cast<long>(send(socket, buffer.data(), buffer.size(), flags));
|
||||
}
|
||||
|
||||
int osCreateSocket(int domain, int type, int protocol)
|
||||
int osCreateSocket(int domain, int type, int protocol) MIJIN_NOEXCEPT
|
||||
{
|
||||
return socket(domain, type, protocol);
|
||||
}
|
||||
|
||||
int osCloseSocket(int socket)
|
||||
int osCloseSocket(int socket) MIJIN_NOEXCEPT
|
||||
{
|
||||
return ::close(socket);
|
||||
}
|
||||
|
||||
bool osIsSocketValid(int socket)
|
||||
bool osIsSocketValid(int socket) MIJIN_NOEXCEPT
|
||||
{
|
||||
return socket >= 0;
|
||||
}
|
||||
|
||||
bool osSetSocketNonBlocking(int socket, bool blocking)
|
||||
bool osSetSocketNonBlocking(int socket, bool blocking) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (blocking)
|
||||
{
|
||||
@ -95,7 +96,7 @@ thread_local bool gWsaInited = false;
|
||||
class WSAGuard
|
||||
{
|
||||
public:
|
||||
~WSAGuard() noexcept
|
||||
~WSAGuard() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (gWsaInited)
|
||||
{
|
||||
@ -104,17 +105,17 @@ public:
|
||||
}
|
||||
} thread_local [[maybe_unused]] gWsaGuard;
|
||||
|
||||
long osRecv(SOCKET socket, std::span<std::uint8_t> buffer, int flags)
|
||||
long osRecv(SOCKET socket, std::span<std::uint8_t> buffer, int flags) MIJIN_NOEXCEPT
|
||||
{
|
||||
return recv(socket, reinterpret_cast<char*>(buffer.data()), static_cast<int>(buffer.size()), flags);
|
||||
}
|
||||
|
||||
long osSend(SOCKET socket, std::span<const std::uint8_t> buffer, int flags)
|
||||
long osSend(SOCKET socket, std::span<const std::uint8_t> buffer, int flags) MIJIN_NOEXCEPT
|
||||
{
|
||||
return send(socket, reinterpret_cast<const char*>(buffer.data()), static_cast<int>(buffer.size()), flags);
|
||||
}
|
||||
|
||||
SOCKET osCreateSocket(int addressFamily, int type, int protocol)
|
||||
SOCKET osCreateSocket(int addressFamily, int type, int protocol) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (!detail::initWSA())
|
||||
{
|
||||
@ -123,17 +124,17 @@ SOCKET osCreateSocket(int addressFamily, int type, int protocol)
|
||||
return socket(addressFamily, type, protocol);
|
||||
}
|
||||
|
||||
int osCloseSocket(SOCKET socket)
|
||||
int osCloseSocket(SOCKET socket) MIJIN_NOEXCEPT
|
||||
{
|
||||
return closesocket(socket);
|
||||
}
|
||||
|
||||
bool osIsSocketValid(SOCKET socket)
|
||||
bool osIsSocketValid(SOCKET socket) MIJIN_NOEXCEPT
|
||||
{
|
||||
return socket != INVALID_SOCKET;
|
||||
}
|
||||
|
||||
bool osSetSocketNonBlocking(SOCKET socket, bool blocking)
|
||||
bool osSetSocketNonBlocking(SOCKET socket, bool blocking) MIJIN_NOEXCEPT
|
||||
{
|
||||
u_long value = blocking ? 0 : 1;
|
||||
return ioctlsocket(socket, FIONBIO, &value) == NO_ERROR;
|
||||
@ -144,7 +145,7 @@ bool osSetSocketNonBlocking(SOCKET socket, bool blocking)
|
||||
namespace detail
|
||||
{
|
||||
#if MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
|
||||
bool initWSA() noexcept
|
||||
bool initWSA() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (gWsaInited)
|
||||
{
|
||||
@ -160,20 +161,20 @@ bool initWSA() noexcept
|
||||
return true;
|
||||
}
|
||||
|
||||
StreamError translateWSAError() noexcept
|
||||
StreamError translateWSAError() MIJIN_NOEXCEPT
|
||||
{
|
||||
// TODO
|
||||
return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
StreamError translateWinError(DWORD error) noexcept
|
||||
StreamError translateWinError(DWORD error) MIJIN_NOEXCEPT
|
||||
{
|
||||
// TODO
|
||||
(void) error;
|
||||
return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
StreamError translateWinError() noexcept
|
||||
StreamError translateWinError() MIJIN_NOEXCEPT
|
||||
{
|
||||
return translateWinError(GetLastError());
|
||||
}
|
||||
@ -327,7 +328,7 @@ StreamFeatures TCPStream::getFeatures()
|
||||
};
|
||||
}
|
||||
|
||||
StreamError TCPStream::open(ip_address_t address, std::uint16_t port) noexcept
|
||||
StreamError TCPStream::open(ip_address_t address, std::uint16_t port) MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(!isOpen(), "Socket is already open.");
|
||||
|
||||
@ -375,19 +376,19 @@ StreamError TCPStream::open(ip_address_t address, std::uint16_t port) noexcept
|
||||
return StreamError::SUCCESS;
|
||||
}
|
||||
|
||||
void TCPStream::close() noexcept
|
||||
void TCPStream::close() MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(isOpen(), "Socket is not open.");
|
||||
osCloseSocket(handle_);
|
||||
handle_ = INVALID_SOCKET_HANDLE;
|
||||
}
|
||||
|
||||
TCPStream& TCPSocket::getStream() noexcept
|
||||
TCPStream& TCPSocket::getStream() MIJIN_NOEXCEPT
|
||||
{
|
||||
return stream_;
|
||||
}
|
||||
|
||||
StreamError TCPServerSocket::setup(ip_address_t address, std::uint16_t port) noexcept
|
||||
StreamError TCPServerSocket::setup(ip_address_t address, std::uint16_t port) MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(!isListening(), "Socket is already listening.");
|
||||
|
||||
@ -440,7 +441,7 @@ StreamError TCPServerSocket::setup(ip_address_t address, std::uint16_t port) noe
|
||||
return StreamError::SUCCESS;
|
||||
}
|
||||
|
||||
void TCPServerSocket::close() noexcept
|
||||
void TCPServerSocket::close() MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(isListening(), "Socket is not listening.");
|
||||
|
||||
@ -448,7 +449,7 @@ void TCPServerSocket::close() noexcept
|
||||
handle_ = INVALID_SOCKET_HANDLE;
|
||||
}
|
||||
|
||||
Task<StreamResult<std::unique_ptr<Socket>>> TCPServerSocket::c_waitForConnection() noexcept
|
||||
Task<StreamResult<std::unique_ptr<Socket>>> TCPServerSocket::c_waitForConnection() MIJIN_NOEXCEPT
|
||||
{
|
||||
while (isListening())
|
||||
{
|
||||
|
@ -30,32 +30,32 @@ inline constexpr socket_handle_t INVALID_SOCKET_HANDLE = -1;
|
||||
class Socket
|
||||
{
|
||||
protected:
|
||||
Socket() noexcept = default;
|
||||
Socket(const Socket&) noexcept = default;
|
||||
Socket(Socket&&) noexcept = default;
|
||||
Socket() MIJIN_NOEXCEPT = default;
|
||||
Socket(const Socket&) MIJIN_NOEXCEPT = default;
|
||||
Socket(Socket&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
Socket& operator=(const Socket&) noexcept = default;
|
||||
Socket& operator=(Socket&&) noexcept = default;
|
||||
Socket& operator=(const Socket&) MIJIN_NOEXCEPT = default;
|
||||
Socket& operator=(Socket&&) MIJIN_NOEXCEPT = default;
|
||||
public:
|
||||
virtual ~Socket() noexcept = default;
|
||||
virtual ~Socket() MIJIN_NOEXCEPT = default;
|
||||
|
||||
virtual Stream& getStream() noexcept = 0;
|
||||
virtual Stream& getStream() MIJIN_NOEXCEPT = 0;
|
||||
};
|
||||
|
||||
class ServerSocket
|
||||
{
|
||||
protected:
|
||||
ServerSocket() noexcept = default;
|
||||
ServerSocket(const ServerSocket&) noexcept = default;
|
||||
ServerSocket(ServerSocket&&) noexcept = default;
|
||||
ServerSocket() MIJIN_NOEXCEPT = default;
|
||||
ServerSocket(const ServerSocket&) MIJIN_NOEXCEPT = default;
|
||||
ServerSocket(ServerSocket&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
ServerSocket& operator=(const ServerSocket&) noexcept = default;
|
||||
ServerSocket& operator=(ServerSocket&&) noexcept = default;
|
||||
ServerSocket& operator=(const ServerSocket&) MIJIN_NOEXCEPT = default;
|
||||
ServerSocket& operator=(ServerSocket&&) MIJIN_NOEXCEPT = default;
|
||||
public:
|
||||
virtual ~ServerSocket() noexcept = default;
|
||||
virtual ~ServerSocket() MIJIN_NOEXCEPT = default;
|
||||
|
||||
virtual void close() noexcept = 0;
|
||||
virtual Task<StreamResult<std::unique_ptr<Socket>>> c_waitForConnection() noexcept = 0;
|
||||
virtual void close() MIJIN_NOEXCEPT = 0;
|
||||
virtual Task<StreamResult<std::unique_ptr<Socket>>> c_waitForConnection() MIJIN_NOEXCEPT = 0;
|
||||
};
|
||||
|
||||
class TCPStream : public Stream
|
||||
@ -74,9 +74,9 @@ public:
|
||||
bool isAtEnd() override;
|
||||
StreamFeatures getFeatures() override;
|
||||
|
||||
StreamError open(ip_address_t address, std::uint16_t port) noexcept;
|
||||
void close() noexcept;
|
||||
[[nodiscard]] bool isOpen() const noexcept { return handle_ != INVALID_SOCKET_HANDLE; }
|
||||
StreamError open(ip_address_t address, std::uint16_t port) MIJIN_NOEXCEPT;
|
||||
void close() MIJIN_NOEXCEPT;
|
||||
[[nodiscard]] bool isOpen() const MIJIN_NOEXCEPT { return handle_ != INVALID_SOCKET_HANDLE; }
|
||||
private:
|
||||
void setNoblock(bool async);
|
||||
|
||||
@ -88,10 +88,10 @@ class TCPSocket : public Socket
|
||||
private:
|
||||
TCPStream stream_;
|
||||
public:
|
||||
TCPStream& getStream() noexcept override;
|
||||
TCPStream& getStream() MIJIN_NOEXCEPT override;
|
||||
|
||||
StreamError open(ip_address_t address, std::uint16_t port) noexcept { return stream_.open(address, port); }
|
||||
StreamError open(std::string_view addressText, std::uint16_t port) noexcept
|
||||
StreamError open(ip_address_t address, std::uint16_t port) MIJIN_NOEXCEPT { return stream_.open(address, port); }
|
||||
StreamError open(std::string_view addressText, std::uint16_t port) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (Optional<ip_address_t> address = ipAddressFromString(addressText); !address.empty())
|
||||
{
|
||||
@ -99,8 +99,8 @@ public:
|
||||
}
|
||||
return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
void close() noexcept { stream_.close(); }
|
||||
[[nodiscard]] bool isOpen() const noexcept { return stream_.isOpen(); }
|
||||
void close() MIJIN_NOEXCEPT { stream_.close(); }
|
||||
[[nodiscard]] bool isOpen() const MIJIN_NOEXCEPT { return stream_.isOpen(); }
|
||||
|
||||
friend class TCPServerSocket;
|
||||
};
|
||||
@ -110,8 +110,8 @@ class TCPServerSocket : public ServerSocket
|
||||
private:
|
||||
socket_handle_t handle_ = INVALID_SOCKET_HANDLE;
|
||||
public:
|
||||
StreamError setup(ip_address_t address, std::uint16_t port) noexcept;
|
||||
StreamError setup(std::string_view addressText, std::uint16_t port) noexcept
|
||||
StreamError setup(ip_address_t address, std::uint16_t port) MIJIN_NOEXCEPT;
|
||||
StreamError setup(std::string_view addressText, std::uint16_t port) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (Optional<ip_address_t> address = ipAddressFromString(addressText); !address.empty())
|
||||
{
|
||||
@ -119,10 +119,10 @@ public:
|
||||
}
|
||||
return StreamError::UNKNOWN_ERROR;
|
||||
}
|
||||
void close() noexcept override;
|
||||
[[nodiscard]] bool isListening() const noexcept { return handle_ >= 0; }
|
||||
void close() MIJIN_NOEXCEPT override;
|
||||
[[nodiscard]] bool isListening() const MIJIN_NOEXCEPT { return handle_ >= 0; }
|
||||
|
||||
Task<StreamResult<std::unique_ptr<Socket>>> c_waitForConnection() noexcept override;
|
||||
Task<StreamResult<std::unique_ptr<Socket>>> c_waitForConnection() MIJIN_NOEXCEPT override;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ namespace mijin
|
||||
namespace
|
||||
{
|
||||
inline constexpr int BIO_BUFFER_SIZE = 4096;
|
||||
ossl::Result<ossl::Context*> getSSLContext() noexcept
|
||||
ossl::Result<ossl::Context*> getSSLContext() MIJIN_NOEXCEPT
|
||||
{
|
||||
static ossl::Context context;
|
||||
static std::mutex contextMutex;
|
||||
@ -52,7 +52,7 @@ ossl::Result<ossl::Context*> getSSLContext() noexcept
|
||||
}
|
||||
}
|
||||
|
||||
StreamError SSLStream::open(Stream& base, const std::string& hostname) noexcept
|
||||
StreamError SSLStream::open(Stream& base, const std::string& hostname) MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(base_ == nullptr, "SSL stream is already open.");
|
||||
|
||||
@ -112,7 +112,7 @@ StreamError SSLStream::open(Stream& base, const std::string& hostname) noexcept
|
||||
return StreamError::SUCCESS;
|
||||
}
|
||||
|
||||
void SSLStream::close() noexcept
|
||||
void SSLStream::close() MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT(base_ != nullptr, "SSL stream is not open.");
|
||||
base_ = nullptr;
|
||||
@ -233,7 +233,7 @@ StreamFeatures SSLStream::getFeatures()
|
||||
};
|
||||
}
|
||||
|
||||
StreamError SSLStream::bioToBase() noexcept
|
||||
StreamError SSLStream::bioToBase() MIJIN_NOEXCEPT
|
||||
{
|
||||
std::array<std::uint8_t, BIO_BUFFER_SIZE> buffer;
|
||||
std::size_t bytes = std::min(externalBio_.ctrlPending(), buffer.size());
|
||||
@ -254,7 +254,7 @@ StreamError SSLStream::bioToBase() noexcept
|
||||
return StreamError::SUCCESS;
|
||||
}
|
||||
|
||||
StreamError SSLStream::baseToBio() noexcept
|
||||
StreamError SSLStream::baseToBio() MIJIN_NOEXCEPT
|
||||
{
|
||||
std::array<std::uint8_t, BIO_BUFFER_SIZE> buffer;
|
||||
std::size_t toRead = externalBio_.getWriteGuarantee();
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include "./openssl_wrappers.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
#include "../io/stream.hpp"
|
||||
|
||||
namespace mijin
|
||||
@ -22,15 +23,15 @@ private:
|
||||
ossl::Ssl ssl_;
|
||||
ossl::Bio externalBio_;
|
||||
public:
|
||||
~SSLStream() noexcept override
|
||||
~SSLStream() MIJIN_NOEXCEPT override
|
||||
{
|
||||
if (base_ != nullptr)
|
||||
{
|
||||
close();
|
||||
}
|
||||
}
|
||||
StreamError open(Stream& base, const std::string& hostname) noexcept;
|
||||
void close() noexcept;
|
||||
StreamError open(Stream& base, const std::string& hostname) MIJIN_NOEXCEPT;
|
||||
void close() MIJIN_NOEXCEPT;
|
||||
|
||||
StreamError readRaw(std::span<std::uint8_t> buffer, const ReadOptions& options, std::size_t* outBytesRead) override;
|
||||
StreamError writeRaw(std::span<const std::uint8_t> buffer) override;
|
||||
@ -40,8 +41,8 @@ public:
|
||||
bool isAtEnd() override;
|
||||
StreamFeatures getFeatures() override;
|
||||
private:
|
||||
StreamError bioToBase() noexcept;
|
||||
StreamError baseToBio() noexcept;
|
||||
StreamError bioToBase() MIJIN_NOEXCEPT;
|
||||
StreamError baseToBio() MIJIN_NOEXCEPT;
|
||||
|
||||
|
||||
template<typename TFunc, typename... TArgs>
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include "../internal/common.hpp"
|
||||
#include "../util/string.hpp"
|
||||
|
||||
namespace mijin
|
||||
@ -28,37 +29,38 @@ private:
|
||||
string_view_t pathQueryFragment_;
|
||||
std::uint16_t port_ = 0;
|
||||
public:
|
||||
constexpr URLBase() noexcept = default;
|
||||
constexpr URLBase() MIJIN_NOEXCEPT = default;
|
||||
constexpr URLBase(const URLBase&) = default;
|
||||
constexpr URLBase(URLBase&&) noexcept = default;
|
||||
constexpr URLBase(string_t base) noexcept : base_(std::move(base)) { parse(); }
|
||||
constexpr URLBase(URLBase&&) MIJIN_NOEXCEPT = default;
|
||||
constexpr URLBase(string_t base) MIJIN_NOEXCEPT : base_(std::move(base)) { parse(); }
|
||||
constexpr URLBase(string_view_t base) : URLBase(string_t(base.begin(), base.end())) {}
|
||||
constexpr URLBase(const TChar* base) : URLBase(string_t(base)) {}
|
||||
|
||||
constexpr URLBase& operator=(const URLBase&) = default;
|
||||
constexpr URLBase& operator=(URLBase&&) noexcept = default;
|
||||
constexpr URLBase& operator=(URLBase&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
[[nodiscard]] constexpr bool isValid() const noexcept { return !base_.empty(); }
|
||||
[[nodiscard]] constexpr string_view_t getScheme() const noexcept { return scheme_; }
|
||||
[[nodiscard]] constexpr string_view_t getUserInfo() const noexcept { return userinfo_; }
|
||||
[[nodiscard]] constexpr string_view_t getHost() const noexcept { return host_; }
|
||||
[[nodiscard]] constexpr string_view_t getPath() const noexcept { return path_; }
|
||||
[[nodiscard]] constexpr string_view_t getQuery() const noexcept { return query_; }
|
||||
[[nodiscard]] constexpr string_view_t getFragment() const noexcept { return fragment_; }
|
||||
[[nodiscard]] constexpr string_view_t getPathQueryFragment() const noexcept { return pathQueryFragment_; }
|
||||
[[nodiscard]] constexpr std::uint16_t getPort() const noexcept { return port_; }
|
||||
[[nodiscard]] constexpr bool isValid() const MIJIN_NOEXCEPT { return !base_.empty(); }
|
||||
[[nodiscard]] constexpr const string_t& getBase() const MIJIN_NOEXCEPT { return base_; }
|
||||
[[nodiscard]] constexpr string_view_t getScheme() const MIJIN_NOEXCEPT { return scheme_; }
|
||||
[[nodiscard]] constexpr string_view_t getUserInfo() const MIJIN_NOEXCEPT { return userinfo_; }
|
||||
[[nodiscard]] constexpr string_view_t getHost() const MIJIN_NOEXCEPT { return host_; }
|
||||
[[nodiscard]] constexpr string_view_t getPath() const MIJIN_NOEXCEPT { return path_; }
|
||||
[[nodiscard]] constexpr string_view_t getQuery() const MIJIN_NOEXCEPT { return query_; }
|
||||
[[nodiscard]] constexpr string_view_t getFragment() const MIJIN_NOEXCEPT { return fragment_; }
|
||||
[[nodiscard]] constexpr string_view_t getPathQueryFragment() const MIJIN_NOEXCEPT { return pathQueryFragment_; }
|
||||
[[nodiscard]] constexpr std::uint16_t getPort() const MIJIN_NOEXCEPT { return port_; }
|
||||
|
||||
|
||||
constexpr void clear() noexcept;
|
||||
constexpr void clear() MIJIN_NOEXCEPT;
|
||||
private:
|
||||
constexpr void parse() noexcept;
|
||||
constexpr bool parseAuthority(string_view_t authority) noexcept;
|
||||
constexpr void parse() MIJIN_NOEXCEPT;
|
||||
constexpr bool parseAuthority(string_view_t authority) MIJIN_NOEXCEPT;
|
||||
};
|
||||
|
||||
using URL = URLBase<char>;
|
||||
|
||||
template<typename TChar, typename TTraits, typename TAllocator>
|
||||
constexpr void URLBase<TChar, TTraits, TAllocator>::clear() noexcept
|
||||
constexpr void URLBase<TChar, TTraits, TAllocator>::clear() MIJIN_NOEXCEPT
|
||||
{
|
||||
base_.clear();
|
||||
scheme_ = {};
|
||||
@ -71,7 +73,7 @@ constexpr void URLBase<TChar, TTraits, TAllocator>::clear() noexcept
|
||||
}
|
||||
|
||||
template<typename TChar, typename TTraits, typename TAllocator>
|
||||
constexpr void URLBase<TChar, TTraits, TAllocator>::parse() noexcept
|
||||
constexpr void URLBase<TChar, TTraits, TAllocator>::parse() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (base_.empty())
|
||||
{
|
||||
@ -135,7 +137,7 @@ constexpr void URLBase<TChar, TTraits, TAllocator>::parse() noexcept
|
||||
}
|
||||
|
||||
template<typename TChar, typename TTraits, typename TAllocator>
|
||||
constexpr bool URLBase<TChar, TTraits, TAllocator>::parseAuthority(string_view_t authority) noexcept
|
||||
constexpr bool URLBase<TChar, TTraits, TAllocator>::parseAuthority(string_view_t authority) MIJIN_NOEXCEPT
|
||||
{
|
||||
string_view_t toParse = authority;
|
||||
typename string_view_t::size_type pos = toParse.find(TChar('@'));
|
||||
|
@ -9,6 +9,7 @@
|
||||
#if __has_include(<fmt/format.h>)
|
||||
# include <fmt/format.h>
|
||||
#endif
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
@ -37,8 +38,8 @@ public:
|
||||
|
||||
Name& operator=(const Name&) = default;
|
||||
auto operator<=>(const Name&) const = default;
|
||||
constexpr operator bool() const noexcept { return id_ != std::numeric_limits<std::size_t>::max(); }
|
||||
constexpr bool operator!() const noexcept { return !static_cast<bool>(*this); }
|
||||
constexpr operator bool() const MIJIN_NOEXCEPT { return id_ != std::numeric_limits<std::size_t>::max(); }
|
||||
constexpr bool operator!() const MIJIN_NOEXCEPT { return !static_cast<bool>(*this); }
|
||||
|
||||
[[nodiscard]] std::string_view stringView() const;
|
||||
[[nodiscard]] const char* c_str() const {
|
||||
@ -57,7 +58,7 @@ public:
|
||||
template<>
|
||||
struct std::hash<mijin::Name> : hash<std::size_t>
|
||||
{
|
||||
std::size_t operator()(mijin::Name name) const noexcept {
|
||||
std::size_t operator()(mijin::Name name) const MIJIN_NOEXCEPT {
|
||||
return hash<std::size_t>::operator()(name.getID());
|
||||
}
|
||||
};
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <string>
|
||||
#include <variant>
|
||||
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
|
||||
@ -30,32 +32,32 @@ private:
|
||||
|
||||
std::variant<Empty, TSuccess, TError> state_;
|
||||
public:
|
||||
ResultBase() = default;
|
||||
ResultBase(const ResultBase&) = default;
|
||||
ResultBase(ResultBase&&) = default;
|
||||
ResultBase(TSuccess successValue) noexcept : state_(std::move(successValue)) {}
|
||||
ResultBase(TError errorValue) noexcept : state_(std::move(errorValue)) {}
|
||||
ResultBase() MIJIN_NOEXCEPT = default;
|
||||
ResultBase(const ResultBase&) MIJIN_NOEXCEPT = default;
|
||||
ResultBase(ResultBase&&) MIJIN_NOEXCEPT = default;
|
||||
ResultBase(TSuccess successValue) MIJIN_NOEXCEPT : state_(std::move(successValue)) {}
|
||||
ResultBase(TError errorValue) MIJIN_NOEXCEPT : state_(std::move(errorValue)) {}
|
||||
|
||||
ResultBase& operator=(const ResultBase&) = default;
|
||||
ResultBase& operator=(ResultBase&&) = default;
|
||||
|
||||
bool operator==(const ResultBase& other) const noexcept { return state_ == other.state_; }
|
||||
bool operator!=(const ResultBase& other) const noexcept { return state_ != other.state_; }
|
||||
operator bool() const noexcept { return isSuccess(); }
|
||||
bool operator!() const noexcept { return !isSuccess(); }
|
||||
TSuccess& operator*() noexcept { return getValue(); }
|
||||
const TSuccess& operator*() const noexcept { return getValue(); }
|
||||
TSuccess* operator->() noexcept { return &getValue(); }
|
||||
const TSuccess* operator->() const noexcept { return &getValue(); }
|
||||
bool operator==(const ResultBase& other) const MIJIN_NOEXCEPT { return state_ == other.state_; }
|
||||
bool operator!=(const ResultBase& other) const MIJIN_NOEXCEPT { return state_ != other.state_; }
|
||||
operator bool() const MIJIN_NOEXCEPT { return isSuccess(); }
|
||||
bool operator!() const MIJIN_NOEXCEPT { return !isSuccess(); }
|
||||
TSuccess& operator*() MIJIN_NOEXCEPT { return getValue(); }
|
||||
const TSuccess& operator*() const MIJIN_NOEXCEPT { return getValue(); }
|
||||
TSuccess* operator->() MIJIN_NOEXCEPT { return &getValue(); }
|
||||
const TSuccess* operator->() const MIJIN_NOEXCEPT { return &getValue(); }
|
||||
|
||||
[[nodiscard]] bool isEmpty() const noexcept { return std::holds_alternative<Empty>(state_); }
|
||||
[[nodiscard]] bool isSuccess() const noexcept { return std::holds_alternative<TSuccess>(state_); }
|
||||
[[nodiscard]] bool isError() const noexcept { return std::holds_alternative<TError>(state_); }
|
||||
[[nodiscard]] bool isEmpty() const MIJIN_NOEXCEPT { return std::holds_alternative<Empty>(state_); }
|
||||
[[nodiscard]] bool isSuccess() const MIJIN_NOEXCEPT { return std::holds_alternative<TSuccess>(state_); }
|
||||
[[nodiscard]] bool isError() const MIJIN_NOEXCEPT { return std::holds_alternative<TError>(state_); }
|
||||
|
||||
[[nodiscard]] TSuccess& getValue() noexcept { return std::get<TSuccess>(state_); }
|
||||
[[nodiscard]] TError& getError() noexcept { return std::get<TError>(state_); }
|
||||
[[nodiscard]] const TSuccess& getValue() const noexcept { return std::get<TSuccess>(state_); }
|
||||
[[nodiscard]] const TError& getError() const noexcept { return std::get<TError>(state_); }
|
||||
[[nodiscard]] TSuccess& getValue() MIJIN_NOEXCEPT { return std::get<TSuccess>(state_); }
|
||||
[[nodiscard]] TError& getError() MIJIN_NOEXCEPT { return std::get<TError>(state_); }
|
||||
[[nodiscard]] const TSuccess& getValue() const MIJIN_NOEXCEPT { return std::get<TSuccess>(state_); }
|
||||
[[nodiscard]] const TError& getError() const MIJIN_NOEXCEPT { return std::get<TError>(state_); }
|
||||
};
|
||||
|
||||
struct ResultError
|
||||
@ -64,11 +66,11 @@ struct ResultError
|
||||
|
||||
ResultError() : message("Unknown error") {}
|
||||
ResultError(const ResultError&) = default;
|
||||
ResultError(ResultError&&) noexcept = default;
|
||||
ResultError(std::string msg) noexcept : message(std::move(msg)) {}
|
||||
ResultError(ResultError&&) MIJIN_NOEXCEPT = default;
|
||||
ResultError(std::string msg) MIJIN_NOEXCEPT : message(std::move(msg)) {}
|
||||
|
||||
ResultError& operator=(const ResultError&) = default;
|
||||
ResultError& operator=(ResultError&&) noexcept = default;
|
||||
ResultError& operator=(ResultError&&) MIJIN_NOEXCEPT = default;
|
||||
};
|
||||
|
||||
template<typename TSuccess>
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "../container/optional.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
#include "../util/traits.hpp"
|
||||
#include "../util/variant.hpp"
|
||||
|
||||
@ -73,14 +74,14 @@ public:
|
||||
private:
|
||||
base_t base_ = UndefinedValue();
|
||||
public:
|
||||
ScriptValue() noexcept = default;
|
||||
ScriptValue(const ScriptValue&) noexcept = default;
|
||||
ScriptValue(ScriptValue&&) noexcept = default;
|
||||
ScriptValue() MIJIN_NOEXCEPT = default;
|
||||
ScriptValue(const ScriptValue&) MIJIN_NOEXCEPT = default;
|
||||
ScriptValue(ScriptValue&&) MIJIN_NOEXCEPT = default;
|
||||
template<typename TValue>
|
||||
ScriptValue(TValue&& value);
|
||||
|
||||
ScriptValue& operator=(const ScriptValue&) = default;
|
||||
ScriptValue& operator=(ScriptValue&&) noexcept = default;
|
||||
ScriptValue& operator=(ScriptValue&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
std::partial_ordering operator<=>(const ScriptValue& other) const = default;
|
||||
|
||||
@ -91,7 +92,7 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Optional<script_int_t> toInt() const noexcept
|
||||
Optional<script_int_t> toInt() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return visit([&](auto&& value) -> Optional<script_int_t>
|
||||
{
|
||||
@ -118,7 +119,7 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Optional<script_float_t> toFloat() const noexcept
|
||||
Optional<script_float_t> toFloat() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return visit([&](auto&& value) -> Optional<script_float_t>
|
||||
{
|
||||
@ -145,7 +146,7 @@ public:
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
Optional<std::string> toString() const noexcept
|
||||
Optional<std::string> toString() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return visit([](auto&& value) -> Optional<std::string>
|
||||
{
|
||||
@ -175,7 +176,7 @@ public:
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]]
|
||||
Optional<std::decay_t<T>> to() const noexcept
|
||||
Optional<std::decay_t<T>> to() const MIJIN_NOEXCEPT
|
||||
{
|
||||
using type_t = std::decay_t<T>;
|
||||
if constexpr (std::is_same_v<type_t, script_int_t>)
|
||||
|
@ -5,6 +5,7 @@
|
||||
#define MIJIN_TYPES_TYPEDEF_HPP_INCLUDED 1
|
||||
|
||||
#include <utility>
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
@ -48,9 +49,9 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit constexpr operator const TBase&() const noexcept { return value; }
|
||||
explicit constexpr operator TBase&() noexcept { return value; }
|
||||
auto operator<=>(const TypeDef&) const noexcept = default;
|
||||
explicit constexpr operator const TBase&() const MIJIN_NOEXCEPT { return value; }
|
||||
explicit constexpr operator TBase&() MIJIN_NOEXCEPT { return value; }
|
||||
auto operator<=>(const TypeDef&) const MIJIN_NOEXCEPT = default;
|
||||
};
|
||||
|
||||
template<typename TBase, typename TTag> requires (!std::is_fundamental_v<TBase>)
|
||||
|
@ -4,10 +4,12 @@
|
||||
#if !defined(MIJIN_UTIL_ALIGN_HPP_INCLUDED)
|
||||
#define MIJIN_UTIL_ALIGN_HPP_INCLUDED 1
|
||||
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
template<typename T>
|
||||
constexpr T alignUp(T value, T alignTo) noexcept
|
||||
constexpr T alignUp(T value, T alignTo) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (value % alignTo != 0)
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <cstdint>
|
||||
#include "./traits.hpp"
|
||||
#include "./types.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
@ -15,23 +16,23 @@ namespace mijin
|
||||
// public defines
|
||||
//
|
||||
|
||||
#define MIJIN_DEFINE_FLAG(name) \
|
||||
struct name : mijin::Flag \
|
||||
{ \
|
||||
private: \
|
||||
struct Proxy_ { \
|
||||
uint8_t value; \
|
||||
}; \
|
||||
public: \
|
||||
constexpr name() = default; \
|
||||
constexpr name(const name&) = default; \
|
||||
constexpr name(Proxy_ proxy) \
|
||||
: Flag(proxy.value) {} \
|
||||
constexpr explicit name(bool value) noexcept \
|
||||
: Flag(value) {} \
|
||||
name& operator=(const name&) = default; \
|
||||
static constexpr Proxy_ YES{1}; \
|
||||
static constexpr Proxy_ NO{0}; \
|
||||
#define MIJIN_DEFINE_FLAG(name) \
|
||||
struct name : mijin::Flag \
|
||||
{ \
|
||||
private: \
|
||||
struct Proxy_ { \
|
||||
uint8_t value; \
|
||||
}; \
|
||||
public: \
|
||||
constexpr name() = default; \
|
||||
constexpr name(const name&) = default; \
|
||||
constexpr name(Proxy_ proxy) MIJIN_NOEXCEPT \
|
||||
: Flag(proxy.value) {} \
|
||||
constexpr explicit name(bool value) MIJIN_NOEXCEPT \
|
||||
: Flag(value) {} \
|
||||
name& operator=(const name&) = default; \
|
||||
static constexpr Proxy_ YES{1}; \
|
||||
static constexpr Proxy_ NO{0}; \
|
||||
}
|
||||
|
||||
//
|
||||
@ -48,23 +49,23 @@ struct Flag
|
||||
|
||||
Flag() = default;
|
||||
Flag(const Flag&) = default;
|
||||
explicit constexpr Flag(uint8_t value) noexcept : value(value) {}
|
||||
explicit constexpr Flag(uint8_t value) MIJIN_NOEXCEPT : value(value) {}
|
||||
|
||||
Flag& operator=(const Flag&) = default;
|
||||
|
||||
constexpr bool operator ==(const Flag& other) const noexcept
|
||||
constexpr bool operator ==(const Flag& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return value == other.value;
|
||||
}
|
||||
constexpr bool operator !=(const Flag& other) const noexcept
|
||||
constexpr bool operator !=(const Flag& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return value != other.value;
|
||||
}
|
||||
constexpr bool operator !() const noexcept
|
||||
constexpr bool operator !() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return !value;
|
||||
}
|
||||
constexpr operator bool() const noexcept
|
||||
constexpr operator bool() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return value != 0;
|
||||
}
|
||||
@ -89,7 +90,7 @@ private:
|
||||
using base_t = FlagSetStorage<offset + 1, TMore...>;
|
||||
static constexpr typename base_t::data_t BIT = (1 << offset);
|
||||
public:
|
||||
constexpr void set(TFirst value) noexcept
|
||||
constexpr void set(TFirst value) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
@ -100,7 +101,7 @@ public:
|
||||
base_t::data_ &= ~BIT;
|
||||
}
|
||||
}
|
||||
constexpr bool get(TFirst) noexcept
|
||||
constexpr bool get(TFirst) MIJIN_NOEXCEPT
|
||||
{
|
||||
return (base_t::data_ & BIT) != 0;
|
||||
}
|
||||
@ -134,19 +135,19 @@ public:
|
||||
public:
|
||||
FlagSet& operator=(const FlagSet&) = default;
|
||||
template<FlagType T> requires is_any_type_v<T, TFlags...>
|
||||
FlagSet& operator=(T flag) noexcept
|
||||
FlagSet& operator=(T flag) MIJIN_NOEXCEPT
|
||||
{
|
||||
reset(flag);
|
||||
return *this;
|
||||
}
|
||||
template<FlagType T> requires is_any_type_v<T, TFlags...>
|
||||
FlagSet& operator|=(T flag) noexcept
|
||||
FlagSet& operator|=(T flag) MIJIN_NOEXCEPT
|
||||
{
|
||||
set(flag);
|
||||
return *this;
|
||||
}
|
||||
template<FlagType T> requires is_any_type_v<T, TFlags...>
|
||||
FlagSet& operator&=(T flag) noexcept
|
||||
FlagSet& operator&=(T flag) MIJIN_NOEXCEPT
|
||||
{
|
||||
unset(flag);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <tuple>
|
||||
#include <variant>
|
||||
#include "../container/optional.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
@ -96,50 +97,50 @@ struct EnumeratingIterator
|
||||
TIdx idx;
|
||||
TIterator base;
|
||||
|
||||
EnumeratingIterator(TIdx idx_, TIterator base_) noexcept : idx(idx_), base(base_) {}
|
||||
EnumeratingIterator(const EnumeratingIterator&) noexcept = default;
|
||||
EnumeratingIterator(TIdx idx_, TIterator base_) MIJIN_NOEXCEPT : idx(idx_), base(base_) {}
|
||||
EnumeratingIterator(const EnumeratingIterator&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
EnumeratingIterator& operator=(const EnumeratingIterator&) noexcept = default;
|
||||
EnumeratingIterator& operator=(const EnumeratingIterator&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
auto operator*() const noexcept
|
||||
auto operator*() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return std::tie(idx, *base);
|
||||
}
|
||||
|
||||
EnumeratingIterator& operator++() noexcept
|
||||
EnumeratingIterator& operator++() MIJIN_NOEXCEPT
|
||||
{
|
||||
++idx;
|
||||
++base;
|
||||
return *this;
|
||||
}
|
||||
|
||||
EnumeratingIterator operator++(int) noexcept
|
||||
EnumeratingIterator operator++(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
EnumeratingIterator copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
EnumeratingIterator& operator--() noexcept
|
||||
EnumeratingIterator& operator--() MIJIN_NOEXCEPT
|
||||
{
|
||||
--idx;
|
||||
--base;
|
||||
return *this;
|
||||
}
|
||||
|
||||
EnumeratingIterator operator--(int) noexcept
|
||||
EnumeratingIterator operator--(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
EnumeratingIterator copy(*this);
|
||||
--(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool operator==(const EnumeratingIterator& other) const noexcept
|
||||
bool operator==(const EnumeratingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return base == other.base; // note: ignoring idx so we don't have to find it out for end()
|
||||
}
|
||||
|
||||
bool operator!=(const EnumeratingIterator& other) const noexcept
|
||||
bool operator!=(const EnumeratingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return base != other.base; // note: ignoring idx so we don't have to find it out for end()
|
||||
}
|
||||
@ -152,12 +153,12 @@ struct Enumeratable : RangeAdapter
|
||||
{
|
||||
RangeRef<TIterable> base;
|
||||
|
||||
auto begin() const noexcept
|
||||
auto begin() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return EnumeratingIterator(TIdx(0), base.begin());
|
||||
}
|
||||
|
||||
auto end() const noexcept
|
||||
auto end() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return EnumeratingIterator(TIdx(0), base.end());
|
||||
}
|
||||
@ -175,50 +176,50 @@ struct ZippingIterator
|
||||
TFirstIterator first;
|
||||
TSecondIterator second;
|
||||
|
||||
ZippingIterator(TFirstIterator first_, TSecondIterator second_) noexcept : first(first_), second(second_) {}
|
||||
ZippingIterator(const ZippingIterator&) noexcept = default;
|
||||
ZippingIterator(TFirstIterator first_, TSecondIterator second_) MIJIN_NOEXCEPT : first(first_), second(second_) {}
|
||||
ZippingIterator(const ZippingIterator&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
ZippingIterator& operator=(const ZippingIterator&) noexcept = default;
|
||||
ZippingIterator& operator=(const ZippingIterator&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
decltype(auto) operator*() const noexcept
|
||||
decltype(auto) operator*() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return std::tie(*first, *second);
|
||||
}
|
||||
|
||||
ZippingIterator& operator++() noexcept
|
||||
ZippingIterator& operator++() MIJIN_NOEXCEPT
|
||||
{
|
||||
++first;
|
||||
++second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZippingIterator operator++(int) noexcept
|
||||
ZippingIterator operator++(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
ZippingIterator copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
ZippingIterator& operator--() noexcept
|
||||
ZippingIterator& operator--() MIJIN_NOEXCEPT
|
||||
{
|
||||
--first;
|
||||
--second;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ZippingIterator operator--(int) noexcept
|
||||
ZippingIterator operator--(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
ZippingIterator copy(*this);
|
||||
--(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool operator==(const ZippingIterator& other) const noexcept
|
||||
bool operator==(const ZippingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return first == other.first || second == other.second; // note: this uses or so reaching the end on one range also ends the zipped one.
|
||||
}
|
||||
|
||||
bool operator!=(const ZippingIterator& other) const noexcept
|
||||
bool operator!=(const ZippingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
@ -232,12 +233,12 @@ struct ZippingRange : RangeAdapter
|
||||
RangeRef<TFirst> first;
|
||||
RangeRef<TSecond> second;
|
||||
|
||||
auto begin() const noexcept
|
||||
auto begin() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return ZippingIterator(first.begin(), second.begin());
|
||||
}
|
||||
|
||||
auto end() const noexcept
|
||||
auto end() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return ZippingIterator(first.end(), second.end());
|
||||
}
|
||||
@ -262,12 +263,12 @@ struct ReplacingIterator
|
||||
value_type what;
|
||||
value_type with;
|
||||
|
||||
ReplacingIterator(TIterator base_, value_type what_, value_type with_) noexcept : base(base_), what(what_), with(with_) {}
|
||||
ReplacingIterator(const ReplacingIterator&) noexcept = default;
|
||||
ReplacingIterator(TIterator base_, value_type what_, value_type with_) MIJIN_NOEXCEPT : base(base_), what(what_), with(with_) {}
|
||||
ReplacingIterator(const ReplacingIterator&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
ReplacingIterator& operator=(const ReplacingIterator&) noexcept = default;
|
||||
ReplacingIterator& operator=(const ReplacingIterator&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
pointer operator->() const noexcept
|
||||
pointer operator->() const MIJIN_NOEXCEPT
|
||||
{
|
||||
if (*base == what) {
|
||||
return &with;
|
||||
@ -275,7 +276,7 @@ struct ReplacingIterator
|
||||
return &*base;
|
||||
}
|
||||
|
||||
reference operator*() const noexcept
|
||||
reference operator*() const MIJIN_NOEXCEPT
|
||||
{
|
||||
if (*base == what) {
|
||||
return with;
|
||||
@ -283,38 +284,38 @@ struct ReplacingIterator
|
||||
return *base;
|
||||
}
|
||||
|
||||
ReplacingIterator& operator++() noexcept
|
||||
ReplacingIterator& operator++() MIJIN_NOEXCEPT
|
||||
{
|
||||
++base;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ReplacingIterator operator++(int) noexcept
|
||||
ReplacingIterator operator++(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
ReplacingIterator copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
ReplacingIterator& operator--() noexcept
|
||||
ReplacingIterator& operator--() MIJIN_NOEXCEPT
|
||||
{
|
||||
--base;
|
||||
return *this;
|
||||
}
|
||||
|
||||
ReplacingIterator operator--(int) noexcept
|
||||
ReplacingIterator operator--(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
ReplacingIterator copy(*this);
|
||||
--(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool operator==(const ReplacingIterator& other) const noexcept
|
||||
bool operator==(const ReplacingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return what == other.what && with == other.with && base == other.base;
|
||||
}
|
||||
|
||||
bool operator!=(const ReplacingIterator& other) const noexcept
|
||||
bool operator!=(const ReplacingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
@ -329,12 +330,12 @@ struct ReplacingRange : RangeAdapter
|
||||
value_type what;
|
||||
value_type with;
|
||||
|
||||
auto begin() const noexcept
|
||||
auto begin() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return ReplacingIterator(base.begin(), what, with);
|
||||
}
|
||||
|
||||
auto end() const noexcept
|
||||
auto end() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return ReplacingIterator(base.end(), what, with);
|
||||
}
|
||||
@ -368,14 +369,14 @@ struct MappingIterator
|
||||
TFunctor functor;
|
||||
mutable Optional<value_type> result;
|
||||
|
||||
MappingIterator(TIterator base_, TFunctor functor_) noexcept : base(base_), functor(std::move(functor_)) {}
|
||||
MappingIterator(const MappingIterator&) noexcept = default;
|
||||
MappingIterator(MappingIterator&&) noexcept = default;
|
||||
MappingIterator(TIterator base_, TFunctor functor_) MIJIN_NOEXCEPT : base(base_), functor(std::move(functor_)) {}
|
||||
MappingIterator(const MappingIterator&) MIJIN_NOEXCEPT = default;
|
||||
MappingIterator(MappingIterator&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
MappingIterator& operator=(const MappingIterator&) noexcept = default;
|
||||
MappingIterator& operator=(MappingIterator&&) noexcept = default;
|
||||
MappingIterator& operator=(const MappingIterator&) MIJIN_NOEXCEPT = default;
|
||||
MappingIterator& operator=(MappingIterator&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
reference operator*() const noexcept
|
||||
reference operator*() const MIJIN_NOEXCEPT
|
||||
{
|
||||
if (result.empty()) {
|
||||
result = std::invoke(functor, *base);
|
||||
@ -383,40 +384,40 @@ struct MappingIterator
|
||||
return *result;
|
||||
}
|
||||
|
||||
MappingIterator& operator++() noexcept
|
||||
MappingIterator& operator++() MIJIN_NOEXCEPT
|
||||
{
|
||||
++base;
|
||||
result.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
MappingIterator operator++(int) noexcept
|
||||
MappingIterator operator++(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
MappingIterator copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
MappingIterator& operator--() noexcept
|
||||
MappingIterator& operator--() MIJIN_NOEXCEPT
|
||||
{
|
||||
--base;
|
||||
result.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
MappingIterator operator--(int) noexcept
|
||||
MappingIterator operator--(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
MappingIterator copy(*this);
|
||||
--(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool operator==(const MappingIterator& other) const noexcept
|
||||
bool operator==(const MappingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return base == other.base; // TODO: compare functor? -> doesn't always work and may be useless
|
||||
}
|
||||
|
||||
bool operator!=(const MappingIterator& other) const noexcept
|
||||
bool operator!=(const MappingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
@ -431,17 +432,17 @@ struct MappingRange : RangeAdapter
|
||||
RangeRef<TIterable> base;
|
||||
TFunctor functor;
|
||||
|
||||
auto begin() const noexcept
|
||||
auto begin() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return MappingIterator(base.begin(), functor);
|
||||
}
|
||||
|
||||
auto end() const noexcept
|
||||
auto end() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return MappingIterator(base.end(), functor);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool empty() const noexcept {
|
||||
[[nodiscard]] bool empty() const MIJIN_NOEXCEPT {
|
||||
return base.begin() == base.end();
|
||||
}
|
||||
};
|
||||
@ -472,7 +473,7 @@ struct OptionalMappingIterator
|
||||
TFunctor functor;
|
||||
mutable optional_type result; // must be mutable so dereferencing can stay const, not nice :/
|
||||
|
||||
OptionalMappingIterator(TIterator base_, TIterator end_, TFunctor functor_) noexcept : base(base_), end(end_), functor(std::move(functor_)) {
|
||||
OptionalMappingIterator(TIterator base_, TIterator end_, TFunctor functor_) MIJIN_NOEXCEPT : base(base_), end(end_), functor(std::move(functor_)) {
|
||||
if (base != end)
|
||||
{
|
||||
result = functor(*base);
|
||||
@ -481,18 +482,18 @@ struct OptionalMappingIterator
|
||||
}
|
||||
}
|
||||
}
|
||||
OptionalMappingIterator(const OptionalMappingIterator&) noexcept = default;
|
||||
OptionalMappingIterator(OptionalMappingIterator&&) noexcept = default;
|
||||
OptionalMappingIterator(const OptionalMappingIterator&) MIJIN_NOEXCEPT = default;
|
||||
OptionalMappingIterator(OptionalMappingIterator&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
OptionalMappingIterator& operator=(const OptionalMappingIterator&) noexcept = default;
|
||||
OptionalMappingIterator& operator=(OptionalMappingIterator&&) noexcept = default;
|
||||
OptionalMappingIterator& operator=(const OptionalMappingIterator&) MIJIN_NOEXCEPT = default;
|
||||
OptionalMappingIterator& operator=(OptionalMappingIterator&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
reference operator*() const noexcept
|
||||
reference operator*() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return *result;
|
||||
}
|
||||
|
||||
OptionalMappingIterator& operator++() noexcept
|
||||
OptionalMappingIterator& operator++() MIJIN_NOEXCEPT
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -502,19 +503,19 @@ struct OptionalMappingIterator
|
||||
return *this;
|
||||
}
|
||||
|
||||
OptionalMappingIterator operator++(int) noexcept
|
||||
OptionalMappingIterator operator++(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
OptionalMappingIterator copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool operator==(const OptionalMappingIterator& other) const noexcept
|
||||
bool operator==(const OptionalMappingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return base == other.base && end == other.end; // TODO: compare functor? -> doesn't always work and may be useless
|
||||
}
|
||||
|
||||
bool operator!=(const OptionalMappingIterator& other) const noexcept
|
||||
bool operator!=(const OptionalMappingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
@ -529,12 +530,12 @@ struct OptionalMappingRange : RangeAdapter
|
||||
RangeRef<TIterable> base;
|
||||
TFunctor functor;
|
||||
|
||||
auto begin() const noexcept
|
||||
auto begin() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return OptionalMappingIterator(base.begin(), base.end(), functor);
|
||||
}
|
||||
|
||||
auto end() const noexcept
|
||||
auto end() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return OptionalMappingIterator(base.end(), base.end(), functor);
|
||||
}
|
||||
@ -561,23 +562,23 @@ struct FilteringIterator
|
||||
TIterator end;
|
||||
TPredicate predicate;
|
||||
|
||||
FilteringIterator(TIterator base_, TIterator end_, TPredicate predicate_) noexcept : base(base_), end(end_), predicate(std::move(predicate_)) {
|
||||
FilteringIterator(TIterator base_, TIterator end_, TPredicate predicate_) MIJIN_NOEXCEPT : base(base_), end(end_), predicate(std::move(predicate_)) {
|
||||
if (base != end && !predicate(*base)) {
|
||||
++(*this);
|
||||
}
|
||||
}
|
||||
FilteringIterator(const FilteringIterator&) noexcept = default;
|
||||
FilteringIterator(FilteringIterator&&) noexcept = default;
|
||||
FilteringIterator(const FilteringIterator&) MIJIN_NOEXCEPT = default;
|
||||
FilteringIterator(FilteringIterator&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
FilteringIterator& operator=(const FilteringIterator&) noexcept = default;
|
||||
FilteringIterator& operator=(FilteringIterator&&) noexcept = default;
|
||||
FilteringIterator& operator=(const FilteringIterator&) MIJIN_NOEXCEPT = default;
|
||||
FilteringIterator& operator=(FilteringIterator&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
reference operator*() const noexcept
|
||||
reference operator*() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return *base;
|
||||
}
|
||||
|
||||
FilteringIterator& operator++() noexcept
|
||||
FilteringIterator& operator++() MIJIN_NOEXCEPT
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -586,19 +587,19 @@ struct FilteringIterator
|
||||
return *this;
|
||||
}
|
||||
|
||||
FilteringIterator operator++(int) noexcept
|
||||
FilteringIterator operator++(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
FilteringIterator copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool operator==(const FilteringIterator& other) const noexcept
|
||||
bool operator==(const FilteringIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return base == other.base && end == other.end; // TODO: compare predicate?
|
||||
}
|
||||
|
||||
bool operator!=(const FilteringIterator& other) const noexcept
|
||||
bool operator!=(const FilteringIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
@ -613,12 +614,12 @@ struct FilteringRange : RangeAdapter
|
||||
RangeRef<TIterable> base;
|
||||
TPredicate predicate;
|
||||
|
||||
auto begin() const noexcept
|
||||
auto begin() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return FilteringIterator(base.begin(), base.end(), predicate);
|
||||
}
|
||||
|
||||
auto end() const noexcept
|
||||
auto end() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return FilteringIterator(base.end(), base.end(), predicate);
|
||||
}
|
||||
@ -647,13 +648,13 @@ struct ChainingIterator
|
||||
TSecondIterator secondBase;
|
||||
TSecondIterator secondBegin;
|
||||
|
||||
ChainingIterator(TFirstIterator firstBase_, TFirstIterator firstEnd_, TSecondIterator secondBase_, TSecondIterator secondBegin_) noexcept
|
||||
ChainingIterator(TFirstIterator firstBase_, TFirstIterator firstEnd_, TSecondIterator secondBase_, TSecondIterator secondBegin_) MIJIN_NOEXCEPT
|
||||
: firstBase(firstBase_), firstEnd(firstEnd_), secondBase(secondBase_), secondBegin(secondBegin_) {}
|
||||
ChainingIterator(const ChainingIterator&) noexcept = default;
|
||||
ChainingIterator(const ChainingIterator&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
ChainingIterator& operator=(const ChainingIterator&) noexcept = default;
|
||||
ChainingIterator& operator=(const ChainingIterator&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
pointer operator->() const noexcept
|
||||
pointer operator->() const MIJIN_NOEXCEPT
|
||||
{
|
||||
if (firstBase == firstEnd)
|
||||
{
|
||||
@ -662,7 +663,7 @@ struct ChainingIterator
|
||||
return &*firstBase;
|
||||
}
|
||||
|
||||
reference operator*() const noexcept
|
||||
reference operator*() const MIJIN_NOEXCEPT
|
||||
{
|
||||
if (firstBase == firstEnd)
|
||||
{
|
||||
@ -671,7 +672,7 @@ struct ChainingIterator
|
||||
return *firstBase;
|
||||
}
|
||||
|
||||
ChainingIterator& operator++() noexcept
|
||||
ChainingIterator& operator++() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (firstBase == firstEnd) {
|
||||
++secondBase;
|
||||
@ -682,14 +683,14 @@ struct ChainingIterator
|
||||
return *this;
|
||||
}
|
||||
|
||||
ChainingIterator operator++(int) noexcept
|
||||
ChainingIterator operator++(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
ChainingIterator copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
ChainingIterator& operator--() noexcept
|
||||
ChainingIterator& operator--() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (secondBase == secondBegin) {
|
||||
--firstBase;
|
||||
@ -700,19 +701,19 @@ struct ChainingIterator
|
||||
return *this;
|
||||
}
|
||||
|
||||
ChainingIterator operator--(int) noexcept
|
||||
ChainingIterator operator--(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
ChainingIterator copy(*this);
|
||||
--(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool operator==(const ChainingIterator& other) const noexcept
|
||||
bool operator==(const ChainingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return firstBase == other.firstBase && secondBase == other.secondBase; // should be enough
|
||||
}
|
||||
|
||||
bool operator!=(const ChainingIterator& other) const noexcept
|
||||
bool operator!=(const ChainingIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
@ -726,12 +727,12 @@ struct ChainedRange : RangeAdapter
|
||||
RangeRef<TFirstRange> first;
|
||||
RangeRef<TSecondRange> second;
|
||||
|
||||
auto begin() const noexcept
|
||||
auto begin() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return ChainingIterator(first.begin(), first.end(), second.begin(), second.begin());
|
||||
}
|
||||
|
||||
auto end() const noexcept
|
||||
auto end() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return ChainingIterator(first.end(), first.end(), second.end(), second.begin());
|
||||
}
|
||||
@ -764,23 +765,23 @@ struct TypeFilteringIterator
|
||||
TIterator base;
|
||||
TIterator end;
|
||||
|
||||
TypeFilteringIterator(TIterator base_, TIterator end_) noexcept : base(base_), end(end_) {
|
||||
TypeFilteringIterator(TIterator base_, TIterator end_) MIJIN_NOEXCEPT : base(base_), end(end_) {
|
||||
if (base != end && !isCastable()) {
|
||||
++(*this);
|
||||
}
|
||||
}
|
||||
TypeFilteringIterator(const TypeFilteringIterator&) noexcept = default;
|
||||
TypeFilteringIterator(TypeFilteringIterator&&) noexcept = default;
|
||||
TypeFilteringIterator(const TypeFilteringIterator&) MIJIN_NOEXCEPT = default;
|
||||
TypeFilteringIterator(TypeFilteringIterator&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
TypeFilteringIterator& operator=(const TypeFilteringIterator&) noexcept = default;
|
||||
TypeFilteringIterator& operator=(TypeFilteringIterator&&) noexcept = default;
|
||||
TypeFilteringIterator& operator=(const TypeFilteringIterator&) MIJIN_NOEXCEPT = default;
|
||||
TypeFilteringIterator& operator=(TypeFilteringIterator&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
reference operator*() const noexcept
|
||||
reference operator*() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return static_cast<reference>(*base);
|
||||
}
|
||||
|
||||
TypeFilteringIterator& operator++() noexcept
|
||||
TypeFilteringIterator& operator++() MIJIN_NOEXCEPT
|
||||
{
|
||||
do
|
||||
{
|
||||
@ -789,19 +790,19 @@ struct TypeFilteringIterator
|
||||
return *this;
|
||||
}
|
||||
|
||||
TypeFilteringIterator operator++(int) noexcept
|
||||
TypeFilteringIterator operator++(int) MIJIN_NOEXCEPT
|
||||
{
|
||||
FilteringIterator copy(*this);
|
||||
++(*this);
|
||||
return copy;
|
||||
}
|
||||
|
||||
bool operator==(const TypeFilteringIterator& other) const noexcept
|
||||
bool operator==(const TypeFilteringIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return base == other.base && end == other.end;
|
||||
}
|
||||
|
||||
bool operator!=(const TypeFilteringIterator& other) const noexcept
|
||||
bool operator!=(const TypeFilteringIterator& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
@ -827,12 +828,12 @@ struct TypeFilteringRange : RangeAdapter
|
||||
|
||||
RangeRef<TIterable> iterable;
|
||||
|
||||
auto begin() const noexcept
|
||||
auto begin() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return TypeFilteringIterator<TType, decltype(iterable.begin())>(iterable.begin(), iterable.end());
|
||||
}
|
||||
|
||||
auto end() const noexcept
|
||||
auto end() const MIJIN_NOEXCEPT
|
||||
{
|
||||
return TypeFilteringIterator<TType, decltype(iterable.begin())>(iterable.end(), iterable.end());
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ std::mutex gDlErrorMutex; // dlerror may not be thread-safe
|
||||
// public functions
|
||||
//
|
||||
|
||||
Result<LibraryHandle> openSharedLibrary(std::string_view libraryFile) noexcept
|
||||
Result<LibraryHandle> openSharedLibrary(std::string_view libraryFile) MIJIN_NOEXCEPT
|
||||
{
|
||||
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
||||
const std::unique_lock dlErrorLock(gDlErrorMutex);
|
||||
@ -67,7 +67,7 @@ Result<LibraryHandle> openSharedLibrary(std::string_view libraryFile) noexcept
|
||||
#endif
|
||||
}
|
||||
|
||||
bool closeSharedLibrary(const LibraryHandle library) noexcept
|
||||
bool closeSharedLibrary(const LibraryHandle library) MIJIN_NOEXCEPT
|
||||
{
|
||||
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
||||
return dlclose(library.data) == 0;
|
||||
@ -77,7 +77,7 @@ bool closeSharedLibrary(const LibraryHandle library) noexcept
|
||||
#endif
|
||||
}
|
||||
|
||||
void* loadSymbolFromLibrary(const LibraryHandle library, const char* symbolName) noexcept
|
||||
void* loadSymbolFromLibrary(const LibraryHandle library, const char* symbolName) MIJIN_NOEXCEPT
|
||||
{
|
||||
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
||||
return dlsym(library.data, symbolName);
|
||||
@ -88,7 +88,7 @@ void* loadSymbolFromLibrary(const LibraryHandle library, const char* symbolName)
|
||||
#endif
|
||||
}
|
||||
|
||||
void setCurrentThreadName(const char* threadName) noexcept
|
||||
void setCurrentThreadName(const char* threadName) MIJIN_NOEXCEPT
|
||||
{
|
||||
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
||||
pthread_setname_np(pthread_self(), threadName);
|
||||
@ -97,7 +97,7 @@ void setCurrentThreadName(const char* threadName) noexcept
|
||||
#endif
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string makeLibraryFilename(std::string_view libraryName) noexcept
|
||||
[[nodiscard]] std::string makeLibraryFilename(std::string_view libraryName) MIJIN_NOEXCEPT
|
||||
{
|
||||
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX
|
||||
return "lib" + std::string(libraryName) + ".so";
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include "../detect.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
#include "../types/result.hpp"
|
||||
|
||||
namespace mijin
|
||||
@ -39,8 +40,8 @@ struct LibraryHandle
|
||||
{
|
||||
void* data = nullptr;
|
||||
|
||||
constexpr operator bool() const noexcept { return data != nullptr; }
|
||||
constexpr bool operator!() const noexcept { return data == nullptr; }
|
||||
constexpr operator bool() const MIJIN_NOEXCEPT { return data != nullptr; }
|
||||
constexpr bool operator!() const MIJIN_NOEXCEPT { return data == nullptr; }
|
||||
};
|
||||
|
||||
class SharedLibrary
|
||||
@ -48,43 +49,43 @@ class SharedLibrary
|
||||
private:
|
||||
LibraryHandle mHandle;
|
||||
public:
|
||||
SharedLibrary() noexcept = default;
|
||||
SharedLibrary() MIJIN_NOEXCEPT = default;
|
||||
SharedLibrary(const SharedLibrary&) = delete;
|
||||
SharedLibrary(SharedLibrary&& other) noexcept : mHandle(std::exchange(other.mHandle, {})) {}
|
||||
inline ~SharedLibrary() noexcept;
|
||||
SharedLibrary(SharedLibrary&& other) MIJIN_NOEXCEPT : mHandle(std::exchange(other.mHandle, {})) {}
|
||||
inline ~SharedLibrary() MIJIN_NOEXCEPT;
|
||||
|
||||
SharedLibrary& operator=(const SharedLibrary&) = delete;
|
||||
SharedLibrary& operator=(SharedLibrary&& other) noexcept
|
||||
SharedLibrary& operator=(SharedLibrary&& other) MIJIN_NOEXCEPT
|
||||
{
|
||||
mHandle = std::exchange(other.mHandle, {});
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr operator bool() const noexcept { return static_cast<bool>(mHandle); }
|
||||
constexpr bool operator!() const noexcept { return !mHandle; }
|
||||
constexpr operator bool() const MIJIN_NOEXCEPT { return static_cast<bool>(mHandle); }
|
||||
constexpr bool operator!() const MIJIN_NOEXCEPT { return !mHandle; }
|
||||
|
||||
[[nodiscard]] inline Result<bool> open(std::string_view libraryFile) noexcept;
|
||||
inline bool close() noexcept;
|
||||
[[nodiscard]] inline void* loadSymbol(const char* symbolName) noexcept;
|
||||
[[nodiscard]] inline Result<bool> open(std::string_view libraryFile) MIJIN_NOEXCEPT;
|
||||
inline bool close() MIJIN_NOEXCEPT;
|
||||
[[nodiscard]] inline void* loadSymbol(const char* symbolName) MIJIN_NOEXCEPT;
|
||||
};
|
||||
|
||||
//
|
||||
// public functions
|
||||
//
|
||||
|
||||
[[nodiscard]] Result<LibraryHandle> openSharedLibrary(std::string_view libraryFile) noexcept;
|
||||
bool closeSharedLibrary(const LibraryHandle library) noexcept;
|
||||
[[nodiscard]] void* loadSymbolFromLibrary(const LibraryHandle library, const char* symbolName) noexcept;
|
||||
void setCurrentThreadName(const char* threadName) noexcept;
|
||||
[[nodiscard]] Result<LibraryHandle> openSharedLibrary(std::string_view libraryFile) MIJIN_NOEXCEPT;
|
||||
bool closeSharedLibrary(const LibraryHandle library) MIJIN_NOEXCEPT;
|
||||
[[nodiscard]] void* loadSymbolFromLibrary(const LibraryHandle library, const char* symbolName) MIJIN_NOEXCEPT;
|
||||
void setCurrentThreadName(const char* threadName) MIJIN_NOEXCEPT;
|
||||
|
||||
[[nodiscard]] std::string makeLibraryFilename(std::string_view libraryName) noexcept;
|
||||
[[nodiscard]] std::string makeLibraryFilename(std::string_view libraryName) MIJIN_NOEXCEPT;
|
||||
|
||||
SharedLibrary::~SharedLibrary() noexcept
|
||||
SharedLibrary::~SharedLibrary() MIJIN_NOEXCEPT
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
Result<bool> SharedLibrary::open(std::string_view libraryFile) noexcept
|
||||
Result<bool> SharedLibrary::open(std::string_view libraryFile) MIJIN_NOEXCEPT
|
||||
{
|
||||
close();
|
||||
Result<LibraryHandle> openResult = openSharedLibrary(libraryFile);
|
||||
@ -96,7 +97,7 @@ Result<bool> SharedLibrary::open(std::string_view libraryFile) noexcept
|
||||
return ResultError(openResult.getError());
|
||||
}
|
||||
|
||||
bool SharedLibrary::close() noexcept
|
||||
bool SharedLibrary::close() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (mHandle)
|
||||
{
|
||||
@ -105,7 +106,7 @@ bool SharedLibrary::close() noexcept
|
||||
return false;
|
||||
}
|
||||
|
||||
void* SharedLibrary::loadSymbol(const char* symbolName) noexcept
|
||||
void* SharedLibrary::loadSymbol(const char* symbolName) MIJIN_NOEXCEPT
|
||||
{
|
||||
return loadSymbolFromLibrary(mHandle, symbolName);
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include "../debug/assert.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
@ -27,7 +28,7 @@ public:
|
||||
using get_t = TGet;
|
||||
using set_t = TSet;
|
||||
|
||||
virtual ~PropertyStorage() noexcept = default;
|
||||
virtual ~PropertyStorage() MIJIN_NOEXCEPT = default;
|
||||
|
||||
[[nodiscard]] virtual TGet getValue() = 0;
|
||||
virtual void setValue(TSet value) = 0;
|
||||
@ -39,15 +40,15 @@ class SimplePropertyStorage : public PropertyStorage<T>
|
||||
private:
|
||||
T value_;
|
||||
public:
|
||||
SimplePropertyStorage() noexcept = default;
|
||||
SimplePropertyStorage(const SimplePropertyStorage& other) noexcept(noexcept(T(other.value_))) = default;
|
||||
SimplePropertyStorage(SimplePropertyStorage&& other) noexcept(noexcept(T(std::move(other.value_)))) = default;
|
||||
explicit SimplePropertyStorage(T value) noexcept(noexcept(T(std::move(value)))) : value_(std::move(value)) {}
|
||||
SimplePropertyStorage() MIJIN_NOEXCEPT = default;
|
||||
SimplePropertyStorage(const SimplePropertyStorage& other) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(T(other.value_))) = default;
|
||||
SimplePropertyStorage(SimplePropertyStorage&& other) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(T(std::move(other.value_)))) = default;
|
||||
explicit SimplePropertyStorage(T value) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(T(std::move(value)))) : value_(std::move(value)) {}
|
||||
|
||||
SimplePropertyStorage& operator=(const SimplePropertyStorage& other) noexcept(noexcept(value_ = other.value_)) = default;
|
||||
SimplePropertyStorage& operator=(SimplePropertyStorage&& other) noexcept(noexcept(value_ = std::move(other.value_))) = default;
|
||||
SimplePropertyStorage& operator=(const SimplePropertyStorage& other) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(value_ = other.value_)) = default;
|
||||
SimplePropertyStorage& operator=(SimplePropertyStorage&& other) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(value_ = std::move(other.value_))) = default;
|
||||
|
||||
const T& getValue() noexcept override { return value_; }
|
||||
const T& getValue() MIJIN_NOEXCEPT override { return value_; }
|
||||
void setValue(T value) override { value_ = std::move(value); }
|
||||
};
|
||||
|
||||
@ -65,30 +66,30 @@ public:
|
||||
private:
|
||||
Property* base_;
|
||||
public:
|
||||
explicit PropertyProxy(Property* base) noexcept : base_(base) {}
|
||||
explicit PropertyProxy(Property* base) MIJIN_NOEXCEPT : base_(base) {}
|
||||
|
||||
operator TGet() noexcept { return base_->get(); }
|
||||
PropertyProxy& operator=(TSet value) noexcept(noexcept(std::declval<T&>() = std::move(value)))
|
||||
operator TGet() MIJIN_NOEXCEPT { return base_->get(); }
|
||||
PropertyProxy& operator=(TSet value) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(std::declval<T&>() = std::move(value)))
|
||||
{
|
||||
base_->set(std::move(value));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
Property() noexcept = default;
|
||||
explicit Property(storage_ptr_t storage) noexcept : storage_(std::move(storage)) {}
|
||||
Property(Property&&) noexcept = default;
|
||||
Property() MIJIN_NOEXCEPT = default;
|
||||
explicit Property(storage_ptr_t storage) MIJIN_NOEXCEPT : storage_(std::move(storage)) {}
|
||||
Property(Property&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
Property& operator=(Property&&) noexcept = default;
|
||||
PropertyProxy operator*() noexcept { return PropertyProxy(this); }
|
||||
std::remove_reference_t<TGet>* operator->() const noexcept { return &get(); }
|
||||
Property& operator=(Property&&) MIJIN_NOEXCEPT = default;
|
||||
PropertyProxy operator*() MIJIN_NOEXCEPT { return PropertyProxy(this); }
|
||||
std::remove_reference_t<TGet>* operator->() const MIJIN_NOEXCEPT { return &get(); }
|
||||
|
||||
[[nodiscard]] TGet get() const noexcept
|
||||
[[nodiscard]] TGet get() const MIJIN_NOEXCEPT
|
||||
{
|
||||
MIJIN_ASSERT_FATAL(storage_ != nullptr, "Cannot get value from an unset property.");
|
||||
return storage_->getValue();
|
||||
}
|
||||
void set(TSet value) noexcept(noexcept(std::declval<T&>() = std::move(value)))
|
||||
void set(TSet value) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(std::declval<T&>() = std::move(value)))
|
||||
{
|
||||
MIJIN_ASSERT_FATAL(storage_ != nullptr, "Cannot set value of an unset property.");
|
||||
storage_->setValue(std::move<TSet>(value));
|
||||
@ -99,7 +100,7 @@ template<typename TStorage>
|
||||
Property(std::unique_ptr<TStorage>) -> Property<typename TStorage::value_t, typename TStorage::get_t, typename TStorage::set_t>;
|
||||
|
||||
template<typename T>
|
||||
Property<T> makeSimpleProperty(T value) noexcept(noexcept(std::declval<T&>() = std::move(value)))
|
||||
Property<T> makeSimpleProperty(T value) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(std::declval<T&>() = std::move(value)))
|
||||
{
|
||||
return Property(std::make_unique<SimplePropertyStorage<T>>(std::move(value)));
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <functional>
|
||||
#include "./common_macros.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
#define MIJIN_SCOPE_EXIT_NAMED(name) \
|
||||
const mijin::ScopeExitGuard name = [&]()
|
||||
@ -19,20 +20,20 @@ private:
|
||||
mutable std::function<void(void)> func; // variable is declared const to make clang-tidy happy, but we still want to be able to reset()
|
||||
public:
|
||||
template<typename TFunc>
|
||||
inline ScopeExitGuard(TFunc&& func_) noexcept : func(std::forward<TFunc>(func_)) {}
|
||||
ScopeExitGuard(const ScopeExitGuard&) noexcept = delete;
|
||||
ScopeExitGuard(ScopeExitGuard&&) noexcept = delete;
|
||||
inline ~ScopeExitGuard() noexcept
|
||||
inline ScopeExitGuard(TFunc&& func_) MIJIN_NOEXCEPT : func(std::forward<TFunc>(func_)) {}
|
||||
ScopeExitGuard(const ScopeExitGuard&) = delete;
|
||||
ScopeExitGuard(ScopeExitGuard&&) = delete;
|
||||
inline ~ScopeExitGuard() MIJIN_NOEXCEPT
|
||||
{
|
||||
if (func) {
|
||||
func();
|
||||
}
|
||||
}
|
||||
|
||||
ScopeExitGuard& operator=(const ScopeExitGuard&) noexcept = delete;
|
||||
ScopeExitGuard& operator=(ScopeExitGuard&&) noexcept = delete;
|
||||
ScopeExitGuard& operator=(const ScopeExitGuard&) = delete;
|
||||
ScopeExitGuard& operator=(ScopeExitGuard&&) = delete;
|
||||
|
||||
inline void reset() const noexcept
|
||||
inline void reset() const MIJIN_NOEXCEPT
|
||||
{
|
||||
func = {};
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "./iterators.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
@ -144,7 +145,7 @@ std::vector<std::basic_string_view<TChar, TTraits>> splitImpl(std::basic_string_
|
||||
}
|
||||
|
||||
template<typename TChar, typename TTraitsA, typename TTraitsB>
|
||||
bool equalsIgnoreCaseImpl(std::basic_string_view<TChar, TTraitsA> stringA, std::basic_string_view<TChar, TTraitsB> stringB) noexcept
|
||||
bool equalsIgnoreCaseImpl(std::basic_string_view<TChar, TTraitsA> stringA, std::basic_string_view<TChar, TTraitsB> stringB) MIJIN_NOEXCEPT
|
||||
{
|
||||
if (stringA.size() != stringB.size())
|
||||
{
|
||||
@ -243,7 +244,7 @@ auto trim(TString&& string)
|
||||
}
|
||||
|
||||
template<typename TLeft, typename TRight>
|
||||
[[nodiscard]] bool equalsIgnoreCase(TLeft&& left, TRight&& right) noexcept
|
||||
[[nodiscard]] bool equalsIgnoreCase(TLeft&& left, TRight&& right) MIJIN_NOEXCEPT
|
||||
{
|
||||
return detail::equalsIgnoreCaseImpl(std::string_view(left), std::string_view(right));
|
||||
}
|
||||
@ -287,7 +288,7 @@ constexpr auto toUpper(TArgs&&... args)
|
||||
|
||||
template<typename TNumber>
|
||||
[[nodiscard]]
|
||||
constexpr bool toNumber(std::string_view stringView, TNumber& outNumber, int base = 10) noexcept
|
||||
constexpr bool toNumber(std::string_view stringView, TNumber& outNumber, int base = 10) MIJIN_NOEXCEPT
|
||||
{
|
||||
const char* start = &*stringView.begin();
|
||||
const char* end = start + stringView.size();
|
||||
@ -297,7 +298,7 @@ constexpr bool toNumber(std::string_view stringView, TNumber& outNumber, int bas
|
||||
|
||||
template<typename TChar, typename TTraits, typename TNumber>
|
||||
[[nodiscard]]
|
||||
constexpr bool toNumber(std::basic_string_view<TChar, TTraits> stringView, TNumber& outNumber, int base = 10) noexcept requires (!std::is_same_v<TChar, char>)
|
||||
constexpr bool toNumber(std::basic_string_view<TChar, TTraits> stringView, TNumber& outNumber, int base = 10) MIJIN_NOEXCEPT requires (!std::is_same_v<TChar, char>)
|
||||
{
|
||||
std::string asString;
|
||||
asString.resize(stringView.size());
|
||||
@ -312,7 +313,7 @@ struct Join
|
||||
{
|
||||
const char* delimiter;
|
||||
|
||||
explicit Join(const char* delimiter_) noexcept : delimiter(delimiter_) {}
|
||||
explicit Join(const char* delimiter_) MIJIN_NOEXCEPT : delimiter(delimiter_) {}
|
||||
};
|
||||
|
||||
template<typename TIterable>
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <vector>
|
||||
#include "../container/optional.hpp"
|
||||
#include "../io/stream.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
#include "../util/hash.hpp"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
@ -52,16 +53,16 @@ public:
|
||||
PathReference() = default;
|
||||
PathReference(const PathReference&) = default;
|
||||
PathReference(PathReference&&) = default;
|
||||
PathReference(class FileSystemAdapter* adapter, fs::path path) noexcept : adapter_(adapter), path_(std::move(path)) {}
|
||||
PathReference(class FileSystemAdapter* adapter, fs::path path) MIJIN_NOEXCEPT : adapter_(adapter), path_(std::move(path)) {}
|
||||
|
||||
PathReference& operator=(const PathReference&) = default;
|
||||
PathReference& operator=(PathReference&&) = default;
|
||||
PathReference& operator=(PathReference&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
auto operator<=>(const PathReference& other) const noexcept = default;
|
||||
auto operator<=>(const PathReference& other) const MIJIN_NOEXCEPT = default;
|
||||
|
||||
[[nodiscard]] bool empty() const noexcept { return adapter_ == nullptr; }
|
||||
[[nodiscard]] bool empty() const MIJIN_NOEXCEPT { return adapter_ == nullptr; }
|
||||
[[nodiscard]] class FileSystemAdapter* getAdapter() const noexcept { return adapter_; }
|
||||
[[nodiscard]] const fs::path& getPath() const noexcept { return path_; }
|
||||
[[nodiscard]] const fs::path& getPath() const MIJIN_NOEXCEPT { return path_; }
|
||||
[[nodiscard]] inline FileInfo getInfo() const;
|
||||
[[nodiscard]] inline Optional<fs::path> getNativePath() const;
|
||||
[[nodiscard]] inline StreamError open(FileOpenMode mode, std::unique_ptr<Stream>& outStream) const;
|
||||
@ -79,7 +80,7 @@ public:
|
||||
[[nodiscard]] virtual Optional<fs::path> getNativePath(const fs::path& /* file */) { return NULL_OPTIONAL; }
|
||||
[[nodiscard]] virtual StreamError open(const fs::path& path, FileOpenMode mode, std::unique_ptr<Stream>& outStream) = 0;
|
||||
|
||||
[[nodiscard]] PathReference getPath(fs::path path) noexcept { return PathReference(this, std::move(path)); }
|
||||
[[nodiscard]] PathReference getPath(fs::path path) MIJIN_NOEXCEPT { return PathReference(this, std::move(path)); }
|
||||
};
|
||||
|
||||
class OSFileSystemAdapter : public FileSystemAdapter
|
||||
@ -151,7 +152,7 @@ inline std::string formatFileSize(std::size_t sizeInBytes)
|
||||
template<>
|
||||
struct std::hash<mijin::PathReference>
|
||||
{
|
||||
std::size_t operator()(const mijin::PathReference& pathRef) const noexcept
|
||||
std::size_t operator()(const mijin::PathReference& pathRef) const MIJIN_NOEXCEPT
|
||||
{
|
||||
std::size_t hash = 0;
|
||||
mijin::hashCombine(hash, pathRef.getAdapter());
|
||||
|
@ -5,6 +5,7 @@
|
||||
#define MIJIN_VIRTUAL_FILESYSTEM_RELATIVE_HPP_INCLUDED 1
|
||||
|
||||
#include "./filesystem.hpp"
|
||||
#include "../internal/common.hpp"
|
||||
|
||||
namespace mijin
|
||||
{
|
||||
@ -32,10 +33,10 @@ public:
|
||||
explicit RelativeFileSystemAdapter(fs::path root, TArgs&&... args)
|
||||
: wrapped_(std::forward<TArgs>(args)...), root_(std::move(root)) {}
|
||||
RelativeFileSystemAdapter(const RelativeFileSystemAdapter&) = default;
|
||||
RelativeFileSystemAdapter(RelativeFileSystemAdapter&&) noexcept = default;
|
||||
RelativeFileSystemAdapter(RelativeFileSystemAdapter&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
RelativeFileSystemAdapter& operator=(const RelativeFileSystemAdapter&) = default;
|
||||
RelativeFileSystemAdapter& operator=(RelativeFileSystemAdapter&&) noexcept = default;
|
||||
RelativeFileSystemAdapter& operator=(RelativeFileSystemAdapter&&) MIJIN_NOEXCEPT = default;
|
||||
|
||||
std::vector<fs::path> getRoots() override;
|
||||
fs::path getHomeFolder() override;
|
||||
@ -44,7 +45,7 @@ public:
|
||||
Optional<fs::path> getNativePath(const fs::path& file) override;
|
||||
StreamError open(const fs::path& path, FileOpenMode mode, std::unique_ptr<Stream>& outStream) override;
|
||||
private:
|
||||
fs::path appendPath(const fs::path& other) const noexcept;
|
||||
fs::path appendPath(const fs::path& other) const MIJIN_NOEXCEPT;
|
||||
};
|
||||
|
||||
//
|
||||
@ -94,7 +95,7 @@ StreamError RelativeFileSystemAdapter<TWrapped>::open(const fs::path& path, File
|
||||
}
|
||||
|
||||
template<typename TWrapped>
|
||||
fs::path RelativeFileSystemAdapter<TWrapped>::appendPath(const fs::path& other) const noexcept
|
||||
fs::path RelativeFileSystemAdapter<TWrapped>::appendPath(const fs::path& other) const MIJIN_NOEXCEPT
|
||||
{
|
||||
fs::path combinedPath = root_;
|
||||
if (other.is_absolute()) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user