Added support for completely disabling noexcept using MIJIN_TEST_NO_NOEXCEPT (for testing).

This commit is contained in:
Patrick 2024-08-29 00:01:23 +02:00
parent a43f92fb58
commit 9ba097fc2f
41 changed files with 643 additions and 564 deletions

View File

@ -34,6 +34,12 @@ if env.get('MIJIN_ENABLE_OPENSSL'):
source/mijin/net/ssl.cpp 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( lib_mijin = env.UnityStaticLibrary(
target = env['LIB_DIR'] + '/mijin', target = env['LIB_DIR'] + '/mijin',

View File

@ -10,5 +10,9 @@
"openssl": "openssl":
{ {
"condition": "getenv('MIJIN_ENABLE_OPENSSL')" "condition": "getenv('MIJIN_ENABLE_OPENSSL')"
},
"curl":
{
"condition": "getenv('MIJIN_ENABLE_CURL')"
} }
} }

View File

@ -135,7 +135,7 @@ void MultiThreadedTaskLoop::workerThread(std::stop_token stopToken, std::size_t
// public functions // public functions
// //
void SimpleTaskLoop::transferCurrentTask(TaskLoop& otherLoop) noexcept void SimpleTaskLoop::transferCurrentTask(TaskLoop& otherLoop) MIJIN_NOEXCEPT
{ {
assertCorrectThread(); assertCorrectThread();
@ -153,7 +153,7 @@ void SimpleTaskLoop::transferCurrentTask(TaskLoop& otherLoop) noexcept
otherLoop.addStoredTask(std::move(storedTask)); otherLoop.addStoredTask(std::move(storedTask));
} }
void SimpleTaskLoop::addStoredTask(StoredTask&& storedTask) noexcept void SimpleTaskLoop::addStoredTask(StoredTask&& storedTask) MIJIN_NOEXCEPT
{ {
storedTask.task->setLoop(this); storedTask.task->setLoop(this);
if (threadId_ == std::thread::id() || threadId_ == std::this_thread::get_id()) 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; std::size_t sum = 0;
for (const StoredTask& task : mijin::chain(tasks_, newTasks_)) for (const StoredTask& task : mijin::chain(tasks_, newTasks_))
@ -188,7 +188,7 @@ std::size_t SimpleTaskLoop::getActiveTasks() const noexcept
return sum; return sum;
} }
void MultiThreadedTaskLoop::transferCurrentTask(TaskLoop& otherLoop) noexcept void MultiThreadedTaskLoop::transferCurrentTask(TaskLoop& otherLoop) MIJIN_NOEXCEPT
{ {
if (&otherLoop == this) { if (&otherLoop == this) {
return; return;
@ -204,7 +204,7 @@ void MultiThreadedTaskLoop::transferCurrentTask(TaskLoop& otherLoop) noexcept
otherLoop.addStoredTask(std::move(storedTask)); otherLoop.addStoredTask(std::move(storedTask));
} }
void MultiThreadedTaskLoop::addStoredTask(StoredTask&& storedTask) noexcept void MultiThreadedTaskLoop::addStoredTask(StoredTask&& storedTask) MIJIN_NOEXCEPT
{ {
storedTask.task->setLoop(this); storedTask.task->setLoop(this);

View File

@ -19,6 +19,7 @@
#include "./future.hpp" #include "./future.hpp"
#include "./message_queue.hpp" #include "./message_queue.hpp"
#include "../container/optional.hpp" #include "../container/optional.hpp"
#include "../internal/common.hpp"
#include "../util/flag.hpp" #include "../util/flag.hpp"
#include "../util/iterators.hpp" #include "../util/iterators.hpp"
#include "../util/traits.hpp" #include "../util/traits.hpp"
@ -68,28 +69,28 @@ private:
std::weak_ptr<struct TaskSharedState> state_; std::weak_ptr<struct TaskSharedState> state_;
public: public:
TaskHandle() = default; 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(const TaskHandle&) = default;
TaskHandle(TaskHandle&&) = default; TaskHandle(TaskHandle&&) = default;
TaskHandle& operator=(const TaskHandle&) = default; TaskHandle& operator=(const TaskHandle&) = default;
TaskHandle& operator=(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_); 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); return !(*this == other);
} }
[[nodiscard]] bool isValid() const noexcept [[nodiscard]] bool isValid() const MIJIN_NOEXCEPT
{ {
return !state_.expired(); return !state_.expired();
} }
inline void cancel() const noexcept; inline void cancel() const MIJIN_NOEXCEPT;
#if MIJIN_COROUTINE_ENABLE_DEBUG_INFO #if MIJIN_COROUTINE_ENABLE_DEBUG_INFO
inline Optional<Stacktrace> getCreationStack() const noexcept; inline Optional<Stacktrace> getCreationStack() const MIJIN_NOEXCEPT;
#endif #endif
}; };
struct TaskSharedState struct TaskSharedState
@ -110,11 +111,11 @@ struct TaskState
TaskState() = default; TaskState() = default;
TaskState(const TaskState&) = default; TaskState(const TaskState&) = default;
TaskState(TaskState&&) noexcept = default; TaskState(TaskState&&) MIJIN_NOEXCEPT = default;
inline TaskState(T _value, TaskStatus _status) noexcept : value(std::move(_value)), status(_status) {} inline TaskState(T _value, TaskStatus _status) MIJIN_NOEXCEPT : value(std::move(_value)), status(_status) {}
inline TaskState(std::exception_ptr _exception) noexcept : exception(std::move(_exception)), status(TaskStatus::FINISHED) {} inline TaskState(std::exception_ptr _exception) MIJIN_NOEXCEPT : exception(std::move(_exception)), status(TaskStatus::FINISHED) {}
TaskState& operator=(const TaskState&) = default; TaskState& operator=(const TaskState&) = default;
TaskState& operator=(TaskState&&) noexcept = default; TaskState& operator=(TaskState&&) MIJIN_NOEXCEPT = default;
}; };
template<> template<>
@ -125,11 +126,11 @@ struct TaskState<void>
TaskState() = default; TaskState() = default;
TaskState(const TaskState&) = default; TaskState(const TaskState&) = default;
TaskState(TaskState&&) noexcept = default; TaskState(TaskState&&) MIJIN_NOEXCEPT = default;
inline TaskState(TaskStatus _status) noexcept : status(_status) {} inline TaskState(TaskStatus _status) MIJIN_NOEXCEPT : status(_status) {}
inline TaskState(std::exception_ptr _exception) noexcept : exception(std::move(_exception)), status(TaskStatus::FINISHED) {} inline TaskState(std::exception_ptr _exception) MIJIN_NOEXCEPT : exception(std::move(_exception)), status(TaskStatus::FINISHED) {}
TaskState& operator=(const TaskState&) = default; TaskState& operator=(const TaskState&) = default;
TaskState& operator=(TaskState&&) noexcept = default; TaskState& operator=(TaskState&&) MIJIN_NOEXCEPT = default;
}; };
namespace impl namespace impl
@ -138,15 +139,15 @@ template<typename TReturn, typename TPromise>
struct TaskReturn struct TaskReturn
{ {
template<typename... TArgs> 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); (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); (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()); (static_cast<TPromise&>(*this).state_) = TaskState<TReturn>(std::current_exception());
} }
}; };
@ -154,11 +155,11 @@ struct TaskReturn
template<typename TPromise> template<typename TPromise>
struct TaskReturn<void, TPromise> struct TaskReturn<void, TPromise>
{ {
constexpr void return_void() noexcept { constexpr void return_void() MIJIN_NOEXCEPT {
static_cast<TPromise&>(*this).state_.status = TaskStatus::FINISHED; 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()); (static_cast<TPromise&>(*this).state_) = TaskState<void>(std::current_exception());
} }
}; };
@ -169,8 +170,8 @@ struct TaskAwaitableFuture
{ {
FuturePtr<TValue> future; FuturePtr<TValue> future;
[[nodiscard]] constexpr bool await_ready() const noexcept { return future->ready(); } [[nodiscard]] constexpr bool await_ready() const MIJIN_NOEXCEPT { return future->ready(); }
constexpr void await_suspend(std::coroutine_handle<>) const noexcept {} constexpr void await_suspend(std::coroutine_handle<>) const MIJIN_NOEXCEPT {}
constexpr TValue await_resume() const constexpr TValue await_resume() const
{ {
impl::throwIfCancelled(); impl::throwIfCancelled();
@ -188,8 +189,8 @@ struct TaskAwaitableSignal
{ {
std::shared_ptr<std::tuple<TArgs...>> data; std::shared_ptr<std::tuple<TArgs...>> data;
[[nodiscard]] constexpr bool await_ready() const noexcept { return false; } [[nodiscard]] constexpr bool await_ready() const MIJIN_NOEXCEPT { return false; }
constexpr void await_suspend(std::coroutine_handle<>) const noexcept {} constexpr void await_suspend(std::coroutine_handle<>) const MIJIN_NOEXCEPT {}
inline auto& await_resume() const inline auto& await_resume() const
{ {
impl::throwIfCancelled(); impl::throwIfCancelled();
@ -202,8 +203,8 @@ struct TaskAwaitableSignal<TSingleArg>
{ {
std::shared_ptr<TSingleArg> data; std::shared_ptr<TSingleArg> data;
[[nodiscard]] constexpr bool await_ready() const noexcept { return false; } [[nodiscard]] constexpr bool await_ready() const MIJIN_NOEXCEPT { return false; }
constexpr void await_suspend(std::coroutine_handle<>) const noexcept {} constexpr void await_suspend(std::coroutine_handle<>) const MIJIN_NOEXCEPT {}
constexpr auto& await_resume() const constexpr auto& await_resume() const
{ {
impl::throwIfCancelled(); impl::throwIfCancelled();
@ -214,8 +215,8 @@ struct TaskAwaitableSignal<TSingleArg>
template<> template<>
struct TaskAwaitableSignal<> struct TaskAwaitableSignal<>
{ {
[[nodiscard]] constexpr bool await_ready() const noexcept { return false; } [[nodiscard]] constexpr bool await_ready() const MIJIN_NOEXCEPT { return false; }
constexpr void await_suspend(std::coroutine_handle<>) const noexcept {} constexpr void await_suspend(std::coroutine_handle<>) const MIJIN_NOEXCEPT {}
inline void await_resume() const { inline void await_resume() const {
impl::throwIfCancelled(); impl::throwIfCancelled();
} }
@ -223,8 +224,8 @@ struct TaskAwaitableSignal<>
struct TaskAwaitableSuspend struct TaskAwaitableSuspend
{ {
[[nodiscard]] constexpr bool await_ready() const noexcept { return false; } [[nodiscard]] constexpr bool await_ready() const MIJIN_NOEXCEPT { return false; }
constexpr void await_suspend(std::coroutine_handle<>) const noexcept {} constexpr void await_suspend(std::coroutine_handle<>) const MIJIN_NOEXCEPT {}
inline void await_resume() const { inline void await_resume() const {
impl::throwIfCancelled(); 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>(); std::shared_ptr<TaskSharedState> sharedState_ = std::make_shared<TaskSharedState>();
TaskLoop* loop_ = nullptr; TaskLoop* loop_ = nullptr;
constexpr task_t get_return_object() noexcept { return task_t(handle_t::from_promise(*this)); } constexpr task_t get_return_object() MIJIN_NOEXCEPT { return task_t(handle_t::from_promise(*this)); }
constexpr TaskAwaitableSuspend initial_suspend() noexcept { return {}; } constexpr TaskAwaitableSuspend initial_suspend() MIJIN_NOEXCEPT { return {}; }
constexpr std::suspend_always final_suspend() noexcept { return {}; } constexpr std::suspend_always final_suspend() noexcept { return {}; } // note: this must always be noexcept, no matter what
// template<typename TValue> // 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); // *state_ = TaskState<result_t>(std::move(value), TaskStatus::YIELDED);
// return {}; // return {};
// } // }
// TODO: implement yielding (can't use futures for this) // TODO: implement yielding (can't use futures for this)
// constexpr void unhandled_exception() noexcept {} // constexpr void unhandled_exception() MIJIN_NOEXCEPT {}
template<typename TValue> 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!"); MIJIN_ASSERT(loop_ != nullptr, "Cannot await future outside of a loop!");
TaskAwaitableFuture<TValue> awaitable{future}; TaskAwaitableFuture<TValue> awaitable{future};
@ -272,7 +273,7 @@ struct TaskPromise : impl::TaskReturn<typename TTraits::result_t, TaskPromise<TT
} }
template<typename TResultOther> 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) 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 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> 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...>>(); auto data = std::make_shared<std::tuple<TFirstArg, TSecondArg, TArgs...>>();
signal.connect([this, data](TFirstArg arg0, TSecondArg arg1, TArgs... args) mutable 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> template<typename TFirstArg>
auto await_transform(Signal<TFirstArg>& signal) noexcept auto await_transform(Signal<TFirstArg>& signal) MIJIN_NOEXCEPT
{ {
auto data = std::make_shared<TFirstArg>(); auto data = std::make_shared<TFirstArg>();
signal.connect([this, data](TFirstArg arg0) mutable signal.connect([this, data](TFirstArg arg0) mutable
@ -307,7 +308,7 @@ struct TaskPromise : impl::TaskReturn<typename TTraits::result_t, TaskPromise<TT
return awaitable; return awaitable;
} }
auto await_transform(Signal<>& signal) noexcept auto await_transform(Signal<>& signal) MIJIN_NOEXCEPT
{ {
signal.connect([this]() signal.connect([this]()
{ {
@ -318,17 +319,17 @@ struct TaskPromise : impl::TaskReturn<typename TTraits::result_t, TaskPromise<TT
return awaitable; 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; state_.status = TaskStatus::SUSPENDED;
return std::suspend_always(); 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(); return std::suspend_never();
} }
TaskAwaitableSuspend await_transform(TaskAwaitableSuspend) noexcept TaskAwaitableSuspend await_transform(TaskAwaitableSuspend) MIJIN_NOEXCEPT
{ {
state_.status = TaskStatus::SUSPENDED; state_.status = TaskStatus::SUSPENDED;
return TaskAwaitableSuspend(); return TaskAwaitableSuspend();
@ -352,7 +353,7 @@ public:
private: private:
handle_t handle_; handle_t handle_;
public: 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 MIJIN_COROUTINE_ENABLE_DEBUG_INFO
if (Result<Stacktrace> stacktrace = captureStacktrace(2); stacktrace.isSuccess()) if (Result<Stacktrace> stacktrace = captureStacktrace(2); stacktrace.isSuccess())
{ {
@ -361,12 +362,12 @@ public:
#endif #endif
} }
TaskBase(const TaskBase&) = delete; 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: public:
TaskBase& operator=(const TaskBase&) = delete; TaskBase& operator=(const TaskBase&) = delete;
TaskBase& operator=(TaskBase&& other) noexcept TaskBase& operator=(TaskBase&& other) MIJIN_NOEXCEPT
{ {
if (handle_) { if (handle_) {
handle_.destroy(); handle_.destroy();
@ -376,13 +377,13 @@ public:
} }
[[nodiscard]] [[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]] [[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: public:
[[nodiscard]] [[nodiscard]]
constexpr TaskState<TResult>& state() noexcept constexpr TaskState<TResult>& state() MIJIN_NOEXCEPT
{ {
return handle_.promise().state_; return handle_.promise().state_;
} }
@ -392,19 +393,19 @@ public:
handle_.resume(); handle_.resume();
return state(); return state();
} }
constexpr std::shared_ptr<TaskSharedState>& sharedState() noexcept constexpr std::shared_ptr<TaskSharedState>& sharedState() MIJIN_NOEXCEPT
{ {
return handle_.promise().sharedState_; return handle_.promise().sharedState_;
} }
private: private:
[[nodiscard]] [[nodiscard]]
constexpr handle_t handle() const noexcept { return handle_; } constexpr handle_t handle() const MIJIN_NOEXCEPT { return handle_; }
[[nodiscard]] [[nodiscard]]
constexpr TaskLoop* getLoop() noexcept constexpr TaskLoop* getLoop() MIJIN_NOEXCEPT
{ {
return handle_.promise().loop_; return handle_.promise().loop_;
} }
constexpr void setLoop(TaskLoop* loop) noexcept constexpr void setLoop(TaskLoop* loop) MIJIN_NOEXCEPT
{ {
// MIJIN_ASSERT(handle_.promise().loop_ == nullptr // MIJIN_ASSERT(handle_.promise().loop_ == nullptr
// || handle_.promise().loop_ == loop // || handle_.promise().loop_ == loop
@ -423,14 +424,14 @@ class WrappedTaskBase
public: public:
virtual ~WrappedTaskBase() = default; virtual ~WrappedTaskBase() = default;
public: public:
virtual TaskStatus status() noexcept = 0; virtual TaskStatus status() MIJIN_NOEXCEPT = 0;
virtual std::exception_ptr exception() noexcept = 0; virtual std::exception_ptr exception() MIJIN_NOEXCEPT = 0;
// virtual std::any result() noexcept = 0; // virtual std::any result() MIJIN_NOEXCEPT = 0;
virtual void resume() = 0; virtual void resume() = 0;
virtual void* raw() noexcept = 0; virtual void* raw() MIJIN_NOEXCEPT = 0;
virtual std::coroutine_handle<> handle() noexcept = 0; virtual std::coroutine_handle<> handle() MIJIN_NOEXCEPT = 0;
virtual void setLoop(TaskLoop* loop) noexcept = 0; virtual void setLoop(TaskLoop* loop) MIJIN_NOEXCEPT = 0;
virtual std::shared_ptr<TaskSharedState>& sharedState() noexcept = 0; virtual std::shared_ptr<TaskSharedState>& sharedState() MIJIN_NOEXCEPT = 0;
[[nodiscard]] inline bool canResume() { [[nodiscard]] inline bool canResume() {
const TaskStatus stat = status(); const TaskStatus stat = status();
@ -444,16 +445,16 @@ class WrappedTask : public WrappedTaskBase
private: private:
TTask task_; TTask task_;
public: 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(const WrappedTask&) = delete;
WrappedTask(WrappedTask&&) noexcept = default; WrappedTask(WrappedTask&&) MIJIN_NOEXCEPT = default;
public: public:
WrappedTask& operator=(const WrappedTask&) = delete; WrappedTask& operator=(const WrappedTask&) = delete;
WrappedTask& operator=(WrappedTask&&) noexcept = default; WrappedTask& operator=(WrappedTask&&) MIJIN_NOEXCEPT = default;
public: public:
TaskStatus status() noexcept override { return task_.state().status; } TaskStatus status() MIJIN_NOEXCEPT override { return task_.state().status; }
std::exception_ptr exception() noexcept override { return task_.state().exception; } std::exception_ptr exception() MIJIN_NOEXCEPT override { return task_.state().exception; }
// std::any result() noexcept override // std::any result() MIJIN_NOEXCEPT
// { // {
// if constexpr (std::is_same_v<typename TTask::result_t, void>) { // if constexpr (std::is_same_v<typename TTask::result_t, void>) {
// return {}; // return {};
@ -463,14 +464,14 @@ public:
// } // }
// } // }
void resume() override { task_.resume(); } void resume() override { task_.resume(); }
void* raw() noexcept override { return &task_; } void* raw() MIJIN_NOEXCEPT override { return &task_; }
std::coroutine_handle<> handle() noexcept override { return task_.handle(); } std::coroutine_handle<> handle() MIJIN_NOEXCEPT override { return task_.handle(); }
void setLoop(TaskLoop* loop) noexcept override { task_.setLoop(loop); } void setLoop(TaskLoop* loop) MIJIN_NOEXCEPT override { task_.setLoop(loop); }
virtual std::shared_ptr<TaskSharedState>& sharedState() noexcept override { return task_.sharedState(); } virtual std::shared_ptr<TaskSharedState>& sharedState() MIJIN_NOEXCEPT override { return task_.sharedState(); }
}; };
template<typename TTask> 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)); return std::make_unique<WrappedTask<TTask>>(std::forward<TTask>(task));
} }
@ -499,29 +500,29 @@ protected:
exception_handler_t uncaughtExceptionHandler_; exception_handler_t uncaughtExceptionHandler_;
public: public:
TaskLoop() = default; TaskLoop() MIJIN_NOEXCEPT = default;
TaskLoop(const TaskLoop&) = delete; TaskLoop(const TaskLoop&) = delete;
TaskLoop(TaskLoop&&) = delete; TaskLoop(TaskLoop&&) = delete;
virtual ~TaskLoop() = default; virtual ~TaskLoop() MIJIN_NOEXCEPT = default;
TaskLoop& operator=(const TaskLoop&) = delete; TaskLoop& operator=(const TaskLoop&) = delete;
TaskLoop& operator=(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> 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 transferCurrentTask(TaskLoop& otherLoop) MIJIN_NOEXCEPT = 0;
virtual void addStoredTask(StoredTask&& storedTask) noexcept = 0; virtual void addStoredTask(StoredTask&& storedTask) MIJIN_NOEXCEPT = 0;
[[nodiscard]] static TaskLoop& current() noexcept; [[nodiscard]] static TaskLoop& current() MIJIN_NOEXCEPT;
protected: protected:
inline TaskStatus tickTask(StoredTask& task); inline TaskStatus tickTask(StoredTask& task);
protected: protected:
static inline TaskLoop*& currentLoopStorage() noexcept; static inline TaskLoop*& currentLoopStorage() MIJIN_NOEXCEPT;
template<typename TResult> template<typename TResult>
static inline void setFutureHelper(StoredTask& storedTask) noexcept; static inline void setFutureHelper(StoredTask& storedTask) MIJIN_NOEXCEPT;
}; };
template<typename TResult = void> template<typename TResult = void>
@ -537,17 +538,17 @@ private:
std::thread::id threadId_; std::thread::id threadId_;
public: // TaskLoop implementation public: // TaskLoop implementation
void transferCurrentTask(TaskLoop& otherLoop) noexcept override; void transferCurrentTask(TaskLoop& otherLoop) MIJIN_NOEXCEPT override;
void addStoredTask(StoredTask&& storedTask) noexcept override; void addStoredTask(StoredTask&& storedTask) MIJIN_NOEXCEPT override;
public: // public interface public: // public interface
[[nodiscard]] constexpr bool empty() const noexcept { return tasks_.empty() && newTasks_.empty(); } [[nodiscard]] constexpr bool empty() const MIJIN_NOEXCEPT { return tasks_.empty() && newTasks_.empty(); }
[[nodiscard]] constexpr std::size_t getNumTasks() const noexcept { return tasks_.size() + newTasks_.size(); } [[nodiscard]] constexpr std::size_t getNumTasks() const MIJIN_NOEXCEPT { return tasks_.size() + newTasks_.size(); }
[[nodiscard]] std::size_t getActiveTasks() const noexcept; [[nodiscard]] std::size_t getActiveTasks() const MIJIN_NOEXCEPT;
inline CanContinue tick(); inline CanContinue tick();
inline void runUntilDone(IgnoreWaiting ignoreWaiting = IgnoreWaiting::NO); inline void runUntilDone(IgnoreWaiting ignoreWaiting = IgnoreWaiting::NO);
inline void cancelAllTasks() noexcept; inline void cancelAllTasks() MIJIN_NOEXCEPT;
[[nodiscard]] inline std::vector<TaskHandle> getAllTasks() const noexcept; [[nodiscard]] inline std::vector<TaskHandle> getAllTasks() const MIJIN_NOEXCEPT;
private: private:
inline void assertCorrectThread() { MIJIN_ASSERT(threadId_ == std::thread::id() || threadId_ == std::this_thread::get_id(), "Unsafe to TaskLoop from different thread!"); } 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_; std::vector<std::jthread> workerThreads_;
public: // TaskLoop implementation public: // TaskLoop implementation
void transferCurrentTask(TaskLoop& otherLoop) noexcept override; void transferCurrentTask(TaskLoop& otherLoop) MIJIN_NOEXCEPT override;
void addStoredTask(StoredTask&& storedTask) noexcept override; void addStoredTask(StoredTask&& storedTask) MIJIN_NOEXCEPT override;
public: // public interface public: // public interface
void start(std::size_t numWorkerThreads); 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()) if (std::shared_ptr<TaskSharedState> state = state_.lock())
{ {
@ -601,7 +602,7 @@ void TaskHandle::cancel() const noexcept
} }
#if MIJIN_COROUTINE_ENABLE_DEBUG_INFO #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()) if (std::shared_ptr<TaskSharedState> state = state_.lock())
{ {
@ -612,7 +613,7 @@ Optional<Stacktrace> TaskHandle::getCreationStack() const noexcept
#endif // MIJIN_COROUTINE_ENABLE_DEBUG_INFO #endif // MIJIN_COROUTINE_ENABLE_DEBUG_INFO
template<typename TResult> template<typename TResult>
TaskBase<TResult>::~TaskBase() noexcept TaskBase<TResult>::~TaskBase() MIJIN_NOEXCEPT
{ {
if (handle_) if (handle_)
{ {
@ -621,7 +622,7 @@ TaskBase<TResult>::~TaskBase() noexcept
} }
template<typename TResult> 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!"); MIJIN_ASSERT(!task.getLoop(), "Attempting to add task that already has a loop!");
task.setLoop(this); task.setLoop(this);
@ -685,20 +686,20 @@ inline TaskStatus TaskLoop::tickTask(StoredTask& task)
return status; 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!"); MIJIN_ASSERT(currentLoopStorage() != nullptr, "Attempting to fetch current loop while no coroutine is running!");
return *currentLoopStorage(); return *currentLoopStorage();
} }
/* static */ auto TaskLoop::currentLoopStorage() noexcept -> TaskLoop*& /* static */ auto TaskLoop::currentLoopStorage() MIJIN_NOEXCEPT -> TaskLoop*&
{ {
static thread_local TaskLoop* storage = nullptr; static thread_local TaskLoop* storage = nullptr;
return storage; return storage;
} }
template<typename TResult> 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()); TaskBase<TResult>& task = *static_cast<TaskBase<TResult>*>(storedTask.task->raw());
auto future = std::any_cast<FuturePtr<TResult>>(storedTask.resultData); 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_)) 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; std::vector<TaskHandle> result;
for (const StoredTask& task : mijin::chain(tasks_, newTasks_)) for (const StoredTask& task : mijin::chain(tasks_, newTasks_))
@ -848,7 +849,7 @@ Task<> c_allDone(const TCollection<FuturePtr<TType>, TTemplateArgs...>& futures)
} while (!allDone); } 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."); MIJIN_ASSERT(impl::gCurrentTask != nullptr, "Attempt to call getCurrentTask() outside of task.");
return TaskHandle(impl::gCurrentTask->task->sharedState()); return TaskHandle(impl::gCurrentTask->task->sharedState());

View File

@ -8,8 +8,9 @@
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include "./signal.hpp" #include "./signal.hpp"
#include "../debug/assert.hpp"
#include "../container/optional.hpp" #include "../container/optional.hpp"
#include "../debug/assert.hpp"
#include "../internal/common.hpp"
namespace mijin namespace mijin
{ {
@ -36,8 +37,8 @@ struct FutureStorage
{ {
Optional<TValue> value; Optional<TValue> value;
void setValue(TValue value_) noexcept { value = std::move(value_); } void setValue(TValue value_) MIJIN_NOEXCEPT { value = std::move(value_); }
[[nodiscard]] TValue& getValue() noexcept { return value.get(); } [[nodiscard]] TValue& getValue() MIJIN_NOEXCEPT { return value.get(); }
}; };
@ -46,8 +47,8 @@ struct FutureStorage
// { // {
// Optional<TValue*> value; // Optional<TValue*> value;
// //
// void setValue(TValue& value_) noexcept { value = &value_; } // void setValue(TValue& value_) MIJIN_NOEXCEPT { value = &value_; }
// [[nodiscard]] TValue& getValue() const noexcept { return *value.get(); } // [[nodiscard]] TValue& getValue() const MIJIN_NOEXCEPT { return *value.get(); }
// }; // };
template<> template<>
@ -65,19 +66,19 @@ private:
public: public:
Future() = default; Future() = default;
Future(const Future&) = delete; Future(const Future&) = delete;
Future(Future&&) noexcept = default; Future(Future&&) MIJIN_NOEXCEPT = default;
public: public:
Future& operator=(const Future&) = delete; Future& operator=(const Future&) = delete;
Future& operator=(Future&&) noexcept = default; Future& operator=(Future&&) MIJIN_NOEXCEPT = default;
[[nodiscard]] [[nodiscard]]
constexpr explicit operator bool() const noexcept { return ready(); } constexpr explicit operator bool() const MIJIN_NOEXCEPT { return ready(); }
[[nodiscard]] [[nodiscard]]
constexpr bool operator!() const noexcept { return !ready(); } constexpr bool operator!() const MIJIN_NOEXCEPT { return !ready(); }
public: // access public: // access
[[nodiscard]] [[nodiscard]]
constexpr decltype(auto) get() noexcept constexpr decltype(auto) get() MIJIN_NOEXCEPT
{ {
MIJIN_ASSERT(isSet_, "Attempting to get from future that is not ready."); MIJIN_ASSERT(isSet_, "Attempting to get from future that is not ready.");
if constexpr(std::is_same_v<TValue, void>) { if constexpr(std::is_same_v<TValue, void>) {
@ -88,7 +89,7 @@ public: // access
} }
} }
[[nodiscard]] [[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."); MIJIN_ASSERT(isSet_, "Attempting to get from future that is not ready.");
if constexpr(std::is_same_v<TValue, void>) { if constexpr(std::is_same_v<TValue, void>) {
@ -99,20 +100,20 @@ public: // access
} }
} }
[[nodiscard]] [[nodiscard]]
constexpr bool ready() const noexcept constexpr bool ready() const MIJIN_NOEXCEPT
{ {
return isSet_; return isSet_;
} }
public: // modification public: // modification
template<typename TArg> requires (!std::is_same_v<TValue, void>) 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!"); MIJIN_ASSERT(!isSet_, "Trying to set a future twice!");
value_.setValue(std::move(value)); value_.setValue(std::move(value));
isSet_ = true; isSet_ = true;
sigSet.emit(); sigSet.emit();
} }
constexpr void set() noexcept constexpr void set() MIJIN_NOEXCEPT
{ {
MIJIN_ASSERT(!isSet_, "Trying to set a future twice!"); MIJIN_ASSERT(!isSet_, "Trying to set a future twice!");
isSet_ = true; isSet_ = true;

View File

@ -8,6 +8,7 @@
#include <atomic> #include <atomic>
#include <optional> #include <optional>
#include <thread> #include <thread>
#include "../internal/common.hpp"
#include "../util/bitarray.hpp" #include "../util/bitarray.hpp"
namespace mijin namespace mijin
@ -37,7 +38,7 @@ private:
std::optional<value_type> message_; std::optional<value_type> message_;
public: public:
MessageQueueIterator() = default; MessageQueueIterator() = default;
explicit MessageQueueIterator(TMessageQueue& queue) noexcept : queue_(&queue) { explicit MessageQueueIterator(TMessageQueue& queue) MIJIN_NOEXCEPT : queue_(&queue) {
message_ = queue_->tryPop(); message_ = queue_->tryPop();
} }
MessageQueueIterator(const MessageQueueIterator&) = delete; MessageQueueIterator(const MessageQueueIterator&) = delete;
@ -46,26 +47,26 @@ public:
MessageQueueIterator& operator=(const MessageQueueIterator&) = delete; MessageQueueIterator& operator=(const MessageQueueIterator&) = delete;
MessageQueueIterator& operator=(MessageQueueIterator&&) = default; 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(); return message_.has_value() == other.message_.has_value();
} }
bool operator!=(const MessageQueueIterator& other) noexcept bool operator!=(const MessageQueueIterator& other) MIJIN_NOEXCEPT
{ {
return !(*this == other); return !(*this == other);
} }
reference operator*() noexcept reference operator*() MIJIN_NOEXCEPT
{ {
return message_.value(); return message_.value();
} }
pointer operator->() noexcept pointer operator->() MIJIN_NOEXCEPT
{ {
return &message_.value(); return &message_.value();
} }
MessageQueueIterator& operator++() noexcept MessageQueueIterator& operator++() MIJIN_NOEXCEPT
{ {
message_ = queue_->tryPop(); message_ = queue_->tryPop();
return *this; return *this;
@ -86,10 +87,10 @@ private:
public: public:
MessageQueue() = default; MessageQueue() = default;
MessageQueue(const MessageQueue&) = delete; MessageQueue(const MessageQueue&) = delete;
MessageQueue(MessageQueue&&) noexcept = delete; MessageQueue(MessageQueue&&) = delete;
MessageQueue& operator=(const MessageQueue&) = delete; MessageQueue& operator=(const MessageQueue&) = delete;
MessageQueue& operator=(MessageQueue&&) noexcept = delete; MessageQueue& operator=(MessageQueue&&) = delete;
[[nodiscard]] bool tryPushMaybeMove(TMessage& message); [[nodiscard]] bool tryPushMaybeMove(TMessage& message);
[[nodiscard]] bool tryPush(TMessage message) { [[nodiscard]] bool tryPush(TMessage message) {
@ -99,8 +100,8 @@ public:
[[nodiscard]] std::optional<TMessage> tryPop(); [[nodiscard]] std::optional<TMessage> tryPop();
[[nodiscard]] TMessage wait(); [[nodiscard]] TMessage wait();
iterator_t begin() noexcept { return iterator_t(*this); } iterator_t begin() MIJIN_NOEXCEPT { return iterator_t(*this); }
iterator_t end() noexcept { return iterator_t(); } iterator_t end() MIJIN_NOEXCEPT { return iterator_t(); }
}; };
template<typename TRequest, typename TResponse, std::size_t requestBufferSize = 32, std::size_t responseBufferSize = 32> template<typename TRequest, typename TResponse, std::size_t requestBufferSize = 32, std::size_t responseBufferSize = 32>

View File

@ -10,6 +10,7 @@
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <vector> #include <vector>
#include "../internal/common.hpp"
#include "../util/flag.hpp" #include "../util/flag.hpp"
namespace mijin namespace mijin
@ -54,17 +55,17 @@ private:
public: public:
Signal() = default; Signal() = default;
Signal(const Signal&) = delete; Signal(const Signal&) = delete;
Signal(Signal&&) noexcept = default; Signal(Signal&&) MIJIN_NOEXCEPT = default;
public: public:
Signal& operator=(const Signal&) = delete; Signal& operator=(const Signal&) = delete;
Signal& operator=(Signal&&) noexcept = default; Signal& operator=(Signal&&) MIJIN_NOEXCEPT = default;
public: public:
template<typename THandler, typename TWeak = void> 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> 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 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) noexcept; inline void disconnect(token_t token) MIJIN_NOEXCEPT;
inline void emit(TArgs&&... args) noexcept; inline void emit(TArgs&&... args) MIJIN_NOEXCEPT;
}; };
// //
@ -73,7 +74,7 @@ public:
template<typename... TArgs> template<typename... TArgs>
template<typename THandler, typename TWeak> 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_); 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... TArgs>
template<typename TObject, typename TWeak> 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_); std::lock_guard lock(handlersMutex_);
@ -109,7 +110,7 @@ inline auto Signal<TArgs...>::connect(TObject& object, void (TObject::* handler)
} }
template<typename... TArgs> 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_); std::lock_guard lock(handlersMutex_);
@ -121,7 +122,7 @@ inline void Signal<TArgs...>::disconnect(token_t token) noexcept
} }
template<typename... TArgs> 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_); std::lock_guard lock(handlersMutex_);

View File

@ -5,6 +5,7 @@
#define MIJIN_ASYNC_TASK_MUTEX_HPP_INCLUDED 1 #define MIJIN_ASYNC_TASK_MUTEX_HPP_INCLUDED 1
#include "./coroutine.hpp" #include "./coroutine.hpp"
#include "../internal/common.hpp"
namespace mijin namespace mijin
{ {
@ -14,13 +15,13 @@ private:
class TaskMutex* mutex_; class TaskMutex* mutex_;
public: public:
explicit TaskMutexLock(class TaskMutex* mutex) noexcept : mutex_(mutex) {} explicit TaskMutexLock(class TaskMutex* mutex) MIJIN_NOEXCEPT : mutex_(mutex) {}
TaskMutexLock(const TaskMutexLock&) = delete; 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; TaskMutexLock& operator=(const TaskMutexLock&) = delete;
inline TaskMutexLock& operator=(TaskMutexLock&& other) noexcept; inline TaskMutexLock& operator=(TaskMutexLock&& other) MIJIN_NOEXCEPT;
inline ~TaskMutexLock() noexcept; inline ~TaskMutexLock() MIJIN_NOEXCEPT;
}; };
class TaskMutex class TaskMutex
@ -37,12 +38,12 @@ public:
locked_ = true; locked_ = true;
co_return TaskMutexLock(this); co_return TaskMutexLock(this);
} }
[[nodiscard]] inline bool isLocked() const noexcept { return locked_; } [[nodiscard]] inline bool isLocked() const MIJIN_NOEXCEPT { return locked_; }
friend class TaskMutexLock; friend class TaskMutexLock;
}; };
TaskMutexLock::~TaskMutexLock() noexcept TaskMutexLock::~TaskMutexLock() MIJIN_NOEXCEPT
{ {
if (mutex_) if (mutex_)
{ {
@ -50,7 +51,7 @@ TaskMutexLock::~TaskMutexLock() noexcept
} }
} }
TaskMutexLock& TaskMutexLock::operator=(TaskMutexLock&& other) noexcept TaskMutexLock& TaskMutexLock::operator=(TaskMutexLock&& other) MIJIN_NOEXCEPT
{ {
if (mutex_) if (mutex_)
{ {

View File

@ -8,6 +8,8 @@
#include <cstdlib> #include <cstdlib>
#include <source_location> #include <source_location>
#include "../internal/common.hpp"
#ifdef _WIN32 #ifdef _WIN32
#pragma comment(lib, "kernel32") #pragma comment(lib, "kernel32")
extern "C" __declspec(dllimport) void __stdcall DebugBreak(); extern "C" __declspec(dllimport) void __stdcall DebugBreak();
@ -139,7 +141,7 @@ constexpr AssertionResult handleAssert(const char* /* condition */,
#ifdef MIJIN_USE_CUSTOM_ERROR_HANDLER #ifdef MIJIN_USE_CUSTOM_ERROR_HANDLER
ErrorHandling handleError(const char* message, const std::source_location& location); ErrorHandling handleError(const char* message, const std::source_location& location);
#else #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::puts(message);
std::printf("Function: %s\n", location.function_name()); std::printf("Function: %s\n", location.function_name());

View File

@ -75,7 +75,7 @@ thread_local backtrace_state* gBacktraceState = nullptr;
// public functions // public functions
// //
Result<Stacktrace> captureStacktrace(unsigned skipFrames) noexcept Result<Stacktrace> captureStacktrace(unsigned skipFrames) MIJIN_NOEXCEPT
{ {
#if MIJIN_USE_LIBBACKTRACE #if MIJIN_USE_LIBBACKTRACE
BacktraceData btData; BacktraceData btData;
@ -104,7 +104,7 @@ Result<Stacktrace> captureStacktrace(unsigned skipFrames) noexcept
#endif // MIJIN_USE_LIBBACKTRACE #endif // MIJIN_USE_LIBBACKTRACE
} }
const Optional<Stacktrace>& getExceptionStacktrace() noexcept const Optional<Stacktrace>& getExceptionStacktrace() MIJIN_NOEXCEPT
{ {
return gCurrentExceptionStackTrace; return gCurrentExceptionStackTrace;
} }

View File

@ -11,6 +11,7 @@
# include <fmt/format.h> # include <fmt/format.h>
#endif #endif
#include "./symbol_info.hpp" #include "./symbol_info.hpp"
#include "../internal/common.hpp"
#include "../types/result.hpp" #include "../types/result.hpp"
#include "../util/iterators.hpp" #include "../util/iterators.hpp"
@ -45,20 +46,20 @@ public:
Stacktrace() = default; Stacktrace() = default;
Stacktrace(const Stacktrace&) = default; Stacktrace(const Stacktrace&) = default;
Stacktrace(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=(const Stacktrace&) = default;
Stacktrace& operator=(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 // public functions
// //
[[nodiscard]] Result<Stacktrace> captureStacktrace(unsigned skipFrames = 0) noexcept; [[nodiscard]] Result<Stacktrace> captureStacktrace(unsigned skipFrames = 0) MIJIN_NOEXCEPT;
[[nodiscard]] const Optional<Stacktrace>& getExceptionStacktrace() noexcept; [[nodiscard]] const Optional<Stacktrace>& getExceptionStacktrace() MIJIN_NOEXCEPT;
template<typename TStream> template<typename TStream>
TStream& operator<<(TStream& stream, const Stackframe& stackframe) TStream& operator<<(TStream& stream, const Stackframe& stackframe)

View File

@ -0,0 +1,4 @@
#pragma once
#include "./exception.hpp"

View 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)

View File

@ -140,7 +140,7 @@ StreamFeatures ProcessStream::getFeatures()
return {}; return {};
} }
std::string shellEscape(const std::string& arg) noexcept std::string shellEscape(const std::string& arg) MIJIN_NOEXCEPT
{ {
std::ostringstream oss; std::ostringstream oss;
const bool requiresQuotes = std::any_of(arg.begin(), arg.end(), [&](const char chr) { return std::isspace(chr); }); 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(); 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; using namespace mijin::pipe;
return args return args

View File

@ -5,6 +5,7 @@
#include <vector> #include <vector>
#include "./stream.hpp" #include "./stream.hpp"
#include "../internal/common.hpp"
namespace mijin namespace mijin
{ {
@ -35,8 +36,8 @@ public:
StreamFeatures getFeatures() override; StreamFeatures getFeatures() override;
}; };
[[nodiscard]] std::string shellEscape(const std::string& arg) noexcept; [[nodiscard]] std::string shellEscape(const std::string& arg) MIJIN_NOEXCEPT;
[[nodiscard]] std::string makeShellCommand(const std::vector<std::string>& args) noexcept; [[nodiscard]] std::string makeShellCommand(const std::vector<std::string>& args) MIJIN_NOEXCEPT;
StreamError ProcessStream::open(const std::vector<std::string>& args, FileOpenMode mode_) StreamError ProcessStream::open(const std::vector<std::string>& args, FileOpenMode mode_)
{ {

View File

@ -12,6 +12,7 @@
#include <string> #include <string>
#include "../async/coroutine.hpp" #include "../async/coroutine.hpp"
#include "../container/typeless_buffer.hpp" #include "../container/typeless_buffer.hpp"
#include "../internal/common.hpp"
#include "../types/result.hpp" #include "../types/result.hpp"
#include "../util/exception.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) switch (error)
{ {

View File

@ -2,6 +2,7 @@
#pragma once #pragma once
#include "../../detect.hpp" #include "../../detect.hpp"
#include "../../internal/common.hpp"
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX #if MIJIN_TARGET_OS == MIJIN_OS_LINUX
#include <fcntl.h> #include <fcntl.h>
@ -18,9 +19,9 @@
namespace mijin::detail namespace mijin::detail
{ {
#if MIJIN_TARGET_OS == MIJIN_OS_WINDOWS #if MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
bool initWSA() noexcept; bool initWSA() MIJIN_NOEXCEPT;
StreamError translateWSAError() noexcept; StreamError translateWSAError() MIJIN_NOEXCEPT;
StreamError translateWinError(DWORD error) noexcept; StreamError translateWinError(DWORD error) MIJIN_NOEXCEPT;
StreamError translateWinError() noexcept; StreamError translateWinError() MIJIN_NOEXCEPT;
#endif // MIJIN_TARGET_OS == MIJIN_OS_WINDOWS #endif // MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
}// namespace mijin::detail }// namespace mijin::detail

View File

@ -35,7 +35,7 @@ namespace mijin
namespace namespace
{ {
inline constexpr std::size_t CONTENT_LENGTH_LIMIT = 100 << 20; // 100MiB 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, "."); std::vector<std::string_view> parts = split(version, ".");
if (parts.size() != 2) 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) 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(); 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; std::map<std::string, std::string> moreHeaders;
if (!request.body.empty()) if (!request.body.empty())
@ -94,7 +94,7 @@ Task<StreamError> HTTPStream::c_writeRequest(const mijin::HTTPRequest& request)
co_return StreamError::SUCCESS; co_return StreamError::SUCCESS;
} }
Task<StreamResult<HTTPResponse>> HTTPStream::c_readResponse() noexcept Task<StreamResult<HTTPResponse>> HTTPStream::c_readResponse() MIJIN_NOEXCEPT
{ {
std::string line; std::string line;
MIJIN_HTTP_READLINE(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, 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; std::string hostname;
if (auto it = request.headers.find("host"); it != request.headers.end()) 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; 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()) 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)); co_return co_await c_request(*ipAddress, port, https, std::move(request));
} }
void HTTPClient::disconnect() noexcept void HTTPClient::disconnect() MIJIN_NOEXCEPT
{ {
if (socket_ == nullptr) if (socket_ == nullptr)
{ {
@ -251,7 +251,7 @@ void HTTPClient::disconnect() noexcept
socket_ = nullptr; 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_) 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); sslStream_ = std::move(sslStream);
stream_.construct(*sslStream_); stream_.construct(*sslStream_);
#else #else
(void) hostname;
return StreamError::NOT_SUPPORTED; return StreamError::NOT_SUPPORTED;
#endif #endif
} }

View File

@ -10,6 +10,7 @@
#include "./socket.hpp" #include "./socket.hpp"
#include "./url.hpp" #include "./url.hpp"
#include "../container/boxed_object.hpp" #include "../container/boxed_object.hpp"
#include "../internal/common.hpp"
#include "../io/stream.hpp" #include "../io/stream.hpp"
namespace mijin namespace mijin
@ -43,14 +44,14 @@ class HTTPStream
private: private:
Stream* base_; Stream* base_;
public: public:
HTTPStream(Stream& base) noexcept : base_(&base) HTTPStream(Stream& base) MIJIN_NOEXCEPT : base_(&base)
{ {
MIJIN_ASSERT(base_ != nullptr, "Invalid parameter for 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: private:
Task<StreamError> c_writeRequest(const HTTPRequest& request) noexcept; Task<StreamError> c_writeRequest(const HTTPRequest& request) MIJIN_NOEXCEPT;
Task<StreamResult<HTTPResponse>> c_readResponse() noexcept; Task<StreamResult<HTTPResponse>> c_readResponse() MIJIN_NOEXCEPT;
}; };
class HTTPClient class HTTPClient
@ -63,12 +64,12 @@ private:
std::uint16_t lastPort_ = 0; std::uint16_t lastPort_ = 0;
bool lastWasHttps_ = false; bool lastWasHttps_ = false;
public: public:
~HTTPClient() noexcept { disconnect(); } ~HTTPClient() MIJIN_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(ip_address_t address, std::uint16_t port, bool https, HTTPRequest request) MIJIN_NOEXCEPT;
Task<StreamResult<HTTPResponse>> c_request(const URL& url, HTTPRequest request = {}) noexcept; Task<StreamResult<HTTPResponse>> c_request(const URL& url, HTTPRequest request = {}) MIJIN_NOEXCEPT;
void disconnect() noexcept; void disconnect() MIJIN_NOEXCEPT;
private: 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;
}; };
} }

View File

@ -32,7 +32,7 @@ StreamError translateGAIError(int error)
return StreamError::UNKNOWN_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()}; 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; 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; 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) if (const int error = gai_error(&handle.item); error != 0)
{ {
@ -112,7 +112,7 @@ struct WSAQueryContext
}; };
using os_resolve_handle_t = 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; (void) bytes;
@ -153,7 +153,7 @@ void WINAPI getAddrComplete(DWORD error, DWORD bytes, LPOVERLAPPED overlapped) n
queryContext.result = std::move(resultAddresses); 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()) if (!detail::initWSA())
{ {
@ -181,12 +181,12 @@ StreamError osBeginResolve(const std::string& hostname, os_resolve_handle_t& que
return StreamError::SUCCESS; return StreamError::SUCCESS;
} }
bool osResolveDone(os_resolve_handle_t& queryContext) noexcept bool osResolveDone(os_resolve_handle_t& queryContext) MIJIN_NOEXCEPT
{ {
return !queryContext.result.isEmpty(); 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; return queryContext.result;
} }
@ -204,7 +204,7 @@ std::string IPv6Address::toString() const
hextets[5], hextets[6], hextets[7]); 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}); std::vector<std::string_view> parts = split(stringView, ".", {.limitParts = 4});
if (parts.size() != 4) { if (parts.size() != 4) {
@ -221,7 +221,7 @@ Optional<IPv4Address> IPv4Address::fromString(std::string_view stringView) noexc
return address; 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 // very specific edge case
if (stringView.contains(":::")) if (stringView.contains(":::"))
@ -275,7 +275,7 @@ Optional<IPv6Address> IPv6Address::fromString(std::string_view stringView) noexc
return address; 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; os_resolve_handle_t resolveHandle;
if (StreamError error = osBeginResolve(hostname, resolveHandle); error != StreamError::SUCCESS) if (StreamError error = osBeginResolve(hostname, resolveHandle); error != StreamError::SUCCESS)

View File

@ -7,6 +7,7 @@
#include <variant> #include <variant>
#include "../async/coroutine.hpp" #include "../async/coroutine.hpp"
#include "../container/optional.hpp" #include "../container/optional.hpp"
#include "../internal/common.hpp"
#include "../io/stream.hpp" // TODO: rename Stream{Error,Result} to IO{*} #include "../io/stream.hpp" // TODO: rename Stream{Error,Result} to IO{*}
namespace mijin namespace mijin
@ -15,29 +16,29 @@ struct IPv4Address
{ {
std::array<std::uint8_t, 4> octets; 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]] std::string toString() const;
[[nodiscard]] [[nodiscard]]
static Optional<IPv4Address> fromString(std::string_view stringView) noexcept; static Optional<IPv4Address> fromString(std::string_view stringView) MIJIN_NOEXCEPT;
}; };
struct IPv6Address struct IPv6Address
{ {
std::array<std::uint16_t, 8> hextets; 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]] std::string toString() const;
[[nodiscard]] [[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>; using ip_address_t = std::variant<IPv4Address, IPv6Address>;
[[nodiscard]] [[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()) if (address.valueless_by_exception())
{ {
@ -47,7 +48,7 @@ inline std::string ipAddressToString(const ip_address_t& address) noexcept
} }
[[nodiscard]] [[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()) 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]] [[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]] [[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())); return c_resolveHostname(std::string(hostname.begin(), hostname.end()));
} }
[[nodiscard]] [[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)); return c_resolveHostname(std::string(hostname));
} }

View File

@ -13,6 +13,7 @@
#include <openssl/x509_vfy.h> #include <openssl/x509_vfy.h>
#include "../debug/assert.hpp" #include "../debug/assert.hpp"
#include "../internal/common.hpp"
#include "../types/result.hpp" #include "../types/result.hpp"
namespace ossl namespace ossl
@ -34,10 +35,10 @@ struct [[nodiscard]] Error
std::vector<ErrorFrame> frames; std::vector<ErrorFrame> frames;
[[nodiscard]] [[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(int sslError = -1) MIJIN_NOEXCEPT;
static inline Error current(SSL* handle, int result) noexcept { return current(SSL_get_error(handle, result)); } static inline Error current(SSL* handle, int result) MIJIN_NOEXCEPT { return current(SSL_get_error(handle, result)); }
}; };
template<typename TSuccess> template<typename TSuccess>
using Result = mijin::ResultBase<TSuccess, Error>; using Result = mijin::ResultBase<TSuccess, Error>;
@ -53,24 +54,24 @@ protected:
THandle handle_ = nullptr; THandle handle_ = nullptr;
protected: protected:
explicit Base(THandle handle) noexcept : handle_(handle) {} explicit Base(THandle handle) MIJIN_NOEXCEPT : handle_(handle) {}
public: public:
Base() noexcept = default; Base() MIJIN_NOEXCEPT = default;
Base(const Base& other) noexcept : handle_(other.handle_) Base(const Base& other) MIJIN_NOEXCEPT : handle_(other.handle_)
{ {
if (handle_) if (handle_)
{ {
TActual::upReferences(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(); static_cast<TActual&>(*this).free();
} }
TActual& operator=(const Base& other) noexcept TActual& operator=(const Base& other) MIJIN_NOEXCEPT
{ {
if (this == &other) if (this == &other)
{ {
@ -85,7 +86,7 @@ public:
return static_cast<TActual&>(*this); return static_cast<TActual&>(*this);
} }
TActual& operator=(Base&& other) noexcept TActual& operator=(Base&& other) MIJIN_NOEXCEPT
{ {
if (this == &other) if (this == &other)
{ {
@ -95,22 +96,22 @@ public:
handle_ = std::exchange(other.handle_, {}); handle_ = std::exchange(other.handle_, {});
return static_cast<TActual&>(*this); return static_cast<TActual&>(*this);
} }
auto operator<=>(const Base&) const noexcept = default; auto operator<=>(const Base&) const MIJIN_NOEXCEPT = default;
operator bool() const noexcept { return static_cast<bool>(handle_); } operator bool() const MIJIN_NOEXCEPT { return static_cast<bool>(handle_); }
bool operator!() const noexcept { return !static_cast<bool>(handle_); } bool operator!() const MIJIN_NOEXCEPT { return !static_cast<bool>(handle_); }
[[nodiscard]] [[nodiscard]]
THandle getHandle() const noexcept { return handle_; } THandle getHandle() const MIJIN_NOEXCEPT { return handle_; }
[[nodiscard]] [[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*> class X509Store : public Base<X509Store, X509_STORE*>
{ {
public: public:
using Base::Base; using Base::Base;
Error create() noexcept Error create() MIJIN_NOEXCEPT
{ {
MIJIN_ASSERT(handle_ == nullptr, "X509 Store already created."); MIJIN_ASSERT(handle_ == nullptr, "X509 Store already created.");
ERR_clear_error(); ERR_clear_error();
@ -122,7 +123,7 @@ public:
return {}; return {};
} }
void free() noexcept void free() MIJIN_NOEXCEPT
{ {
if (handle_ != nullptr) 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(); ERR_clear_error();
if (!X509_STORE_load_file(handle_, file)) if (!X509_STORE_load_file(handle_, file))
@ -141,7 +142,7 @@ public:
return {}; return {};
} }
static void upReferences(X509_STORE* handle) noexcept static void upReferences(X509_STORE* handle) MIJIN_NOEXCEPT
{ {
X509_STORE_up_ref(handle); X509_STORE_up_ref(handle);
} }
@ -150,7 +151,7 @@ public:
class Context : public Base<Context, SSL_CTX*> class Context : public Base<Context, SSL_CTX*>
{ {
public: public:
Error create(const SSL_METHOD* method) noexcept Error create(const SSL_METHOD* method) MIJIN_NOEXCEPT
{ {
MIJIN_ASSERT(handle_ == nullptr, "Context already created."); MIJIN_ASSERT(handle_ == nullptr, "Context already created.");
ERR_clear_error(); ERR_clear_error();
@ -162,7 +163,7 @@ public:
return {}; return {};
} }
void free() noexcept void free() MIJIN_NOEXCEPT
{ {
if (handle_ == nullptr) if (handle_ == nullptr)
{ {
@ -172,17 +173,17 @@ public:
handle_ = nullptr; 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); 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()); SSL_CTX_set_cert_store(handle_, store.releaseHandle());
} }
Error setMinProtoVersion(int version) const noexcept Error setMinProtoVersion(int version) const MIJIN_NOEXCEPT
{ {
ERR_clear_error(); ERR_clear_error();
if (!SSL_CTX_set_min_proto_version(handle_, version)) if (!SSL_CTX_set_min_proto_version(handle_, version))
@ -192,7 +193,7 @@ public:
return {}; return {};
} }
static void upReferences(SSL_CTX* handle) noexcept static void upReferences(SSL_CTX* handle) MIJIN_NOEXCEPT
{ {
SSL_CTX_up_ref(handle); SSL_CTX_up_ref(handle);
} }
@ -201,7 +202,7 @@ public:
class Bio : public Base<Bio, BIO*> class Bio : public Base<Bio, BIO*>
{ {
public: 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(handle_ == nullptr, "Ssl already created.");
MIJIN_ASSERT(otherBio.handle_ == nullptr, "Ssl already created."); MIJIN_ASSERT(otherBio.handle_ == nullptr, "Ssl already created.");
@ -213,7 +214,7 @@ public:
return {}; return {};
} }
void free() noexcept void free() MIJIN_NOEXCEPT
{ {
if (handle_ == nullptr) if (handle_ == nullptr)
{ {
@ -224,18 +225,18 @@ public:
} }
[[nodiscard]] [[nodiscard]]
std::size_t ctrlPending() const noexcept std::size_t ctrlPending() const MIJIN_NOEXCEPT
{ {
return BIO_ctrl_pending(handle_); return BIO_ctrl_pending(handle_);
} }
[[nodiscard]] [[nodiscard]]
std::size_t ctrlWPending() const noexcept std::size_t ctrlWPending() const MIJIN_NOEXCEPT
{ {
return BIO_ctrl_wpending(handle_); 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(); ERR_clear_error();
const int result = BIO_write(handle_, data, length); const int result = BIO_write(handle_, data, length);
@ -246,7 +247,7 @@ public:
return result; return result;
} }
Result<int> read(void* data, int length) const noexcept Result<int> read(void* data, int length) const MIJIN_NOEXCEPT
{ {
ERR_clear_error(); ERR_clear_error();
const int result = BIO_read(handle_, data, length); const int result = BIO_read(handle_, data, length);
@ -258,24 +259,24 @@ public:
} }
[[nodiscard]] [[nodiscard]]
int getReadRequest() const noexcept int getReadRequest() const MIJIN_NOEXCEPT
{ {
return BIO_get_read_request(handle_); return BIO_get_read_request(handle_);
} }
[[nodiscard]] [[nodiscard]]
int getWriteGuarantee() const noexcept int getWriteGuarantee() const MIJIN_NOEXCEPT
{ {
return BIO_get_write_guarantee(handle_); return BIO_get_write_guarantee(handle_);
} }
[[nodiscard]] [[nodiscard]]
int getWritePending() const noexcept int getWritePending() const MIJIN_NOEXCEPT
{ {
return BIO_wpending(handle_); return BIO_wpending(handle_);
} }
Error flush() const noexcept Error flush() const MIJIN_NOEXCEPT
{ {
ERR_clear_error(); ERR_clear_error();
if (!BIO_flush(handle_)) if (!BIO_flush(handle_))
@ -285,7 +286,7 @@ public:
return {}; return {};
} }
static void upReferences(BIO* handle) noexcept static void upReferences(BIO* handle) MIJIN_NOEXCEPT
{ {
BIO_up_ref(handle); BIO_up_ref(handle);
} }
@ -294,7 +295,7 @@ public:
class Ssl : public Base<Ssl, SSL*> class Ssl : public Base<Ssl, SSL*>
{ {
public: public:
Error create(const Context& context) noexcept Error create(const Context& context) MIJIN_NOEXCEPT
{ {
MIJIN_ASSERT(handle_ == nullptr, "Ssl already created."); MIJIN_ASSERT(handle_ == nullptr, "Ssl already created.");
ERR_clear_error(); ERR_clear_error();
@ -306,7 +307,7 @@ public:
return {}; return {};
} }
void free() noexcept void free() MIJIN_NOEXCEPT
{ {
if (handle_ == nullptr) if (handle_ == nullptr)
{ {
@ -316,18 +317,18 @@ public:
handle_ = nullptr; 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()); 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(); BIO* bioHandle = bio.releaseHandle();
SSL_set_bio(handle_, bioHandle, bioHandle); SSL_set_bio(handle_, bioHandle, bioHandle);
} }
Error setTLSExtHostname(const char* hostname) const noexcept Error setTLSExtHostname(const char* hostname) const MIJIN_NOEXCEPT
{ {
ERR_clear_error(); ERR_clear_error();
if (const int result = SSL_set_tlsext_host_name(handle_, hostname); result != 1) if (const int result = SSL_set_tlsext_host_name(handle_, hostname); result != 1)
@ -337,7 +338,7 @@ public:
return {}; return {};
} }
Error setHost(const char* hostname) const noexcept Error setHost(const char* hostname) const MIJIN_NOEXCEPT
{ {
ERR_clear_error(); ERR_clear_error();
if (const int result = SSL_set1_host(handle_, hostname); result != 1) if (const int result = SSL_set1_host(handle_, hostname); result != 1)
@ -347,7 +348,7 @@ public:
return {}; return {};
} }
Error connect() const noexcept Error connect() const MIJIN_NOEXCEPT
{ {
ERR_clear_error(); ERR_clear_error();
if (const int result = SSL_connect(handle_); result != 1) if (const int result = SSL_connect(handle_); result != 1)
@ -357,7 +358,7 @@ public:
return {}; return {};
} }
Error shutdown() const noexcept Error shutdown() const MIJIN_NOEXCEPT
{ {
ERR_clear_error(); ERR_clear_error();
if (const int result = SSL_shutdown(handle_); result != 1) if (const int result = SSL_shutdown(handle_); result != 1)
@ -372,12 +373,12 @@ public:
} }
[[nodiscard]] [[nodiscard]]
long getVerifyResult() const noexcept long getVerifyResult() const MIJIN_NOEXCEPT
{ {
return SSL_get_verify_result(handle_); 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(); ERR_clear_error();
const int result = SSL_write(handle_, data, length); const int result = SSL_write(handle_, data, length);
@ -388,7 +389,7 @@ public:
return result; return result;
} }
Result<int> read(void* data, int length) const noexcept Result<int> read(void* data, int length) const MIJIN_NOEXCEPT
{ {
ERR_clear_error(); ERR_clear_error();
const int result = SSL_read(handle_, data, length); const int result = SSL_read(handle_, data, length);
@ -400,18 +401,18 @@ public:
} }
[[nodiscard]] [[nodiscard]]
int pending() const noexcept int pending() const MIJIN_NOEXCEPT
{ {
return SSL_pending(handle_); return SSL_pending(handle_);
} }
static void upReferences(SSL* handle) noexcept static void upReferences(SSL* handle) MIJIN_NOEXCEPT
{ {
SSL_up_ref(handle); SSL_up_ref(handle);
} }
}; };
Error Error::current(int sslError_) noexcept Error Error::current(int sslError_) MIJIN_NOEXCEPT
{ {
Error error = { Error error = {
.sslError = sslError_ .sslError = sslError_

View File

@ -3,6 +3,7 @@
#include "./detail/net_common.hpp" #include "./detail/net_common.hpp"
#include "../detect.hpp" #include "../detect.hpp"
#include "../internal/common.hpp"
#include "../util/variant.hpp" #include "../util/variant.hpp"
namespace mijin namespace mijin
@ -10,7 +11,7 @@ namespace mijin
namespace namespace
{ {
inline constexpr int LISTEN_BACKLOG = 3; inline constexpr int LISTEN_BACKLOG = 3;
StreamError translateErrno() noexcept StreamError translateErrno() MIJIN_NOEXCEPT
{ {
switch (errno) switch (errno)
{ {
@ -30,7 +31,7 @@ int readFlags(const ReadOptions& options)
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX #if MIJIN_TARGET_OS == MIJIN_OS_LINUX
const int SOCKOPT_ONE = 1; 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); const int currentFlags = fcntl(handle, F_GETFL);
if (currentFlags < 0) if (currentFlags < 0)
@ -40,7 +41,7 @@ bool appendSocketFlags(int handle, int flags) noexcept
return fcntl(handle, F_SETFL, currentFlags | flags) >= 0; 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); const int currentFlags = fcntl(handle, F_GETFL);
if (currentFlags < 0) if (currentFlags < 0)
@ -50,32 +51,32 @@ bool removeSocketFlags(int handle, int flags) noexcept
return fcntl(handle, F_SETFL, currentFlags & ~flags) >= 0; 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)); 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)); 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); return socket(domain, type, protocol);
} }
int osCloseSocket(int socket) int osCloseSocket(int socket) MIJIN_NOEXCEPT
{ {
return ::close(socket); return ::close(socket);
} }
bool osIsSocketValid(int socket) bool osIsSocketValid(int socket) MIJIN_NOEXCEPT
{ {
return socket >= 0; return socket >= 0;
} }
bool osSetSocketNonBlocking(int socket, bool blocking) bool osSetSocketNonBlocking(int socket, bool blocking) MIJIN_NOEXCEPT
{ {
if (blocking) if (blocking)
{ {
@ -95,7 +96,7 @@ thread_local bool gWsaInited = false;
class WSAGuard class WSAGuard
{ {
public: public:
~WSAGuard() noexcept ~WSAGuard() MIJIN_NOEXCEPT
{ {
if (gWsaInited) if (gWsaInited)
{ {
@ -104,17 +105,17 @@ public:
} }
} thread_local [[maybe_unused]] gWsaGuard; } 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); 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); 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()) if (!detail::initWSA())
{ {
@ -123,17 +124,17 @@ SOCKET osCreateSocket(int addressFamily, int type, int protocol)
return socket(addressFamily, type, protocol); return socket(addressFamily, type, protocol);
} }
int osCloseSocket(SOCKET socket) int osCloseSocket(SOCKET socket) MIJIN_NOEXCEPT
{ {
return closesocket(socket); return closesocket(socket);
} }
bool osIsSocketValid(SOCKET socket) bool osIsSocketValid(SOCKET socket) MIJIN_NOEXCEPT
{ {
return socket != INVALID_SOCKET; return socket != INVALID_SOCKET;
} }
bool osSetSocketNonBlocking(SOCKET socket, bool blocking) bool osSetSocketNonBlocking(SOCKET socket, bool blocking) MIJIN_NOEXCEPT
{ {
u_long value = blocking ? 0 : 1; u_long value = blocking ? 0 : 1;
return ioctlsocket(socket, FIONBIO, &value) == NO_ERROR; return ioctlsocket(socket, FIONBIO, &value) == NO_ERROR;
@ -144,7 +145,7 @@ bool osSetSocketNonBlocking(SOCKET socket, bool blocking)
namespace detail namespace detail
{ {
#if MIJIN_TARGET_OS == MIJIN_OS_WINDOWS #if MIJIN_TARGET_OS == MIJIN_OS_WINDOWS
bool initWSA() noexcept bool initWSA() MIJIN_NOEXCEPT
{ {
if (gWsaInited) if (gWsaInited)
{ {
@ -160,20 +161,20 @@ bool initWSA() noexcept
return true; return true;
} }
StreamError translateWSAError() noexcept StreamError translateWSAError() MIJIN_NOEXCEPT
{ {
// TODO // TODO
return StreamError::UNKNOWN_ERROR; return StreamError::UNKNOWN_ERROR;
} }
StreamError translateWinError(DWORD error) noexcept StreamError translateWinError(DWORD error) MIJIN_NOEXCEPT
{ {
// TODO // TODO
(void) error; (void) error;
return StreamError::UNKNOWN_ERROR; return StreamError::UNKNOWN_ERROR;
} }
StreamError translateWinError() noexcept StreamError translateWinError() MIJIN_NOEXCEPT
{ {
return translateWinError(GetLastError()); 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."); 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; return StreamError::SUCCESS;
} }
void TCPStream::close() noexcept void TCPStream::close() MIJIN_NOEXCEPT
{ {
MIJIN_ASSERT(isOpen(), "Socket is not open."); MIJIN_ASSERT(isOpen(), "Socket is not open.");
osCloseSocket(handle_); osCloseSocket(handle_);
handle_ = INVALID_SOCKET_HANDLE; handle_ = INVALID_SOCKET_HANDLE;
} }
TCPStream& TCPSocket::getStream() noexcept TCPStream& TCPSocket::getStream() MIJIN_NOEXCEPT
{ {
return stream_; 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."); 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; return StreamError::SUCCESS;
} }
void TCPServerSocket::close() noexcept void TCPServerSocket::close() MIJIN_NOEXCEPT
{ {
MIJIN_ASSERT(isListening(), "Socket is not listening."); MIJIN_ASSERT(isListening(), "Socket is not listening.");
@ -448,7 +449,7 @@ void TCPServerSocket::close() noexcept
handle_ = INVALID_SOCKET_HANDLE; 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()) while (isListening())
{ {

View File

@ -30,32 +30,32 @@ inline constexpr socket_handle_t INVALID_SOCKET_HANDLE = -1;
class Socket class Socket
{ {
protected: protected:
Socket() noexcept = default; Socket() MIJIN_NOEXCEPT = default;
Socket(const Socket&) noexcept = default; Socket(const Socket&) MIJIN_NOEXCEPT = default;
Socket(Socket&&) noexcept = default; Socket(Socket&&) MIJIN_NOEXCEPT = default;
Socket& operator=(const Socket&) noexcept = default; Socket& operator=(const Socket&) MIJIN_NOEXCEPT = default;
Socket& operator=(Socket&&) noexcept = default; Socket& operator=(Socket&&) MIJIN_NOEXCEPT = default;
public: public:
virtual ~Socket() noexcept = default; virtual ~Socket() MIJIN_NOEXCEPT = default;
virtual Stream& getStream() noexcept = 0; virtual Stream& getStream() MIJIN_NOEXCEPT = 0;
}; };
class ServerSocket class ServerSocket
{ {
protected: protected:
ServerSocket() noexcept = default; ServerSocket() MIJIN_NOEXCEPT = default;
ServerSocket(const ServerSocket&) noexcept = default; ServerSocket(const ServerSocket&) MIJIN_NOEXCEPT = default;
ServerSocket(ServerSocket&&) noexcept = default; ServerSocket(ServerSocket&&) MIJIN_NOEXCEPT = default;
ServerSocket& operator=(const ServerSocket&) noexcept = default; ServerSocket& operator=(const ServerSocket&) MIJIN_NOEXCEPT = default;
ServerSocket& operator=(ServerSocket&&) noexcept = default; ServerSocket& operator=(ServerSocket&&) MIJIN_NOEXCEPT = default;
public: public:
virtual ~ServerSocket() noexcept = default; virtual ~ServerSocket() MIJIN_NOEXCEPT = default;
virtual void close() noexcept = 0; virtual void close() MIJIN_NOEXCEPT = 0;
virtual Task<StreamResult<std::unique_ptr<Socket>>> c_waitForConnection() noexcept = 0; virtual Task<StreamResult<std::unique_ptr<Socket>>> c_waitForConnection() MIJIN_NOEXCEPT = 0;
}; };
class TCPStream : public Stream class TCPStream : public Stream
@ -74,9 +74,9 @@ public:
bool isAtEnd() override; bool isAtEnd() override;
StreamFeatures getFeatures() override; StreamFeatures getFeatures() override;
StreamError open(ip_address_t address, std::uint16_t port) noexcept; StreamError open(ip_address_t address, std::uint16_t port) MIJIN_NOEXCEPT;
void close() noexcept; void close() MIJIN_NOEXCEPT;
[[nodiscard]] bool isOpen() const noexcept { return handle_ != INVALID_SOCKET_HANDLE; } [[nodiscard]] bool isOpen() const MIJIN_NOEXCEPT { return handle_ != INVALID_SOCKET_HANDLE; }
private: private:
void setNoblock(bool async); void setNoblock(bool async);
@ -88,10 +88,10 @@ class TCPSocket : public Socket
private: private:
TCPStream stream_; TCPStream stream_;
public: 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(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) noexcept StreamError open(std::string_view addressText, std::uint16_t port) MIJIN_NOEXCEPT
{ {
if (Optional<ip_address_t> address = ipAddressFromString(addressText); !address.empty()) if (Optional<ip_address_t> address = ipAddressFromString(addressText); !address.empty())
{ {
@ -99,8 +99,8 @@ public:
} }
return StreamError::UNKNOWN_ERROR; return StreamError::UNKNOWN_ERROR;
} }
void close() noexcept { stream_.close(); } void close() MIJIN_NOEXCEPT { stream_.close(); }
[[nodiscard]] bool isOpen() const noexcept { return stream_.isOpen(); } [[nodiscard]] bool isOpen() const MIJIN_NOEXCEPT { return stream_.isOpen(); }
friend class TCPServerSocket; friend class TCPServerSocket;
}; };
@ -110,8 +110,8 @@ class TCPServerSocket : public ServerSocket
private: private:
socket_handle_t handle_ = INVALID_SOCKET_HANDLE; socket_handle_t handle_ = INVALID_SOCKET_HANDLE;
public: public:
StreamError setup(ip_address_t address, 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) noexcept StreamError setup(std::string_view addressText, std::uint16_t port) MIJIN_NOEXCEPT
{ {
if (Optional<ip_address_t> address = ipAddressFromString(addressText); !address.empty()) if (Optional<ip_address_t> address = ipAddressFromString(addressText); !address.empty())
{ {
@ -119,10 +119,10 @@ public:
} }
return StreamError::UNKNOWN_ERROR; return StreamError::UNKNOWN_ERROR;
} }
void close() noexcept override; void close() MIJIN_NOEXCEPT override;
[[nodiscard]] bool isListening() const noexcept { return handle_ >= 0; } [[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;
}; };
} }

View File

@ -9,7 +9,7 @@ namespace mijin
namespace namespace
{ {
inline constexpr int BIO_BUFFER_SIZE = 4096; 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 ossl::Context context;
static std::mutex contextMutex; 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."); 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; return StreamError::SUCCESS;
} }
void SSLStream::close() noexcept void SSLStream::close() MIJIN_NOEXCEPT
{ {
MIJIN_ASSERT(base_ != nullptr, "SSL stream is not open."); MIJIN_ASSERT(base_ != nullptr, "SSL stream is not open.");
base_ = nullptr; 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::array<std::uint8_t, BIO_BUFFER_SIZE> buffer;
std::size_t bytes = std::min(externalBio_.ctrlPending(), buffer.size()); std::size_t bytes = std::min(externalBio_.ctrlPending(), buffer.size());
@ -254,7 +254,7 @@ StreamError SSLStream::bioToBase() noexcept
return StreamError::SUCCESS; return StreamError::SUCCESS;
} }
StreamError SSLStream::baseToBio() noexcept StreamError SSLStream::baseToBio() MIJIN_NOEXCEPT
{ {
std::array<std::uint8_t, BIO_BUFFER_SIZE> buffer; std::array<std::uint8_t, BIO_BUFFER_SIZE> buffer;
std::size_t toRead = externalBio_.getWriteGuarantee(); std::size_t toRead = externalBio_.getWriteGuarantee();

View File

@ -11,6 +11,7 @@
#include <memory> #include <memory>
#include "./openssl_wrappers.hpp" #include "./openssl_wrappers.hpp"
#include "../internal/common.hpp"
#include "../io/stream.hpp" #include "../io/stream.hpp"
namespace mijin namespace mijin
@ -22,15 +23,15 @@ private:
ossl::Ssl ssl_; ossl::Ssl ssl_;
ossl::Bio externalBio_; ossl::Bio externalBio_;
public: public:
~SSLStream() noexcept override ~SSLStream() MIJIN_NOEXCEPT override
{ {
if (base_ != nullptr) if (base_ != nullptr)
{ {
close(); close();
} }
} }
StreamError open(Stream& base, const std::string& hostname) noexcept; StreamError open(Stream& base, const std::string& hostname) MIJIN_NOEXCEPT;
void close() noexcept; void close() MIJIN_NOEXCEPT;
StreamError readRaw(std::span<std::uint8_t> buffer, const ReadOptions& options, std::size_t* outBytesRead) override; 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; StreamError writeRaw(std::span<const std::uint8_t> buffer) override;
@ -40,8 +41,8 @@ public:
bool isAtEnd() override; bool isAtEnd() override;
StreamFeatures getFeatures() override; StreamFeatures getFeatures() override;
private: private:
StreamError bioToBase() noexcept; StreamError bioToBase() MIJIN_NOEXCEPT;
StreamError baseToBio() noexcept; StreamError baseToBio() MIJIN_NOEXCEPT;
template<typename TFunc, typename... TArgs> template<typename TFunc, typename... TArgs>

View File

@ -7,6 +7,7 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include "../internal/common.hpp"
#include "../util/string.hpp" #include "../util/string.hpp"
namespace mijin namespace mijin
@ -28,37 +29,38 @@ private:
string_view_t pathQueryFragment_; string_view_t pathQueryFragment_;
std::uint16_t port_ = 0; std::uint16_t port_ = 0;
public: public:
constexpr URLBase() noexcept = default; constexpr URLBase() MIJIN_NOEXCEPT = default;
constexpr URLBase(const URLBase&) = default; constexpr URLBase(const URLBase&) = default;
constexpr URLBase(URLBase&&) noexcept = default; constexpr URLBase(URLBase&&) MIJIN_NOEXCEPT = default;
constexpr URLBase(string_t base) noexcept : base_(std::move(base)) { parse(); } 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(string_view_t base) : URLBase(string_t(base.begin(), base.end())) {}
constexpr URLBase(const TChar* base) : URLBase(string_t(base)) {} constexpr URLBase(const TChar* base) : URLBase(string_t(base)) {}
constexpr URLBase& operator=(const URLBase&) = default; 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 bool isValid() const MIJIN_NOEXCEPT { return !base_.empty(); }
[[nodiscard]] constexpr string_view_t getScheme() const noexcept { return scheme_; } [[nodiscard]] constexpr const string_t& getBase() const MIJIN_NOEXCEPT { return base_; }
[[nodiscard]] constexpr string_view_t getUserInfo() const noexcept { return userinfo_; } [[nodiscard]] constexpr string_view_t getScheme() const MIJIN_NOEXCEPT { return scheme_; }
[[nodiscard]] constexpr string_view_t getHost() const noexcept { return host_; } [[nodiscard]] constexpr string_view_t getUserInfo() const MIJIN_NOEXCEPT { return userinfo_; }
[[nodiscard]] constexpr string_view_t getPath() const noexcept { return path_; } [[nodiscard]] constexpr string_view_t getHost() const MIJIN_NOEXCEPT { return host_; }
[[nodiscard]] constexpr string_view_t getQuery() const noexcept { return query_; } [[nodiscard]] constexpr string_view_t getPath() const MIJIN_NOEXCEPT { return path_; }
[[nodiscard]] constexpr string_view_t getFragment() const noexcept { return fragment_; } [[nodiscard]] constexpr string_view_t getQuery() const MIJIN_NOEXCEPT { return query_; }
[[nodiscard]] constexpr string_view_t getPathQueryFragment() const noexcept { return pathQueryFragment_; } [[nodiscard]] constexpr string_view_t getFragment() const MIJIN_NOEXCEPT { return fragment_; }
[[nodiscard]] constexpr std::uint16_t getPort() const noexcept { return port_; } [[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: private:
constexpr void parse() noexcept; constexpr void parse() MIJIN_NOEXCEPT;
constexpr bool parseAuthority(string_view_t authority) noexcept; constexpr bool parseAuthority(string_view_t authority) MIJIN_NOEXCEPT;
}; };
using URL = URLBase<char>; using URL = URLBase<char>;
template<typename TChar, typename TTraits, typename TAllocator> 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(); base_.clear();
scheme_ = {}; scheme_ = {};
@ -71,7 +73,7 @@ constexpr void URLBase<TChar, TTraits, TAllocator>::clear() noexcept
} }
template<typename TChar, typename TTraits, typename TAllocator> 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()) if (base_.empty())
{ {
@ -135,7 +137,7 @@ constexpr void URLBase<TChar, TTraits, TAllocator>::parse() noexcept
} }
template<typename TChar, typename TTraits, typename TAllocator> 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; string_view_t toParse = authority;
typename string_view_t::size_type pos = toParse.find(TChar('@')); typename string_view_t::size_type pos = toParse.find(TChar('@'));

View File

@ -9,6 +9,7 @@
#if __has_include(<fmt/format.h>) #if __has_include(<fmt/format.h>)
# include <fmt/format.h> # include <fmt/format.h>
#endif #endif
#include "../internal/common.hpp"
namespace mijin namespace mijin
{ {
@ -37,8 +38,8 @@ public:
Name& operator=(const Name&) = default; Name& operator=(const Name&) = default;
auto operator<=>(const Name&) const = default; auto operator<=>(const Name&) const = default;
constexpr operator bool() const noexcept { return id_ != std::numeric_limits<std::size_t>::max(); } constexpr operator bool() const MIJIN_NOEXCEPT { return id_ != std::numeric_limits<std::size_t>::max(); }
constexpr bool operator!() const noexcept { return !static_cast<bool>(*this); } constexpr bool operator!() const MIJIN_NOEXCEPT { return !static_cast<bool>(*this); }
[[nodiscard]] std::string_view stringView() const; [[nodiscard]] std::string_view stringView() const;
[[nodiscard]] const char* c_str() const { [[nodiscard]] const char* c_str() const {
@ -57,7 +58,7 @@ public:
template<> template<>
struct std::hash<mijin::Name> : hash<std::size_t> 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()); return hash<std::size_t>::operator()(name.getID());
} }
}; };

View File

@ -7,6 +7,8 @@
#include <string> #include <string>
#include <variant> #include <variant>
#include "../internal/common.hpp"
namespace mijin namespace mijin
{ {
@ -30,32 +32,32 @@ private:
std::variant<Empty, TSuccess, TError> state_; std::variant<Empty, TSuccess, TError> state_;
public: public:
ResultBase() = default; ResultBase() MIJIN_NOEXCEPT = default;
ResultBase(const ResultBase&) = default; ResultBase(const ResultBase&) MIJIN_NOEXCEPT = default;
ResultBase(ResultBase&&) = default; ResultBase(ResultBase&&) MIJIN_NOEXCEPT = default;
ResultBase(TSuccess successValue) noexcept : state_(std::move(successValue)) {} ResultBase(TSuccess successValue) MIJIN_NOEXCEPT : state_(std::move(successValue)) {}
ResultBase(TError errorValue) noexcept : state_(std::move(errorValue)) {} ResultBase(TError errorValue) MIJIN_NOEXCEPT : state_(std::move(errorValue)) {}
ResultBase& operator=(const ResultBase&) = default; ResultBase& operator=(const ResultBase&) = default;
ResultBase& operator=(ResultBase&&) = default; ResultBase& operator=(ResultBase&&) = default;
bool operator==(const ResultBase& other) const noexcept { return state_ == other.state_; } bool operator==(const ResultBase& other) const MIJIN_NOEXCEPT { return state_ == other.state_; }
bool operator!=(const ResultBase& other) const noexcept { return state_ != other.state_; } bool operator!=(const ResultBase& other) const MIJIN_NOEXCEPT { return state_ != other.state_; }
operator bool() const noexcept { return isSuccess(); } operator bool() const MIJIN_NOEXCEPT { return isSuccess(); }
bool operator!() const noexcept { return !isSuccess(); } bool operator!() const MIJIN_NOEXCEPT { return !isSuccess(); }
TSuccess& operator*() noexcept { return getValue(); } TSuccess& operator*() MIJIN_NOEXCEPT { return getValue(); }
const TSuccess& operator*() const noexcept { return getValue(); } const TSuccess& operator*() const MIJIN_NOEXCEPT { return getValue(); }
TSuccess* operator->() noexcept { return &getValue(); } TSuccess* operator->() MIJIN_NOEXCEPT { return &getValue(); }
const TSuccess* operator->() const noexcept { return &getValue(); } const TSuccess* operator->() const MIJIN_NOEXCEPT { return &getValue(); }
[[nodiscard]] bool isEmpty() const noexcept { return std::holds_alternative<Empty>(state_); } [[nodiscard]] bool isEmpty() const MIJIN_NOEXCEPT { return std::holds_alternative<Empty>(state_); }
[[nodiscard]] bool isSuccess() const noexcept { return std::holds_alternative<TSuccess>(state_); } [[nodiscard]] bool isSuccess() const MIJIN_NOEXCEPT { return std::holds_alternative<TSuccess>(state_); }
[[nodiscard]] bool isError() const noexcept { return std::holds_alternative<TError>(state_); } [[nodiscard]] bool isError() const MIJIN_NOEXCEPT { return std::holds_alternative<TError>(state_); }
[[nodiscard]] TSuccess& getValue() noexcept { return std::get<TSuccess>(state_); } [[nodiscard]] TSuccess& getValue() MIJIN_NOEXCEPT { return std::get<TSuccess>(state_); }
[[nodiscard]] TError& getError() noexcept { return std::get<TError>(state_); } [[nodiscard]] TError& getError() MIJIN_NOEXCEPT { return std::get<TError>(state_); }
[[nodiscard]] const TSuccess& getValue() const noexcept { return std::get<TSuccess>(state_); } [[nodiscard]] const TSuccess& getValue() const MIJIN_NOEXCEPT { return std::get<TSuccess>(state_); }
[[nodiscard]] const TError& getError() const noexcept { return std::get<TError>(state_); } [[nodiscard]] const TError& getError() const MIJIN_NOEXCEPT { return std::get<TError>(state_); }
}; };
struct ResultError struct ResultError
@ -64,11 +66,11 @@ struct ResultError
ResultError() : message("Unknown error") {} ResultError() : message("Unknown error") {}
ResultError(const ResultError&) = default; ResultError(const ResultError&) = default;
ResultError(ResultError&&) noexcept = default; ResultError(ResultError&&) MIJIN_NOEXCEPT = default;
ResultError(std::string msg) noexcept : message(std::move(msg)) {} ResultError(std::string msg) MIJIN_NOEXCEPT : message(std::move(msg)) {}
ResultError& operator=(const ResultError&) = default; ResultError& operator=(const ResultError&) = default;
ResultError& operator=(ResultError&&) noexcept = default; ResultError& operator=(ResultError&&) MIJIN_NOEXCEPT = default;
}; };
template<typename TSuccess> template<typename TSuccess>

View File

@ -11,6 +11,7 @@
#include <vector> #include <vector>
#include "../container/optional.hpp" #include "../container/optional.hpp"
#include "../internal/common.hpp"
#include "../util/traits.hpp" #include "../util/traits.hpp"
#include "../util/variant.hpp" #include "../util/variant.hpp"
@ -73,14 +74,14 @@ public:
private: private:
base_t base_ = UndefinedValue(); base_t base_ = UndefinedValue();
public: public:
ScriptValue() noexcept = default; ScriptValue() MIJIN_NOEXCEPT = default;
ScriptValue(const ScriptValue&) noexcept = default; ScriptValue(const ScriptValue&) MIJIN_NOEXCEPT = default;
ScriptValue(ScriptValue&&) noexcept = default; ScriptValue(ScriptValue&&) MIJIN_NOEXCEPT = default;
template<typename TValue> template<typename TValue>
ScriptValue(TValue&& value); ScriptValue(TValue&& value);
ScriptValue& operator=(const ScriptValue&) = default; 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; std::partial_ordering operator<=>(const ScriptValue& other) const = default;
@ -91,7 +92,7 @@ public:
} }
[[nodiscard]] [[nodiscard]]
Optional<script_int_t> toInt() const noexcept Optional<script_int_t> toInt() const MIJIN_NOEXCEPT
{ {
return visit([&](auto&& value) -> Optional<script_int_t> return visit([&](auto&& value) -> Optional<script_int_t>
{ {
@ -118,7 +119,7 @@ public:
} }
[[nodiscard]] [[nodiscard]]
Optional<script_float_t> toFloat() const noexcept Optional<script_float_t> toFloat() const MIJIN_NOEXCEPT
{ {
return visit([&](auto&& value) -> Optional<script_float_t> return visit([&](auto&& value) -> Optional<script_float_t>
{ {
@ -145,7 +146,7 @@ public:
} }
[[nodiscard]] [[nodiscard]]
Optional<std::string> toString() const noexcept Optional<std::string> toString() const MIJIN_NOEXCEPT
{ {
return visit([](auto&& value) -> Optional<std::string> return visit([](auto&& value) -> Optional<std::string>
{ {
@ -175,7 +176,7 @@ public:
template<typename T> template<typename T>
[[nodiscard]] [[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>; using type_t = std::decay_t<T>;
if constexpr (std::is_same_v<type_t, script_int_t>) if constexpr (std::is_same_v<type_t, script_int_t>)

View File

@ -5,6 +5,7 @@
#define MIJIN_TYPES_TYPEDEF_HPP_INCLUDED 1 #define MIJIN_TYPES_TYPEDEF_HPP_INCLUDED 1
#include <utility> #include <utility>
#include "../internal/common.hpp"
namespace mijin namespace mijin
{ {
@ -48,9 +49,9 @@ public:
return *this; return *this;
} }
explicit constexpr operator const TBase&() const noexcept { return value; } explicit constexpr operator const TBase&() const MIJIN_NOEXCEPT { return value; }
explicit constexpr operator TBase&() noexcept { return value; } explicit constexpr operator TBase&() MIJIN_NOEXCEPT { return value; }
auto operator<=>(const TypeDef&) const noexcept = default; auto operator<=>(const TypeDef&) const MIJIN_NOEXCEPT = default;
}; };
template<typename TBase, typename TTag> requires (!std::is_fundamental_v<TBase>) template<typename TBase, typename TTag> requires (!std::is_fundamental_v<TBase>)

View File

@ -4,10 +4,12 @@
#if !defined(MIJIN_UTIL_ALIGN_HPP_INCLUDED) #if !defined(MIJIN_UTIL_ALIGN_HPP_INCLUDED)
#define MIJIN_UTIL_ALIGN_HPP_INCLUDED 1 #define MIJIN_UTIL_ALIGN_HPP_INCLUDED 1
#include "../internal/common.hpp"
namespace mijin namespace mijin
{ {
template<typename T> template<typename T>
constexpr T alignUp(T value, T alignTo) noexcept constexpr T alignUp(T value, T alignTo) MIJIN_NOEXCEPT
{ {
if (value % alignTo != 0) if (value % alignTo != 0)
{ {

View File

@ -7,6 +7,7 @@
#include <cstdint> #include <cstdint>
#include "./traits.hpp" #include "./traits.hpp"
#include "./types.hpp" #include "./types.hpp"
#include "../internal/common.hpp"
namespace mijin namespace mijin
{ {
@ -15,23 +16,23 @@ namespace mijin
// public defines // public defines
// //
#define MIJIN_DEFINE_FLAG(name) \ #define MIJIN_DEFINE_FLAG(name) \
struct name : mijin::Flag \ struct name : mijin::Flag \
{ \ { \
private: \ private: \
struct Proxy_ { \ struct Proxy_ { \
uint8_t value; \ uint8_t value; \
}; \ }; \
public: \ public: \
constexpr name() = default; \ constexpr name() = default; \
constexpr name(const name&) = default; \ constexpr name(const name&) = default; \
constexpr name(Proxy_ proxy) \ constexpr name(Proxy_ proxy) MIJIN_NOEXCEPT \
: Flag(proxy.value) {} \ : Flag(proxy.value) {} \
constexpr explicit name(bool value) noexcept \ constexpr explicit name(bool value) MIJIN_NOEXCEPT \
: Flag(value) {} \ : Flag(value) {} \
name& operator=(const name&) = default; \ name& operator=(const name&) = default; \
static constexpr Proxy_ YES{1}; \ static constexpr Proxy_ YES{1}; \
static constexpr Proxy_ NO{0}; \ static constexpr Proxy_ NO{0}; \
} }
// //
@ -48,23 +49,23 @@ struct Flag
Flag() = default; Flag() = default;
Flag(const 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; 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; 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; return value != other.value;
} }
constexpr bool operator !() const noexcept constexpr bool operator !() const MIJIN_NOEXCEPT
{ {
return !value; return !value;
} }
constexpr operator bool() const noexcept constexpr operator bool() const MIJIN_NOEXCEPT
{ {
return value != 0; return value != 0;
} }
@ -89,7 +90,7 @@ private:
using base_t = FlagSetStorage<offset + 1, TMore...>; using base_t = FlagSetStorage<offset + 1, TMore...>;
static constexpr typename base_t::data_t BIT = (1 << offset); static constexpr typename base_t::data_t BIT = (1 << offset);
public: public:
constexpr void set(TFirst value) noexcept constexpr void set(TFirst value) MIJIN_NOEXCEPT
{ {
if (value) if (value)
{ {
@ -100,7 +101,7 @@ public:
base_t::data_ &= ~BIT; base_t::data_ &= ~BIT;
} }
} }
constexpr bool get(TFirst) noexcept constexpr bool get(TFirst) MIJIN_NOEXCEPT
{ {
return (base_t::data_ & BIT) != 0; return (base_t::data_ & BIT) != 0;
} }
@ -134,19 +135,19 @@ public:
public: public:
FlagSet& operator=(const FlagSet&) = default; FlagSet& operator=(const FlagSet&) = default;
template<FlagType T> requires is_any_type_v<T, TFlags...> template<FlagType T> requires is_any_type_v<T, TFlags...>
FlagSet& operator=(T flag) noexcept FlagSet& operator=(T flag) MIJIN_NOEXCEPT
{ {
reset(flag); reset(flag);
return *this; return *this;
} }
template<FlagType T> requires is_any_type_v<T, TFlags...> template<FlagType T> requires is_any_type_v<T, TFlags...>
FlagSet& operator|=(T flag) noexcept FlagSet& operator|=(T flag) MIJIN_NOEXCEPT
{ {
set(flag); set(flag);
return *this; return *this;
} }
template<FlagType T> requires is_any_type_v<T, TFlags...> template<FlagType T> requires is_any_type_v<T, TFlags...>
FlagSet& operator&=(T flag) noexcept FlagSet& operator&=(T flag) MIJIN_NOEXCEPT
{ {
unset(flag); unset(flag);
} }

View File

@ -11,6 +11,7 @@
#include <tuple> #include <tuple>
#include <variant> #include <variant>
#include "../container/optional.hpp" #include "../container/optional.hpp"
#include "../internal/common.hpp"
namespace mijin namespace mijin
{ {
@ -96,50 +97,50 @@ struct EnumeratingIterator
TIdx idx; TIdx idx;
TIterator base; TIterator base;
EnumeratingIterator(TIdx idx_, TIterator base_) noexcept : idx(idx_), base(base_) {} EnumeratingIterator(TIdx idx_, TIterator base_) MIJIN_NOEXCEPT : idx(idx_), base(base_) {}
EnumeratingIterator(const EnumeratingIterator&) noexcept = default; 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); return std::tie(idx, *base);
} }
EnumeratingIterator& operator++() noexcept EnumeratingIterator& operator++() MIJIN_NOEXCEPT
{ {
++idx; ++idx;
++base; ++base;
return *this; return *this;
} }
EnumeratingIterator operator++(int) noexcept EnumeratingIterator operator++(int) MIJIN_NOEXCEPT
{ {
EnumeratingIterator copy(*this); EnumeratingIterator copy(*this);
++(*this); ++(*this);
return copy; return copy;
} }
EnumeratingIterator& operator--() noexcept EnumeratingIterator& operator--() MIJIN_NOEXCEPT
{ {
--idx; --idx;
--base; --base;
return *this; return *this;
} }
EnumeratingIterator operator--(int) noexcept EnumeratingIterator operator--(int) MIJIN_NOEXCEPT
{ {
EnumeratingIterator copy(*this); EnumeratingIterator copy(*this);
--(*this); --(*this);
return copy; 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() 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() 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; RangeRef<TIterable> base;
auto begin() const noexcept auto begin() const MIJIN_NOEXCEPT
{ {
return EnumeratingIterator(TIdx(0), base.begin()); return EnumeratingIterator(TIdx(0), base.begin());
} }
auto end() const noexcept auto end() const MIJIN_NOEXCEPT
{ {
return EnumeratingIterator(TIdx(0), base.end()); return EnumeratingIterator(TIdx(0), base.end());
} }
@ -175,50 +176,50 @@ struct ZippingIterator
TFirstIterator first; TFirstIterator first;
TSecondIterator second; TSecondIterator second;
ZippingIterator(TFirstIterator first_, TSecondIterator second_) noexcept : first(first_), second(second_) {} ZippingIterator(TFirstIterator first_, TSecondIterator second_) MIJIN_NOEXCEPT : first(first_), second(second_) {}
ZippingIterator(const ZippingIterator&) noexcept = default; 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); return std::tie(*first, *second);
} }
ZippingIterator& operator++() noexcept ZippingIterator& operator++() MIJIN_NOEXCEPT
{ {
++first; ++first;
++second; ++second;
return *this; return *this;
} }
ZippingIterator operator++(int) noexcept ZippingIterator operator++(int) MIJIN_NOEXCEPT
{ {
ZippingIterator copy(*this); ZippingIterator copy(*this);
++(*this); ++(*this);
return copy; return copy;
} }
ZippingIterator& operator--() noexcept ZippingIterator& operator--() MIJIN_NOEXCEPT
{ {
--first; --first;
--second; --second;
return *this; return *this;
} }
ZippingIterator operator--(int) noexcept ZippingIterator operator--(int) MIJIN_NOEXCEPT
{ {
ZippingIterator copy(*this); ZippingIterator copy(*this);
--(*this); --(*this);
return copy; 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. 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); return !(*this == other);
} }
@ -232,12 +233,12 @@ struct ZippingRange : RangeAdapter
RangeRef<TFirst> first; RangeRef<TFirst> first;
RangeRef<TSecond> second; RangeRef<TSecond> second;
auto begin() const noexcept auto begin() const MIJIN_NOEXCEPT
{ {
return ZippingIterator(first.begin(), second.begin()); return ZippingIterator(first.begin(), second.begin());
} }
auto end() const noexcept auto end() const MIJIN_NOEXCEPT
{ {
return ZippingIterator(first.end(), second.end()); return ZippingIterator(first.end(), second.end());
} }
@ -262,12 +263,12 @@ struct ReplacingIterator
value_type what; value_type what;
value_type with; value_type with;
ReplacingIterator(TIterator base_, value_type what_, value_type with_) noexcept : base(base_), what(what_), with(with_) {} ReplacingIterator(TIterator base_, value_type what_, value_type with_) MIJIN_NOEXCEPT : base(base_), what(what_), with(with_) {}
ReplacingIterator(const ReplacingIterator&) noexcept = default; 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) { if (*base == what) {
return &with; return &with;
@ -275,7 +276,7 @@ struct ReplacingIterator
return &*base; return &*base;
} }
reference operator*() const noexcept reference operator*() const MIJIN_NOEXCEPT
{ {
if (*base == what) { if (*base == what) {
return with; return with;
@ -283,38 +284,38 @@ struct ReplacingIterator
return *base; return *base;
} }
ReplacingIterator& operator++() noexcept ReplacingIterator& operator++() MIJIN_NOEXCEPT
{ {
++base; ++base;
return *this; return *this;
} }
ReplacingIterator operator++(int) noexcept ReplacingIterator operator++(int) MIJIN_NOEXCEPT
{ {
ReplacingIterator copy(*this); ReplacingIterator copy(*this);
++(*this); ++(*this);
return copy; return copy;
} }
ReplacingIterator& operator--() noexcept ReplacingIterator& operator--() MIJIN_NOEXCEPT
{ {
--base; --base;
return *this; return *this;
} }
ReplacingIterator operator--(int) noexcept ReplacingIterator operator--(int) MIJIN_NOEXCEPT
{ {
ReplacingIterator copy(*this); ReplacingIterator copy(*this);
--(*this); --(*this);
return copy; 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; 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); return !(*this == other);
} }
@ -329,12 +330,12 @@ struct ReplacingRange : RangeAdapter
value_type what; value_type what;
value_type with; value_type with;
auto begin() const noexcept auto begin() const MIJIN_NOEXCEPT
{ {
return ReplacingIterator(base.begin(), what, with); return ReplacingIterator(base.begin(), what, with);
} }
auto end() const noexcept auto end() const MIJIN_NOEXCEPT
{ {
return ReplacingIterator(base.end(), what, with); return ReplacingIterator(base.end(), what, with);
} }
@ -368,14 +369,14 @@ struct MappingIterator
TFunctor functor; TFunctor functor;
mutable Optional<value_type> result; mutable Optional<value_type> result;
MappingIterator(TIterator base_, TFunctor functor_) noexcept : base(base_), functor(std::move(functor_)) {} MappingIterator(TIterator base_, TFunctor functor_) MIJIN_NOEXCEPT : base(base_), functor(std::move(functor_)) {}
MappingIterator(const MappingIterator&) noexcept = default; MappingIterator(const MappingIterator&) MIJIN_NOEXCEPT = default;
MappingIterator(MappingIterator&&) noexcept = default; MappingIterator(MappingIterator&&) MIJIN_NOEXCEPT = default;
MappingIterator& operator=(const MappingIterator&) noexcept = default; MappingIterator& operator=(const MappingIterator&) MIJIN_NOEXCEPT = default;
MappingIterator& operator=(MappingIterator&&) noexcept = default; MappingIterator& operator=(MappingIterator&&) MIJIN_NOEXCEPT = default;
reference operator*() const noexcept reference operator*() const MIJIN_NOEXCEPT
{ {
if (result.empty()) { if (result.empty()) {
result = std::invoke(functor, *base); result = std::invoke(functor, *base);
@ -383,40 +384,40 @@ struct MappingIterator
return *result; return *result;
} }
MappingIterator& operator++() noexcept MappingIterator& operator++() MIJIN_NOEXCEPT
{ {
++base; ++base;
result.reset(); result.reset();
return *this; return *this;
} }
MappingIterator operator++(int) noexcept MappingIterator operator++(int) MIJIN_NOEXCEPT
{ {
MappingIterator copy(*this); MappingIterator copy(*this);
++(*this); ++(*this);
return copy; return copy;
} }
MappingIterator& operator--() noexcept MappingIterator& operator--() MIJIN_NOEXCEPT
{ {
--base; --base;
result.reset(); result.reset();
return *this; return *this;
} }
MappingIterator operator--(int) noexcept MappingIterator operator--(int) MIJIN_NOEXCEPT
{ {
MappingIterator copy(*this); MappingIterator copy(*this);
--(*this); --(*this);
return copy; 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 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); return !(*this == other);
} }
@ -431,17 +432,17 @@ struct MappingRange : RangeAdapter
RangeRef<TIterable> base; RangeRef<TIterable> base;
TFunctor functor; TFunctor functor;
auto begin() const noexcept auto begin() const MIJIN_NOEXCEPT
{ {
return MappingIterator(base.begin(), functor); return MappingIterator(base.begin(), functor);
} }
auto end() const noexcept auto end() const MIJIN_NOEXCEPT
{ {
return MappingIterator(base.end(), functor); return MappingIterator(base.end(), functor);
} }
[[nodiscard]] bool empty() const noexcept { [[nodiscard]] bool empty() const MIJIN_NOEXCEPT {
return base.begin() == base.end(); return base.begin() == base.end();
} }
}; };
@ -472,7 +473,7 @@ struct OptionalMappingIterator
TFunctor functor; TFunctor functor;
mutable optional_type result; // must be mutable so dereferencing can stay const, not nice :/ 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) if (base != end)
{ {
result = functor(*base); result = functor(*base);
@ -481,18 +482,18 @@ struct OptionalMappingIterator
} }
} }
} }
OptionalMappingIterator(const OptionalMappingIterator&) noexcept = default; OptionalMappingIterator(const OptionalMappingIterator&) MIJIN_NOEXCEPT = default;
OptionalMappingIterator(OptionalMappingIterator&&) noexcept = default; OptionalMappingIterator(OptionalMappingIterator&&) MIJIN_NOEXCEPT = default;
OptionalMappingIterator& operator=(const OptionalMappingIterator&) noexcept = default; OptionalMappingIterator& operator=(const OptionalMappingIterator&) MIJIN_NOEXCEPT = default;
OptionalMappingIterator& operator=(OptionalMappingIterator&&) noexcept = default; OptionalMappingIterator& operator=(OptionalMappingIterator&&) MIJIN_NOEXCEPT = default;
reference operator*() const noexcept reference operator*() const MIJIN_NOEXCEPT
{ {
return *result; return *result;
} }
OptionalMappingIterator& operator++() noexcept OptionalMappingIterator& operator++() MIJIN_NOEXCEPT
{ {
do do
{ {
@ -502,19 +503,19 @@ struct OptionalMappingIterator
return *this; return *this;
} }
OptionalMappingIterator operator++(int) noexcept OptionalMappingIterator operator++(int) MIJIN_NOEXCEPT
{ {
OptionalMappingIterator copy(*this); OptionalMappingIterator copy(*this);
++(*this); ++(*this);
return copy; 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 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); return !(*this == other);
} }
@ -529,12 +530,12 @@ struct OptionalMappingRange : RangeAdapter
RangeRef<TIterable> base; RangeRef<TIterable> base;
TFunctor functor; TFunctor functor;
auto begin() const noexcept auto begin() const MIJIN_NOEXCEPT
{ {
return OptionalMappingIterator(base.begin(), base.end(), functor); return OptionalMappingIterator(base.begin(), base.end(), functor);
} }
auto end() const noexcept auto end() const MIJIN_NOEXCEPT
{ {
return OptionalMappingIterator(base.end(), base.end(), functor); return OptionalMappingIterator(base.end(), base.end(), functor);
} }
@ -561,23 +562,23 @@ struct FilteringIterator
TIterator end; TIterator end;
TPredicate predicate; 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)) { if (base != end && !predicate(*base)) {
++(*this); ++(*this);
} }
} }
FilteringIterator(const FilteringIterator&) noexcept = default; FilteringIterator(const FilteringIterator&) MIJIN_NOEXCEPT = default;
FilteringIterator(FilteringIterator&&) noexcept = default; FilteringIterator(FilteringIterator&&) MIJIN_NOEXCEPT = default;
FilteringIterator& operator=(const FilteringIterator&) noexcept = default; FilteringIterator& operator=(const FilteringIterator&) MIJIN_NOEXCEPT = default;
FilteringIterator& operator=(FilteringIterator&&) noexcept = default; FilteringIterator& operator=(FilteringIterator&&) MIJIN_NOEXCEPT = default;
reference operator*() const noexcept reference operator*() const MIJIN_NOEXCEPT
{ {
return *base; return *base;
} }
FilteringIterator& operator++() noexcept FilteringIterator& operator++() MIJIN_NOEXCEPT
{ {
do do
{ {
@ -586,19 +587,19 @@ struct FilteringIterator
return *this; return *this;
} }
FilteringIterator operator++(int) noexcept FilteringIterator operator++(int) MIJIN_NOEXCEPT
{ {
FilteringIterator copy(*this); FilteringIterator copy(*this);
++(*this); ++(*this);
return copy; 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? 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); return !(*this == other);
} }
@ -613,12 +614,12 @@ struct FilteringRange : RangeAdapter
RangeRef<TIterable> base; RangeRef<TIterable> base;
TPredicate predicate; TPredicate predicate;
auto begin() const noexcept auto begin() const MIJIN_NOEXCEPT
{ {
return FilteringIterator(base.begin(), base.end(), predicate); return FilteringIterator(base.begin(), base.end(), predicate);
} }
auto end() const noexcept auto end() const MIJIN_NOEXCEPT
{ {
return FilteringIterator(base.end(), base.end(), predicate); return FilteringIterator(base.end(), base.end(), predicate);
} }
@ -647,13 +648,13 @@ struct ChainingIterator
TSecondIterator secondBase; TSecondIterator secondBase;
TSecondIterator secondBegin; 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_) {} : 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) if (firstBase == firstEnd)
{ {
@ -662,7 +663,7 @@ struct ChainingIterator
return &*firstBase; return &*firstBase;
} }
reference operator*() const noexcept reference operator*() const MIJIN_NOEXCEPT
{ {
if (firstBase == firstEnd) if (firstBase == firstEnd)
{ {
@ -671,7 +672,7 @@ struct ChainingIterator
return *firstBase; return *firstBase;
} }
ChainingIterator& operator++() noexcept ChainingIterator& operator++() MIJIN_NOEXCEPT
{ {
if (firstBase == firstEnd) { if (firstBase == firstEnd) {
++secondBase; ++secondBase;
@ -682,14 +683,14 @@ struct ChainingIterator
return *this; return *this;
} }
ChainingIterator operator++(int) noexcept ChainingIterator operator++(int) MIJIN_NOEXCEPT
{ {
ChainingIterator copy(*this); ChainingIterator copy(*this);
++(*this); ++(*this);
return copy; return copy;
} }
ChainingIterator& operator--() noexcept ChainingIterator& operator--() MIJIN_NOEXCEPT
{ {
if (secondBase == secondBegin) { if (secondBase == secondBegin) {
--firstBase; --firstBase;
@ -700,19 +701,19 @@ struct ChainingIterator
return *this; return *this;
} }
ChainingIterator operator--(int) noexcept ChainingIterator operator--(int) MIJIN_NOEXCEPT
{ {
ChainingIterator copy(*this); ChainingIterator copy(*this);
--(*this); --(*this);
return copy; 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 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); return !(*this == other);
} }
@ -726,12 +727,12 @@ struct ChainedRange : RangeAdapter
RangeRef<TFirstRange> first; RangeRef<TFirstRange> first;
RangeRef<TSecondRange> second; RangeRef<TSecondRange> second;
auto begin() const noexcept auto begin() const MIJIN_NOEXCEPT
{ {
return ChainingIterator(first.begin(), first.end(), second.begin(), second.begin()); 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()); return ChainingIterator(first.end(), first.end(), second.end(), second.begin());
} }
@ -764,23 +765,23 @@ struct TypeFilteringIterator
TIterator base; TIterator base;
TIterator end; 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()) { if (base != end && !isCastable()) {
++(*this); ++(*this);
} }
} }
TypeFilteringIterator(const TypeFilteringIterator&) noexcept = default; TypeFilteringIterator(const TypeFilteringIterator&) MIJIN_NOEXCEPT = default;
TypeFilteringIterator(TypeFilteringIterator&&) noexcept = default; TypeFilteringIterator(TypeFilteringIterator&&) MIJIN_NOEXCEPT = default;
TypeFilteringIterator& operator=(const TypeFilteringIterator&) noexcept = default; TypeFilteringIterator& operator=(const TypeFilteringIterator&) MIJIN_NOEXCEPT = default;
TypeFilteringIterator& operator=(TypeFilteringIterator&&) noexcept = default; TypeFilteringIterator& operator=(TypeFilteringIterator&&) MIJIN_NOEXCEPT = default;
reference operator*() const noexcept reference operator*() const MIJIN_NOEXCEPT
{ {
return static_cast<reference>(*base); return static_cast<reference>(*base);
} }
TypeFilteringIterator& operator++() noexcept TypeFilteringIterator& operator++() MIJIN_NOEXCEPT
{ {
do do
{ {
@ -789,19 +790,19 @@ struct TypeFilteringIterator
return *this; return *this;
} }
TypeFilteringIterator operator++(int) noexcept TypeFilteringIterator operator++(int) MIJIN_NOEXCEPT
{ {
FilteringIterator copy(*this); FilteringIterator copy(*this);
++(*this); ++(*this);
return copy; return copy;
} }
bool operator==(const TypeFilteringIterator& other) const noexcept bool operator==(const TypeFilteringIterator& other) const MIJIN_NOEXCEPT
{ {
return base == other.base && end == other.end; 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); return !(*this == other);
} }
@ -827,12 +828,12 @@ struct TypeFilteringRange : RangeAdapter
RangeRef<TIterable> iterable; RangeRef<TIterable> iterable;
auto begin() const noexcept auto begin() const MIJIN_NOEXCEPT
{ {
return TypeFilteringIterator<TType, decltype(iterable.begin())>(iterable.begin(), iterable.end()); 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()); return TypeFilteringIterator<TType, decltype(iterable.begin())>(iterable.end(), iterable.end());
} }

View File

@ -47,7 +47,7 @@ std::mutex gDlErrorMutex; // dlerror may not be thread-safe
// public functions // 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 #if MIJIN_TARGET_OS == MIJIN_OS_LINUX
const std::unique_lock dlErrorLock(gDlErrorMutex); const std::unique_lock dlErrorLock(gDlErrorMutex);
@ -67,7 +67,7 @@ Result<LibraryHandle> openSharedLibrary(std::string_view libraryFile) noexcept
#endif #endif
} }
bool closeSharedLibrary(const LibraryHandle library) noexcept bool closeSharedLibrary(const LibraryHandle library) MIJIN_NOEXCEPT
{ {
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX #if MIJIN_TARGET_OS == MIJIN_OS_LINUX
return dlclose(library.data) == 0; return dlclose(library.data) == 0;
@ -77,7 +77,7 @@ bool closeSharedLibrary(const LibraryHandle library) noexcept
#endif #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 #if MIJIN_TARGET_OS == MIJIN_OS_LINUX
return dlsym(library.data, symbolName); return dlsym(library.data, symbolName);
@ -88,7 +88,7 @@ void* loadSymbolFromLibrary(const LibraryHandle library, const char* symbolName)
#endif #endif
} }
void setCurrentThreadName(const char* threadName) noexcept void setCurrentThreadName(const char* threadName) MIJIN_NOEXCEPT
{ {
#if MIJIN_TARGET_OS == MIJIN_OS_LINUX #if MIJIN_TARGET_OS == MIJIN_OS_LINUX
pthread_setname_np(pthread_self(), threadName); pthread_setname_np(pthread_self(), threadName);
@ -97,7 +97,7 @@ void setCurrentThreadName(const char* threadName) noexcept
#endif #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 #if MIJIN_TARGET_OS == MIJIN_OS_LINUX
return "lib" + std::string(libraryName) + ".so"; return "lib" + std::string(libraryName) + ".so";

View File

@ -9,6 +9,7 @@
#include <string_view> #include <string_view>
#include <utility> #include <utility>
#include "../detect.hpp" #include "../detect.hpp"
#include "../internal/common.hpp"
#include "../types/result.hpp" #include "../types/result.hpp"
namespace mijin namespace mijin
@ -39,8 +40,8 @@ struct LibraryHandle
{ {
void* data = nullptr; void* data = nullptr;
constexpr operator bool() const noexcept { return data != nullptr; } constexpr operator bool() const MIJIN_NOEXCEPT { return data != nullptr; }
constexpr bool operator!() const noexcept { return data == nullptr; } constexpr bool operator!() const MIJIN_NOEXCEPT { return data == nullptr; }
}; };
class SharedLibrary class SharedLibrary
@ -48,43 +49,43 @@ class SharedLibrary
private: private:
LibraryHandle mHandle; LibraryHandle mHandle;
public: public:
SharedLibrary() noexcept = default; SharedLibrary() MIJIN_NOEXCEPT = default;
SharedLibrary(const SharedLibrary&) = delete; SharedLibrary(const SharedLibrary&) = delete;
SharedLibrary(SharedLibrary&& other) noexcept : mHandle(std::exchange(other.mHandle, {})) {} SharedLibrary(SharedLibrary&& other) MIJIN_NOEXCEPT : mHandle(std::exchange(other.mHandle, {})) {}
inline ~SharedLibrary() noexcept; inline ~SharedLibrary() MIJIN_NOEXCEPT;
SharedLibrary& operator=(const SharedLibrary&) = delete; SharedLibrary& operator=(const SharedLibrary&) = delete;
SharedLibrary& operator=(SharedLibrary&& other) noexcept SharedLibrary& operator=(SharedLibrary&& other) MIJIN_NOEXCEPT
{ {
mHandle = std::exchange(other.mHandle, {}); mHandle = std::exchange(other.mHandle, {});
return *this; return *this;
} }
constexpr operator bool() const noexcept { return static_cast<bool>(mHandle); } constexpr operator bool() const MIJIN_NOEXCEPT { return static_cast<bool>(mHandle); }
constexpr bool operator!() const noexcept { return !mHandle; } constexpr bool operator!() const MIJIN_NOEXCEPT { return !mHandle; }
[[nodiscard]] inline Result<bool> open(std::string_view libraryFile) noexcept; [[nodiscard]] inline Result<bool> open(std::string_view libraryFile) MIJIN_NOEXCEPT;
inline bool close() noexcept; inline bool close() MIJIN_NOEXCEPT;
[[nodiscard]] inline void* loadSymbol(const char* symbolName) noexcept; [[nodiscard]] inline void* loadSymbol(const char* symbolName) MIJIN_NOEXCEPT;
}; };
// //
// public functions // public functions
// //
[[nodiscard]] Result<LibraryHandle> openSharedLibrary(std::string_view libraryFile) noexcept; [[nodiscard]] Result<LibraryHandle> openSharedLibrary(std::string_view libraryFile) MIJIN_NOEXCEPT;
bool closeSharedLibrary(const LibraryHandle library) noexcept; bool closeSharedLibrary(const LibraryHandle library) MIJIN_NOEXCEPT;
[[nodiscard]] void* loadSymbolFromLibrary(const LibraryHandle library, const char* symbolName) noexcept; [[nodiscard]] void* loadSymbolFromLibrary(const LibraryHandle library, const char* symbolName) MIJIN_NOEXCEPT;
void setCurrentThreadName(const char* threadName) 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(); close();
} }
Result<bool> SharedLibrary::open(std::string_view libraryFile) noexcept Result<bool> SharedLibrary::open(std::string_view libraryFile) MIJIN_NOEXCEPT
{ {
close(); close();
Result<LibraryHandle> openResult = openSharedLibrary(libraryFile); Result<LibraryHandle> openResult = openSharedLibrary(libraryFile);
@ -96,7 +97,7 @@ Result<bool> SharedLibrary::open(std::string_view libraryFile) noexcept
return ResultError(openResult.getError()); return ResultError(openResult.getError());
} }
bool SharedLibrary::close() noexcept bool SharedLibrary::close() MIJIN_NOEXCEPT
{ {
if (mHandle) if (mHandle)
{ {
@ -105,7 +106,7 @@ bool SharedLibrary::close() noexcept
return false; return false;
} }
void* SharedLibrary::loadSymbol(const char* symbolName) noexcept void* SharedLibrary::loadSymbol(const char* symbolName) MIJIN_NOEXCEPT
{ {
return loadSymbolFromLibrary(mHandle, symbolName); return loadSymbolFromLibrary(mHandle, symbolName);
} }

View File

@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "../debug/assert.hpp" #include "../debug/assert.hpp"
#include "../internal/common.hpp"
namespace mijin namespace mijin
{ {
@ -27,7 +28,7 @@ public:
using get_t = TGet; using get_t = TGet;
using set_t = TSet; using set_t = TSet;
virtual ~PropertyStorage() noexcept = default; virtual ~PropertyStorage() MIJIN_NOEXCEPT = default;
[[nodiscard]] virtual TGet getValue() = 0; [[nodiscard]] virtual TGet getValue() = 0;
virtual void setValue(TSet value) = 0; virtual void setValue(TSet value) = 0;
@ -39,15 +40,15 @@ class SimplePropertyStorage : public PropertyStorage<T>
private: private:
T value_; T value_;
public: public:
SimplePropertyStorage() noexcept = default; SimplePropertyStorage() MIJIN_NOEXCEPT = default;
SimplePropertyStorage(const SimplePropertyStorage& other) noexcept(noexcept(T(other.value_))) = default; SimplePropertyStorage(const SimplePropertyStorage& other) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(T(other.value_))) = default;
SimplePropertyStorage(SimplePropertyStorage&& other) noexcept(noexcept(T(std::move(other.value_)))) = default; SimplePropertyStorage(SimplePropertyStorage&& other) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(T(std::move(other.value_)))) = default;
explicit SimplePropertyStorage(T value) noexcept(noexcept(T(std::move(value)))) : value_(std::move(value)) {} 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=(const SimplePropertyStorage& other) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(value_ = other.value_)) = default;
SimplePropertyStorage& operator=(SimplePropertyStorage&& other) noexcept(noexcept(value_ = std::move(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); } void setValue(T value) override { value_ = std::move(value); }
}; };
@ -65,30 +66,30 @@ public:
private: private:
Property* base_; Property* base_;
public: public:
explicit PropertyProxy(Property* base) noexcept : base_(base) {} explicit PropertyProxy(Property* base) MIJIN_NOEXCEPT : base_(base) {}
operator TGet() noexcept { return base_->get(); } operator TGet() MIJIN_NOEXCEPT { return base_->get(); }
PropertyProxy& operator=(TSet value) noexcept(noexcept(std::declval<T&>() = std::move(value))) PropertyProxy& operator=(TSet value) MIJIN_CONDITIONAL_NOEXCEPT(noexcept(std::declval<T&>() = std::move(value)))
{ {
base_->set(std::move(value)); base_->set(std::move(value));
return *this; return *this;
} }
}; };
Property() noexcept = default; Property() MIJIN_NOEXCEPT = default;
explicit Property(storage_ptr_t storage) noexcept : storage_(std::move(storage)) {} explicit Property(storage_ptr_t storage) MIJIN_NOEXCEPT : storage_(std::move(storage)) {}
Property(Property&&) noexcept = default; Property(Property&&) MIJIN_NOEXCEPT = default;
Property& operator=(Property&&) noexcept = default; Property& operator=(Property&&) MIJIN_NOEXCEPT = default;
PropertyProxy operator*() noexcept { return PropertyProxy(this); } PropertyProxy operator*() MIJIN_NOEXCEPT { return PropertyProxy(this); }
std::remove_reference_t<TGet>* operator->() const noexcept { return &get(); } 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."); MIJIN_ASSERT_FATAL(storage_ != nullptr, "Cannot get value from an unset property.");
return storage_->getValue(); 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."); MIJIN_ASSERT_FATAL(storage_ != nullptr, "Cannot set value of an unset property.");
storage_->setValue(std::move<TSet>(value)); 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>; Property(std::unique_ptr<TStorage>) -> Property<typename TStorage::value_t, typename TStorage::get_t, typename TStorage::set_t>;
template<typename 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))); return Property(std::make_unique<SimplePropertyStorage<T>>(std::move(value)));
} }

View File

@ -5,6 +5,7 @@
#include <functional> #include <functional>
#include "./common_macros.hpp" #include "./common_macros.hpp"
#include "../internal/common.hpp"
#define MIJIN_SCOPE_EXIT_NAMED(name) \ #define MIJIN_SCOPE_EXIT_NAMED(name) \
const mijin::ScopeExitGuard 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() 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: public:
template<typename TFunc> template<typename TFunc>
inline ScopeExitGuard(TFunc&& func_) noexcept : func(std::forward<TFunc>(func_)) {} inline ScopeExitGuard(TFunc&& func_) MIJIN_NOEXCEPT : func(std::forward<TFunc>(func_)) {}
ScopeExitGuard(const ScopeExitGuard&) noexcept = delete; ScopeExitGuard(const ScopeExitGuard&) = delete;
ScopeExitGuard(ScopeExitGuard&&) noexcept = delete; ScopeExitGuard(ScopeExitGuard&&) = delete;
inline ~ScopeExitGuard() noexcept inline ~ScopeExitGuard() MIJIN_NOEXCEPT
{ {
if (func) { if (func) {
func(); func();
} }
} }
ScopeExitGuard& operator=(const ScopeExitGuard&) noexcept = delete; ScopeExitGuard& operator=(const ScopeExitGuard&) = delete;
ScopeExitGuard& operator=(ScopeExitGuard&&) noexcept = delete; ScopeExitGuard& operator=(ScopeExitGuard&&) = delete;
inline void reset() const noexcept inline void reset() const MIJIN_NOEXCEPT
{ {
func = {}; func = {};
} }

View File

@ -16,6 +16,7 @@
#include <vector> #include <vector>
#include "./iterators.hpp" #include "./iterators.hpp"
#include "../internal/common.hpp"
namespace mijin 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> 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()) if (stringA.size() != stringB.size())
{ {
@ -243,7 +244,7 @@ auto trim(TString&& string)
} }
template<typename TLeft, typename TRight> 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)); return detail::equalsIgnoreCaseImpl(std::string_view(left), std::string_view(right));
} }
@ -287,7 +288,7 @@ constexpr auto toUpper(TArgs&&... args)
template<typename TNumber> template<typename TNumber>
[[nodiscard]] [[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* start = &*stringView.begin();
const char* end = start + stringView.size(); 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> template<typename TChar, typename TTraits, typename TNumber>
[[nodiscard]] [[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; std::string asString;
asString.resize(stringView.size()); asString.resize(stringView.size());
@ -312,7 +313,7 @@ struct Join
{ {
const char* delimiter; const char* delimiter;
explicit Join(const char* delimiter_) noexcept : delimiter(delimiter_) {} explicit Join(const char* delimiter_) MIJIN_NOEXCEPT : delimiter(delimiter_) {}
}; };
template<typename TIterable> template<typename TIterable>

View File

@ -12,6 +12,7 @@
#include <vector> #include <vector>
#include "../container/optional.hpp" #include "../container/optional.hpp"
#include "../io/stream.hpp" #include "../io/stream.hpp"
#include "../internal/common.hpp"
#include "../util/hash.hpp" #include "../util/hash.hpp"
namespace fs = std::filesystem; namespace fs = std::filesystem;
@ -52,16 +53,16 @@ public:
PathReference() = default; PathReference() = default;
PathReference(const PathReference&) = default; PathReference(const PathReference&) = default;
PathReference(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=(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]] 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 FileInfo getInfo() const;
[[nodiscard]] inline Optional<fs::path> getNativePath() const; [[nodiscard]] inline Optional<fs::path> getNativePath() const;
[[nodiscard]] inline StreamError open(FileOpenMode mode, std::unique_ptr<Stream>& outStream) 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 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]] 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 class OSFileSystemAdapter : public FileSystemAdapter
@ -151,7 +152,7 @@ inline std::string formatFileSize(std::size_t sizeInBytes)
template<> template<>
struct std::hash<mijin::PathReference> 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; std::size_t hash = 0;
mijin::hashCombine(hash, pathRef.getAdapter()); mijin::hashCombine(hash, pathRef.getAdapter());

View File

@ -5,6 +5,7 @@
#define MIJIN_VIRTUAL_FILESYSTEM_RELATIVE_HPP_INCLUDED 1 #define MIJIN_VIRTUAL_FILESYSTEM_RELATIVE_HPP_INCLUDED 1
#include "./filesystem.hpp" #include "./filesystem.hpp"
#include "../internal/common.hpp"
namespace mijin namespace mijin
{ {
@ -32,10 +33,10 @@ public:
explicit RelativeFileSystemAdapter(fs::path root, TArgs&&... args) explicit RelativeFileSystemAdapter(fs::path root, TArgs&&... args)
: wrapped_(std::forward<TArgs>(args)...), root_(std::move(root)) {} : wrapped_(std::forward<TArgs>(args)...), root_(std::move(root)) {}
RelativeFileSystemAdapter(const RelativeFileSystemAdapter&) = default; RelativeFileSystemAdapter(const RelativeFileSystemAdapter&) = default;
RelativeFileSystemAdapter(RelativeFileSystemAdapter&&) noexcept = default; RelativeFileSystemAdapter(RelativeFileSystemAdapter&&) MIJIN_NOEXCEPT = default;
RelativeFileSystemAdapter& operator=(const RelativeFileSystemAdapter&) = default; RelativeFileSystemAdapter& operator=(const RelativeFileSystemAdapter&) = default;
RelativeFileSystemAdapter& operator=(RelativeFileSystemAdapter&&) noexcept = default; RelativeFileSystemAdapter& operator=(RelativeFileSystemAdapter&&) MIJIN_NOEXCEPT = default;
std::vector<fs::path> getRoots() override; std::vector<fs::path> getRoots() override;
fs::path getHomeFolder() override; fs::path getHomeFolder() override;
@ -44,7 +45,7 @@ public:
Optional<fs::path> getNativePath(const fs::path& file) override; Optional<fs::path> getNativePath(const fs::path& file) override;
StreamError open(const fs::path& path, FileOpenMode mode, std::unique_ptr<Stream>& outStream) override; StreamError open(const fs::path& path, FileOpenMode mode, std::unique_ptr<Stream>& outStream) override;
private: 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> 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_; fs::path combinedPath = root_;
if (other.is_absolute()) { if (other.is_absolute()) {