diff --git a/source/mijin/container/boxed_object.hpp b/source/mijin/container/boxed_object.hpp index 2adc357..c131991 100644 --- a/source/mijin/container/boxed_object.hpp +++ b/source/mijin/container/boxed_object.hpp @@ -32,13 +32,14 @@ class BoxedObject { private: union { + std::byte placeholder_; T object_; }; #if MIJIN_BOXED_OBJECT_DEBUG bool constructed = false; #endif public: - BoxedObject() = default; + BoxedObject() noexcept : placeholder_() {}; explicit BoxedObject(T object) #if MIJIN_BOXED_OBJECT_DEBUG : constructed(true) @@ -59,6 +60,11 @@ public: BoxedObject& operator=(const BoxedObject&) = delete; BoxedObject& operator=(BoxedObject&&) = delete; + T& operator*() noexcept { return get(); } + const T& operator*() const noexcept { return get(); } + T* operator->() noexcept { return &get(); } + const T* operator->() const noexcept { return &get(); } + template void construct(TArgs&&... args) { diff --git a/source/mijin/container/optional.hpp b/source/mijin/container/optional.hpp index 46304c3..54ae8ed 100644 --- a/source/mijin/container/optional.hpp +++ b/source/mijin/container/optional.hpp @@ -138,6 +138,10 @@ public: constexpr explicit operator bool() const noexcept { return !empty(); } [[nodiscard]] constexpr bool operator !() const noexcept { return empty(); } + [[nodiscard]] + constexpr std::remove_reference_t& operator*() noexcept { return get(); } + [[nodiscard]] + constexpr const std::remove_reference_t& operator*() const noexcept { return get(); } public: template void emplace(Types&&... params) noexcept; diff --git a/source/mijin/debug/assert.hpp b/source/mijin/debug/assert.hpp index 44bea03..12ff2db 100644 --- a/source/mijin/debug/assert.hpp +++ b/source/mijin/debug/assert.hpp @@ -28,7 +28,7 @@ namespace mijin #if MIJIN_DEBUG -#define MIJIN_DO_RAISE_ERROR(msg, source_loc) \ +#define MIJIN_RAISE_ERROR(msg, source_loc) \ switch (mijin::handleError(msg, source_loc)) \ { \ case mijin::ErrorHandling::CONTINUE: \ @@ -40,10 +40,8 @@ switch (mijin::handleError(msg, source_loc)) \ std::abort(); \ } -#define MIJIN_RAISE_ERROR(msg, func, file, line) MIJIN_DO_RAISE_ERROR(msg, func, file, line) - #define MIJIN_ERROR(msg) \ -MIJIN_DO_RAISE_ERROR(msg, std::source_location::current()) +MIJIN_RAISE_ERROR(msg, std::source_location::current()) #define MIJIN_FATAL(msg) \ MIJIN_ERROR(msg) \ @@ -57,7 +55,7 @@ if (!static_cast(condition)) if (true) /*!ignoreAll */ \ { \ const mijin::AssertionResult assertion_result__ = mijin::handleAssert( \ - #condition, msg, MIJIN_FUNC(), __FILE__, __LINE__); \ + #condition, msg, std::source_location::current()); \ switch (assertion_result__) \ { \ case mijin::AssertionResult::ABORT: \ @@ -116,20 +114,17 @@ enum class ErrorHandling #ifdef MIJIN_USE_CUSTOM_ASSERTION_HANDLER AssertionResult handleAssert(const char* condition, - const char* message, const char* function, - const char* file, int line) noexcept; + const char* message, const std::source_location& location); #else constexpr AssertionResult handleAssert(const char* /* condition */, - const char* /* message */, const char* /* function */, - const char* /* file */, int /* line */) + const char* /* message */, const std::source_location& /* location */) { return AssertionResult::ERROR; } #endif // MIJIN_USE_CUSTOM_ASSERTION_HANDLER #ifdef MIJIN_USE_CUSTOM_ERROR_HANDLER -ErrorHandling handleError(const char* message, const char* function, - const char* file, int line) noexcept; +ErrorHandling handleError(const char* message, const std::source_location& location); #else inline ErrorHandling handleError(const char* message, const std::source_location& location) noexcept { diff --git a/source/mijin/util/iterators.hpp b/source/mijin/util/iterators.hpp index e0be6cd..2aff82a 100644 --- a/source/mijin/util/iterators.hpp +++ b/source/mijin/util/iterators.hpp @@ -10,6 +10,7 @@ #include #include #include +#include "../container/optional.hpp" namespace mijin { @@ -277,7 +278,7 @@ struct MappingIterator { using orig_value_type = typename std::iterator_traits::value_type; using difference_type = std::ptrdiff_t; - using value_type = std::invoke_result_t; + using value_type = std::invoke_result_t; using reference = value_type&; using iterator_category = std::bidirectional_iterator_tag; // TODO? @@ -285,7 +286,7 @@ struct MappingIterator TIterator base; TFunctor functor; - mutable std::optional result; + mutable Optional result; MappingIterator(TIterator base_, TFunctor functor_) noexcept : base(base_), functor(std::move(functor_)) {} MappingIterator(const MappingIterator&) noexcept = default; @@ -296,8 +297,8 @@ struct MappingIterator reference operator*() const noexcept { - if (!result.has_value()) { - result = functor(*base); + if (result.empty()) { + result = std::invoke(functor, *base); } return *result; } @@ -305,7 +306,7 @@ struct MappingIterator MappingIterator& operator++() noexcept { ++base; - result = std::nullopt; + result.reset(); return *this; } @@ -319,7 +320,7 @@ struct MappingIterator MappingIterator& operator--() noexcept { --base; - result = std::nullopt; + result.reset(); return *this; }