Added operators to BoxedObject, fixed MappintIterator for reference types and fixed signature of custom assertion and error handlers.

This commit is contained in:
Patrick 2023-11-12 15:25:46 +01:00
parent 2cc0f74d06
commit 7c1dd29a85
4 changed files with 24 additions and 18 deletions

View File

@ -32,13 +32,14 @@ class BoxedObject
{ {
private: private:
union { union {
std::byte placeholder_;
T object_; T object_;
}; };
#if MIJIN_BOXED_OBJECT_DEBUG #if MIJIN_BOXED_OBJECT_DEBUG
bool constructed = false; bool constructed = false;
#endif #endif
public: public:
BoxedObject() = default; BoxedObject() noexcept : placeholder_() {};
explicit BoxedObject(T object) explicit BoxedObject(T object)
#if MIJIN_BOXED_OBJECT_DEBUG #if MIJIN_BOXED_OBJECT_DEBUG
: constructed(true) : constructed(true)
@ -59,6 +60,11 @@ public:
BoxedObject& operator=(const BoxedObject&) = delete; BoxedObject& operator=(const BoxedObject&) = delete;
BoxedObject& operator=(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<typename... TArgs> template<typename... TArgs>
void construct(TArgs&&... args) void construct(TArgs&&... args)
{ {

View File

@ -138,6 +138,10 @@ public:
constexpr explicit operator bool() const noexcept { return !empty(); } constexpr explicit operator bool() const noexcept { return !empty(); }
[[nodiscard]] [[nodiscard]]
constexpr bool operator !() const noexcept { return empty(); } constexpr bool operator !() const noexcept { return empty(); }
[[nodiscard]]
constexpr std::remove_reference_t<TValue>& operator*() noexcept { return get(); }
[[nodiscard]]
constexpr const std::remove_reference_t<TValue>& operator*() const noexcept { return get(); }
public: public:
template<typename... Types> template<typename... Types>
void emplace(Types&&... params) noexcept; void emplace(Types&&... params) noexcept;

View File

@ -28,7 +28,7 @@ namespace mijin
#if MIJIN_DEBUG #if MIJIN_DEBUG
#define MIJIN_DO_RAISE_ERROR(msg, source_loc) \ #define MIJIN_RAISE_ERROR(msg, source_loc) \
switch (mijin::handleError(msg, source_loc)) \ switch (mijin::handleError(msg, source_loc)) \
{ \ { \
case mijin::ErrorHandling::CONTINUE: \ case mijin::ErrorHandling::CONTINUE: \
@ -40,10 +40,8 @@ switch (mijin::handleError(msg, source_loc)) \
std::abort(); \ std::abort(); \
} }
#define MIJIN_RAISE_ERROR(msg, func, file, line) MIJIN_DO_RAISE_ERROR(msg, func, file, line)
#define MIJIN_ERROR(msg) \ #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) \ #define MIJIN_FATAL(msg) \
MIJIN_ERROR(msg) \ MIJIN_ERROR(msg) \
@ -57,7 +55,7 @@ if (!static_cast<bool>(condition))
if (true) /*!ignoreAll */ \ if (true) /*!ignoreAll */ \
{ \ { \
const mijin::AssertionResult assertion_result__ = mijin::handleAssert( \ const mijin::AssertionResult assertion_result__ = mijin::handleAssert( \
#condition, msg, MIJIN_FUNC(), __FILE__, __LINE__); \ #condition, msg, std::source_location::current()); \
switch (assertion_result__) \ switch (assertion_result__) \
{ \ { \
case mijin::AssertionResult::ABORT: \ case mijin::AssertionResult::ABORT: \
@ -116,20 +114,17 @@ enum class ErrorHandling
#ifdef MIJIN_USE_CUSTOM_ASSERTION_HANDLER #ifdef MIJIN_USE_CUSTOM_ASSERTION_HANDLER
AssertionResult handleAssert(const char* condition, AssertionResult handleAssert(const char* condition,
const char* message, const char* function, const char* message, const std::source_location& location);
const char* file, int line) noexcept;
#else #else
constexpr AssertionResult handleAssert(const char* /* condition */, constexpr AssertionResult handleAssert(const char* /* condition */,
const char* /* message */, const char* /* function */, const char* /* message */, const std::source_location& /* location */)
const char* /* file */, int /* line */)
{ {
return AssertionResult::ERROR; return AssertionResult::ERROR;
} }
#endif // MIJIN_USE_CUSTOM_ASSERTION_HANDLER #endif // MIJIN_USE_CUSTOM_ASSERTION_HANDLER
#ifdef MIJIN_USE_CUSTOM_ERROR_HANDLER #ifdef MIJIN_USE_CUSTOM_ERROR_HANDLER
ErrorHandling handleError(const char* message, const char* function, ErrorHandling handleError(const char* message, const std::source_location& location);
const char* file, int line) noexcept;
#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) noexcept
{ {

View File

@ -10,6 +10,7 @@
#include <string_view> #include <string_view>
#include <tuple> #include <tuple>
#include <variant> #include <variant>
#include "../container/optional.hpp"
namespace mijin namespace mijin
{ {
@ -277,7 +278,7 @@ struct MappingIterator
{ {
using orig_value_type = typename std::iterator_traits<TIterator>::value_type; using orig_value_type = typename std::iterator_traits<TIterator>::value_type;
using difference_type = std::ptrdiff_t; using difference_type = std::ptrdiff_t;
using value_type = std::invoke_result_t<TFunctor, orig_value_type>; using value_type = std::invoke_result_t<TFunctor, orig_value_type&>;
using reference = value_type&; using reference = value_type&;
using iterator_category = std::bidirectional_iterator_tag; // TODO? using iterator_category = std::bidirectional_iterator_tag; // TODO?
@ -285,7 +286,7 @@ struct MappingIterator
TIterator base; TIterator base;
TFunctor functor; TFunctor functor;
mutable std::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_) noexcept : base(base_), functor(std::move(functor_)) {}
MappingIterator(const MappingIterator&) noexcept = default; MappingIterator(const MappingIterator&) noexcept = default;
@ -296,8 +297,8 @@ struct MappingIterator
reference operator*() const noexcept reference operator*() const noexcept
{ {
if (!result.has_value()) { if (result.empty()) {
result = functor(*base); result = std::invoke(functor, *base);
} }
return *result; return *result;
} }
@ -305,7 +306,7 @@ struct MappingIterator
MappingIterator& operator++() noexcept MappingIterator& operator++() noexcept
{ {
++base; ++base;
result = std::nullopt; result.reset();
return *this; return *this;
} }
@ -319,7 +320,7 @@ struct MappingIterator
MappingIterator& operator--() noexcept MappingIterator& operator--() noexcept
{ {
--base; --base;
result = std::nullopt; result.reset();
return *this; return *this;
} }