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

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

View File

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