Compare commits

...

4 Commits

4 changed files with 151 additions and 11 deletions

View File

@ -34,21 +34,21 @@ namespace impl
template<typename TValue> template<typename TValue>
struct FutureStorage struct FutureStorage
{ {
std::optional<TValue> value; Optional<TValue> value;
void setValue(TValue value_) noexcept { value = std::move(value_); } void setValue(TValue value_) noexcept { value = std::move(value_); }
[[nodiscard]] TValue& getValue() noexcept { return value.value(); } [[nodiscard]] TValue& getValue() noexcept { return value.get(); }
}; };
template<typename TValue> // template<typename TValue>
struct FutureStorage<TValue&> // struct FutureStorage<TValue&>
{ // {
std::optional<TValue*> value; // Optional<TValue*> value;
//
void setValue(TValue& value_) noexcept { value = &value_; } // void setValue(TValue& value_) noexcept { value = &value_; }
[[nodiscard]] TValue& getValue() const noexcept { return *value.value(); } // [[nodiscard]] TValue& getValue() const noexcept { return *value.get(); }
}; // };
template<> template<>
struct FutureStorage<void> struct FutureStorage<void>

View File

@ -173,7 +173,12 @@ Optional<TValue>::Optional(Optional&& other) noexcept
{ {
if (other) if (other)
{ {
if constexpr (!std::is_reference_v<TValue>) {
emplace(std::move(other.get())); emplace(std::move(other.get()));
}
else {
emplace(other.get());
}
other.reset(); other.reset();
} }
} }

View File

@ -7,6 +7,9 @@
#include <cmath> #include <cmath>
#include <iomanip> #include <iomanip>
#include <vector> #include <vector>
#if __has_include(<fmt/format.h>)
# include <fmt/format.h>
#endif
#include "./symbol_info.hpp" #include "./symbol_info.hpp"
#include "../types/result.hpp" #include "../types/result.hpp"
#include "../util/iterators.hpp" #include "../util/iterators.hpp"
@ -82,4 +85,56 @@ TStream& operator<<(TStream& stream, const Stacktrace& stacktrace)
} // namespace mijin } // namespace mijin
#if __has_include(<fmt/format.h>)
template<>
struct fmt::formatter<mijin::Stackframe>
{
constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin())
{
auto it = ctx.begin();
auto end = ctx.end();
if (it != end && *it != '}') throw format_error("invalid format");
return it;
}
template<typename TContext>
auto format(const mijin::Stackframe& stackframe, TContext& ctx) const -> decltype(ctx.out())
{
auto it = ctx.out();
it = fmt::format_to(it, "[{}] {}:{} in {}", stackframe.address, stackframe.filename,
stackframe.lineNumber, mijin::demangleCPPIdentifier(stackframe.function.c_str()));
return it;
}
};
template<>
struct fmt::formatter<mijin::Stacktrace>
{
constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin())
{
auto it = ctx.begin();
auto end = ctx.end();
if (it != end && *it != '}') throw format_error("invalid format");
return it;
}
template<typename TContext>
auto format(const mijin::Stacktrace& stacktrace, TContext& ctx) const -> decltype(ctx.out())
{
const int numDigits = static_cast<int>(std::ceil(std::log10(stacktrace.getFrames().size())));
auto it = ctx.out();
it = fmt::format_to(it, "[{} frames]", stacktrace.getFrames().size());
for (const auto& [idx, frame] : mijin::enumerate(stacktrace.getFrames()))
{
it = fmt::format_to(it, "\n #{:<{}} at {}", idx, numDigits, frame);
}
return it;
}
};
#endif // __has_include(<fmt/format.h>)
#endif // !defined(MIJIN_DEBUG_STACKTRACE_HPP_INCLUDED) #endif // !defined(MIJIN_DEBUG_STACKTRACE_HPP_INCLUDED)

View File

@ -169,6 +169,86 @@ Enumeratable<TIdx, TIterable> enumerate(TIterable&& iterable)
return {.base = {std::forward<TIterable>(iterable)}}; return {.base = {std::forward<TIterable>(iterable)}};
} }
template<typename TFirstIterator, typename TSecondIterator>
struct ZippingIterator
{
TFirstIterator first;
TSecondIterator second;
ZippingIterator(TFirstIterator first_, TSecondIterator second_) noexcept : first(first_), second(second_) {}
ZippingIterator(const ZippingIterator&) noexcept = default;
ZippingIterator& operator=(const ZippingIterator&) noexcept = default;
auto operator*() const noexcept
{
return std::tie(*first, *second);
}
ZippingIterator& operator++() noexcept
{
++first;
++second;
return *this;
}
ZippingIterator operator++(int) noexcept
{
ZippingIterator copy(*this);
++(*this);
return copy;
}
ZippingIterator& operator--() noexcept
{
--first;
--second;
return *this;
}
ZippingIterator operator--(int) noexcept
{
ZippingIterator copy(*this);
--(*this);
return copy;
}
bool operator==(const ZippingIterator& other) const noexcept
{
return first == other.first || second == other.second; // note: this uses or so reaching the end on one range also ends the zipped one.
}
bool operator!=(const ZippingIterator& other) const noexcept
{
return !(*this == other);
}
};
template<typename TFirstIterator, typename TSecondIterator>
ZippingIterator(TFirstIterator, TSecondIterator) -> ZippingIterator<TFirstIterator, TSecondIterator>;
template<typename TFirst, typename TSecond>
struct ZippingRange : RangeAdapter
{
RangeRef<TFirst> first;
RangeRef<TSecond> second;
auto begin() const noexcept
{
return ZippingIterator(first.begin(), second.begin());
}
auto end() const noexcept
{
return ZippingIterator(first.end(), second.end());
}
};
template<typename TFirst, typename TSecond>
ZippingRange<TFirst, TSecond> zip(TFirst&& first, TSecond&& second)
{
return {.first = {std::forward<TFirst>(first)}, .second = {std::forward<TSecond>(second)}};
}
template<typename TIterator> template<typename TIterator>
struct ReplacingIterator struct ReplacingIterator
{ {