// clang-format off
template<class F, class T, class U>
requires std::relation<F, T, U>
-[[nodiscard]] constexpr bool check_equivalence_relation_subsumes_relation() {
+constexpr bool check_equivalence_relation_subsumes_relation() {
return false;
}
template<class F, class T, class U>
requires std::equivalence_relation<F, T, U> && true
-[[nodiscard]] constexpr bool check_equivalence_relation_subsumes_relation() {
+constexpr bool check_equivalence_relation_subsumes_relation() {
return true;
}
// clang-format on
// clang-format off
template<class F, class T, class U>
requires std::relation<F, T, U> && true
-[[nodiscard]] constexpr bool check_relation_subsumes_equivalence_relation() {
+constexpr bool check_relation_subsumes_equivalence_relation() {
return true;
}
template<class F, class T, class U>
requires std::equivalence_relation<F, T, U>
-[[nodiscard]] constexpr bool check_relation_subsumes_equivalence_relation() {
+constexpr bool check_relation_subsumes_equivalence_relation() {
return false;
}
// clang-format on
// clang-format off
template<class F, class T, class U>
requires std::equivalence_relation<F, T, T> && std::equivalence_relation<F, U, U>
-[[nodiscard]] constexpr bool check_equivalence_relation_subsumes_itself() {
+constexpr bool check_equivalence_relation_subsumes_itself() {
return false;
}
template<class F, class T, class U>
requires std::equivalence_relation<F, T, U>
-[[nodiscard]] constexpr bool check_equivalence_relation_subsumes_itself() {
+constexpr bool check_equivalence_relation_subsumes_itself() {
return true;
}
// clang-format on
// clang-format off
template<class F, class T, class U>
requires std::relation<F, T, U>
-[[nodiscard]] constexpr bool check_subsumption() { return false; }
+constexpr bool check_subsumption() { return false; }
template<class F, class T>
requires std::equivalence_relation<F, T, T> && true
-[[nodiscard]] constexpr bool check_subsumption() { return false; }
+constexpr bool check_subsumption() { return false; }
template<class F, class T, class U>
requires std::equivalence_relation<F, T, U> && true
-[[nodiscard]] constexpr bool check_subsumption() { return true; }
+constexpr bool check_subsumption() { return true; }
// clang-format on
static_assert(check_subsumption<int (*)(int, int), int, int>());
// clang-format off
template<class F, class T, class U>
requires std::relation<F, T, U> && true
-[[nodiscard]] constexpr bool check_reverse_subsumption() { return true; }
+constexpr bool check_reverse_subsumption() { return true; }
template<class F, class T, class U>
requires std::equivalence_relation<F, T, U>
-[[nodiscard]] constexpr bool check_no_subsumption() { return false; }
+constexpr bool check_no_subsumption() { return false; }
// clang-format on
static_assert(check_reverse_subsumption<int (*)(int, int), int, int>());
#include <type_traits>
template <class R, class... Args>
-[[nodiscard]] constexpr bool check_invocable() {
+constexpr bool check_invocable() {
constexpr bool result = std::invocable<R(Args...), Args...>;
static_assert(std::invocable<R(Args...) noexcept, Args...> == result);
static_assert(std::invocable<R (*)(Args...), Args...> == result);
namespace pointer_to_member_functions {
// clang-format off
template<class Member, class T, class... Args>
- [[nodiscard]] constexpr bool check_member_is_invocable()
+ constexpr bool check_member_is_invocable()
{
constexpr bool result = std::invocable<Member, T, Args...>;
using uncv_t = std::remove_cvref_t<T>;
static_assert(!std::predicate<const Predicate, int, double, char>);
static_assert(!std::predicate<const Predicate&, int, double, char>);
-[[nodiscard]] constexpr bool check_lambda(auto) { return false; }
+constexpr bool check_lambda(auto) { return false; }
-[[nodiscard]] constexpr bool check_lambda(std::predicate auto) { return true; }
+constexpr bool check_lambda(std::predicate auto) { return true; }
static_assert(check_lambda([] { return std::true_type(); }));
static_assert(check_lambda([]() -> int* { return nullptr; }));
static_assert(!std::predicate<const Predicate, int, double, char>);
static_assert(!std::predicate<const Predicate&, int, double, char>);
-[[nodiscard]] constexpr bool check_lambda(auto) { return false; }
+constexpr bool check_lambda(auto) { return false; }
-[[nodiscard]] constexpr bool check_lambda(std::predicate auto) { return true; }
+constexpr bool check_lambda(std::predicate auto) { return true; }
static_assert(check_lambda([] { return std::true_type(); }));
static_assert(check_lambda([]() -> int* { return nullptr; }));
#include <concepts>
-[[nodiscard]] constexpr bool check_subsumption(std::regular_invocable auto) {
+constexpr bool check_subsumption(std::regular_invocable auto) {
return false;
}
// clang-format off
template<class F>
requires std::predicate<F> && true
-[[nodiscard]] constexpr bool check_subsumption(F)
+constexpr bool check_subsumption(F)
{
return true;
}
#include <concepts>
-[[nodiscard]] constexpr bool check_subsumption(std::regular_invocable auto) {
+constexpr bool check_subsumption(std::regular_invocable auto) {
return false;
}
// clang-format off
template<class F>
requires std::predicate<F> && true
-[[nodiscard]] constexpr bool check_subsumption(F)
+constexpr bool check_subsumption(F)
{
return true;
}
#include <type_traits>
template <class R, class... Args>
-[[nodiscard]] constexpr bool check_invocable() {
+constexpr bool check_invocable() {
constexpr bool result = std::regular_invocable<R(Args...), Args...>;
static_assert(std::regular_invocable<R(Args...) noexcept, Args...> == result);
static_assert(std::regular_invocable<R (*)(Args...), Args...> == result);
namespace pointer_to_member_functions {
// clang-format off
template<class Member, class T, class... Args>
- [[nodiscard]] constexpr bool check_member_is_invocable()
+ constexpr bool check_member_is_invocable()
{
constexpr bool result = std::regular_invocable<Member, T, Args...>;
using uncv_t = std::remove_cvref_t<T>;
template<class F, class T, class U>
requires std::predicate<F, T, T> && std::predicate<F, T, U> &&
std::predicate<F, U, T> && std::predicate<F, U, U>
-[[nodiscard]] constexpr bool check_relation_subsumes_predicate() {
+constexpr bool check_relation_subsumes_predicate() {
return false;
}
template<class F, class T, class U>
requires std::relation<F, T, U> && true
-[[nodiscard]] constexpr bool check_relation_subsumes_predicate() {
+constexpr bool check_relation_subsumes_predicate() {
return true;
}
// clang-format on
// clang-format off
template<class F, class T, class U>
requires std::relation<F, T, T> && std::relation<F, U, U>
-[[nodiscard]] constexpr bool check_relation_subsumes_itself() {
+constexpr bool check_relation_subsumes_itself() {
return false;
}
template<class F, class T, class U>
requires std::relation<F, T, U>
-[[nodiscard]] constexpr bool check_relation_subsumes_itself() {
+constexpr bool check_relation_subsumes_itself() {
return true;
}
// clang-format on
template<class F, class T, class U>
requires std::predicate<F, T, T> && std::predicate<F, T, U> &&
std::predicate<F, U, T> && std::predicate<F, U, U>
-[[nodiscard]] constexpr bool check_subsumption() { return false; }
+constexpr bool check_subsumption() { return false; }
template<class F, class T, class U>
requires std::relation<F, T, U> && true
-[[nodiscard]] constexpr bool check_subsumption() { return true; }
+constexpr bool check_subsumption() { return true; }
// clang-format on
static_assert(check_subsumption<int (*)(int, double), int, double>());
// clang-format off
template<class F, class T, class U>
requires std::relation<F, T, U>
-[[nodiscard]] constexpr bool check_strict_weak_order_subsumes_relation() {
+constexpr bool check_strict_weak_order_subsumes_relation() {
return false;
}
template<class F, class T, class U>
requires std::strict_weak_order<F, T, U> && true
-[[nodiscard]] constexpr bool check_strict_weak_order_subsumes_relation() {
+constexpr bool check_strict_weak_order_subsumes_relation() {
return true;
}
// clang-format on
// clang-format off
template<class F, class T, class U>
requires std::relation<F, T, U> && true
-[[nodiscard]] constexpr bool check_relation_subsumes_strict_weak_order() {
+constexpr bool check_relation_subsumes_strict_weak_order() {
return true;
}
template<class F, class T, class U>
requires std::strict_weak_order<F, T, U>
-[[nodiscard]] constexpr bool check_relation_subsumes_strict_weak_order() {
+constexpr bool check_relation_subsumes_strict_weak_order() {
return false;
}
// clang-format on
// clang-format off
template<class F, class T, class U>
requires std::strict_weak_order<F, T, T> && std::strict_weak_order<F, U, U>
-[[nodiscard]] constexpr bool check_strict_weak_order_subsumes_itself() {
+constexpr bool check_strict_weak_order_subsumes_itself() {
return false;
}
template<class F, class T, class U>
requires std::strict_weak_order<F, T, U>
-[[nodiscard]] constexpr bool check_strict_weak_order_subsumes_itself() {
+constexpr bool check_strict_weak_order_subsumes_itself() {
return true;
}
// clang-format on
// clang-format off
template<class F, class T, class U>
requires std::relation<F, T, U>
-[[nodiscard]] constexpr bool check_subsumption() { return false; }
+constexpr bool check_subsumption() { return false; }
template<class F, class T, class U>
requires std::strict_weak_order<F, T, U> && true
-[[nodiscard]] constexpr bool check_subsumption() { return true; }
+constexpr bool check_subsumption() { return true; }
// clang-format on
static_assert(check_subsumption<int (*)(int, double), int, double>());
constexpr Proxy proxy(A& a) { return Proxy{a}; }
} // namespace N
-[[nodiscard]] constexpr bool CheckRegression() {
+constexpr bool CheckRegression() {
int i = 1, j = 2;
lv_swap(i, j);
assert(i == 2 && j == 1);
// This overload should never be called. It exists solely to force subsumption.
template <std::integral I>
-[[nodiscard]] constexpr bool CheckSubsumption(I) {
+constexpr bool CheckSubsumption(I) {
return false;
}
// clang-format off
template <std::integral I>
requires std::signed_integral<I> && (!std::unsigned_integral<I>)
-[[nodiscard]] constexpr bool CheckSubsumption(I) {
+constexpr bool CheckSubsumption(I) {
return std::is_signed_v<I>;
}
template <std::integral I>
requires std::unsigned_integral<I> && (!std::signed_integral<I>)
-[[nodiscard]] constexpr bool CheckSubsumption(I) {
+constexpr bool CheckSubsumption(I) {
return std::is_unsigned_v<I>;
}
// clang-format on
static_assert(!std::regular<cv_copy_assignment const volatile>);
struct is_equality_comparable {
- [[nodiscard]] bool operator==(is_equality_comparable const&) const = default;
+ bool operator==(is_equality_comparable const&) const = default;
};
static_assert(std::regular<is_equality_comparable>);
#include <vector>
template <class T, class Expected>
-[[nodiscard]] constexpr bool check_iter_value_t() {
+constexpr bool check_iter_value_t() {
constexpr bool result = std::same_as<std::iter_value_t<T>, Expected>;
static_assert(std::same_as<std::iter_value_t<T const>, Expected> == result);
static_assert(std::same_as<std::iter_value_t<T volatile>, Expected> == result);
// clang-format off
template <class T>
requires requires { typename std::iter_value_t<T>; }
-[[nodiscard]] constexpr bool check_no_iter_value_t() {
+constexpr bool check_no_iter_value_t() {
return false;
}
// clang-format on
template <class T>
-[[nodiscard]] constexpr bool check_no_iter_value_t() {
+constexpr bool check_no_iter_value_t() {
return true;
}
// clang-format off
template<std::input_iterator>
-[[nodiscard]] constexpr bool check_subsumption() {
+constexpr bool check_subsumption() {
return false;
}
template<std::forward_iterator>
-[[nodiscard]] constexpr bool check_subsumption() {
+constexpr bool check_subsumption() {
return true;
}
// clang-format on
// clang-format off
template<std::weakly_incrementable I>
requires std::regular<I>
-[[nodiscard]] constexpr bool check_subsumption() {
+constexpr bool check_subsumption() {
return false;
}
template<std::incrementable>
-[[nodiscard]] constexpr bool check_subsumption() {
+constexpr bool check_subsumption() {
return true;
}
// clang-format on
// clang-format off
template<std::input_or_output_iterator I>
requires std::indirectly_readable<I>
-[[nodiscard]] constexpr bool check_subsumption() {
+constexpr bool check_subsumption() {
return false;
}
template<std::input_iterator>
-[[nodiscard]] constexpr bool check_subsumption() {
+constexpr bool check_subsumption() {
return true;
}
// clang-format on
// clang-format off
template<std::weakly_incrementable>
-[[nodiscard]] constexpr bool check_subsumption() {
+constexpr bool check_subsumption() {
return false;
}
template<std::input_or_output_iterator>
-[[nodiscard]] constexpr bool check_subsumption() {
+constexpr bool check_subsumption() {
return true;
}
// clang-format on
#include "read_write.h"
template <class In>
-[[nodiscard]] constexpr bool check_indirectly_readable() {
+constexpr bool check_indirectly_readable() {
constexpr bool result = std::indirectly_readable<In>;
static_assert(std::indirectly_readable<In const> == result);
static_assert(std::indirectly_readable<In volatile> == result);
// clang-format off
template<std::input_or_output_iterator, std::semiregular>
-[[nodiscard]] constexpr bool check_sentinel_subsumption() {
+constexpr bool check_sentinel_subsumption() {
return false;
}
template<class I, std::sentinel_for<I> >
-[[nodiscard]] constexpr bool check_subsumption() {
+constexpr bool check_subsumption() {
return true;
}
// clang-format on
#include "read_write.h"
template <class Out, class T>
-[[nodiscard]] constexpr bool check_indirectly_writable() {
+constexpr bool check_indirectly_writable() {
constexpr bool result = std::indirectly_writable<Out, T>;
static_assert(std::indirectly_writable<Out const, T> == result);
return result;
constexpr explicit iterator_wrapper(I i) noexcept : base_(std::move(i)) {}
// `noexcept(false)` is used to check that this operator is called.
- [[nodiscard]] constexpr decltype(auto) operator*() const& noexcept(false) { return *base_; }
+ constexpr decltype(auto) operator*() const& noexcept(false) { return *base_; }
// `noexcept` is used to check that this operator is called.
- [[nodiscard]] constexpr auto&& operator*() && noexcept { return std::move(*base_); }
+ constexpr auto&& operator*() && noexcept { return std::move(*base_); }
constexpr iterator_wrapper& operator++() noexcept {
++base_;
constexpr void operator++(int) noexcept { ++base_; }
- [[nodiscard]] constexpr bool operator==(iterator_wrapper const& other) const noexcept { return base_ == other.base_; }
+ constexpr bool operator==(iterator_wrapper const& other) const noexcept { return base_ == other.base_; }
private:
I base_ = I{};
constexpr explicit unqualified_lookup_wrapper(I i) noexcept : base_(std::move(i)) {}
- [[nodiscard]] constexpr decltype(auto) operator*() const noexcept { return *base_; }
+ constexpr decltype(auto) operator*() const noexcept { return *base_; }
constexpr unqualified_lookup_wrapper& operator++() noexcept {
++base_;
constexpr void operator++(int) noexcept { ++base_; }
- [[nodiscard]] constexpr bool operator==(unqualified_lookup_wrapper const& other) const noexcept {
+ constexpr bool operator==(unqualified_lookup_wrapper const& other) const noexcept {
return base_ == other.base_;
}
// Delegates `std::ranges::iter_move` for the underlying iterator. `noexcept(false)` will be used
// to ensure that the unqualified-lookup overload is chosen.
- [[nodiscard]] friend constexpr decltype(auto) iter_move(unqualified_lookup_wrapper& i) noexcept(false) {
+ friend constexpr decltype(auto) iter_move(unqualified_lookup_wrapper& i) noexcept(false) {
return std::ranges::iter_move(i.base_);
}
template<std::ranges::range R>
requires std::input_iterator<std::ranges::iterator_t<R>>
-[[nodiscard]] constexpr bool check_input_range_subsumption() {
+constexpr bool check_input_range_subsumption() {
return false;
}
template<std::ranges::input_range>
requires true
-[[nodiscard]] constexpr bool check_input_range_subsumption() {
+constexpr bool check_input_range_subsumption() {
return true;
}
template<std::ranges::input_range R>
requires std::forward_iterator<std::ranges::iterator_t<R>>
-[[nodiscard]] constexpr bool check_forward_range_subsumption() {
+constexpr bool check_forward_range_subsumption() {
return false;
}
template<std::ranges::forward_range>
requires true
-[[nodiscard]] constexpr bool check_forward_range_subsumption() {
+constexpr bool check_forward_range_subsumption() {
return true;
}
template<std::ranges::forward_range R>
requires std::bidirectional_iterator<std::ranges::iterator_t<R>>
-[[nodiscard]] constexpr bool check_bidirectional_range_subsumption() {
+constexpr bool check_bidirectional_range_subsumption() {
return false;
}
template<std::ranges::bidirectional_range>
requires true
-[[nodiscard]] constexpr bool check_bidirectional_range_subsumption() {
+constexpr bool check_bidirectional_range_subsumption() {
return true;
}
};
struct no_lt_not_totally_ordered_with {
- [[nodiscard]] bool operator==(no_lt_not_totally_ordered_with const&) const = default;
- [[nodiscard]] auto operator<=>(no_lt_not_totally_ordered_with const&) const = default;
+ bool operator==(no_lt_not_totally_ordered_with const&) const = default;
+ auto operator<=>(no_lt_not_totally_ordered_with const&) const = default;
operator totally_ordered_with_others() const noexcept;
- [[nodiscard]] bool operator==(totally_ordered_with_others const&) const;
- [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const;
- [[nodiscard]] auto operator<(totally_ordered_with_others const&) const;
+ bool operator==(totally_ordered_with_others const&) const;
+ auto operator<=>(totally_ordered_with_others const&) const;
+ auto operator<(totally_ordered_with_others const&) const;
};
struct no_gt_not_totally_ordered_with {
- [[nodiscard]] bool operator==(no_gt_not_totally_ordered_with const&) const = default;
- [[nodiscard]] auto operator<=>(no_gt_not_totally_ordered_with const&) const = default;
+ bool operator==(no_gt_not_totally_ordered_with const&) const = default;
+ auto operator<=>(no_gt_not_totally_ordered_with const&) const = default;
operator totally_ordered_with_others() const noexcept;
- [[nodiscard]] bool operator==(totally_ordered_with_others const&) const;
- [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const;
- [[nodiscard]] auto operator>(totally_ordered_with_others const&) const;
+ bool operator==(totally_ordered_with_others const&) const;
+ auto operator<=>(totally_ordered_with_others const&) const;
+ auto operator>(totally_ordered_with_others const&) const;
};
struct no_le_not_totally_ordered_with {
- [[nodiscard]] bool operator==(no_le_not_totally_ordered_with const&) const = default;
- [[nodiscard]] auto operator<=>(no_le_not_totally_ordered_with const&) const = default;
+ bool operator==(no_le_not_totally_ordered_with const&) const = default;
+ auto operator<=>(no_le_not_totally_ordered_with const&) const = default;
operator totally_ordered_with_others() const noexcept;
- [[nodiscard]] bool operator==(totally_ordered_with_others const&) const;
- [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const;
- [[nodiscard]] auto operator<=(totally_ordered_with_others const&) const;
+ bool operator==(totally_ordered_with_others const&) const;
+ auto operator<=>(totally_ordered_with_others const&) const;
+ auto operator<=(totally_ordered_with_others const&) const;
};
struct no_ge_not_totally_ordered_with {
- [[nodiscard]] bool operator==(no_ge_not_totally_ordered_with const&) const = default;
- [[nodiscard]] auto operator<=>(no_ge_not_totally_ordered_with const&) const = default;
+ bool operator==(no_ge_not_totally_ordered_with const&) const = default;
+ auto operator<=>(no_ge_not_totally_ordered_with const&) const = default;
operator totally_ordered_with_others() const noexcept;
- [[nodiscard]] bool operator==(totally_ordered_with_others const&) const;
- [[nodiscard]] auto operator<=>(totally_ordered_with_others const&) const;
- [[nodiscard]] auto operator>=(totally_ordered_with_others const&) const;
+ bool operator==(totally_ordered_with_others const&) const;
+ auto operator<=>(totally_ordered_with_others const&) const;
+ auto operator>=(totally_ordered_with_others const&) const;
};
struct partial_ordering_totally_ordered_with {
- [[nodiscard]] auto operator<=>(partial_ordering_totally_ordered_with const&) const noexcept = default;
- [[nodiscard]] std::partial_ordering operator<=>(totally_ordered_with_others const&) const noexcept;
+ auto operator<=>(partial_ordering_totally_ordered_with const&) const noexcept = default;
+ std::partial_ordering operator<=>(totally_ordered_with_others const&) const noexcept;
operator totally_ordered_with_others() const;
};
struct weak_ordering_totally_ordered_with {
- [[nodiscard]] auto operator<=>(weak_ordering_totally_ordered_with const&) const noexcept = default;
- [[nodiscard]] std::weak_ordering operator<=>(totally_ordered_with_others const&) const noexcept;
+ auto operator<=>(weak_ordering_totally_ordered_with const&) const noexcept = default;
+ std::weak_ordering operator<=>(totally_ordered_with_others const&) const noexcept;
operator totally_ordered_with_others() const;
};
struct strong_ordering_totally_ordered_with {
- [[nodiscard]] auto operator<=>(strong_ordering_totally_ordered_with const&) const noexcept = default;
- [[nodiscard]] std::strong_ordering operator<=>(totally_ordered_with_others const&) const noexcept;
+ auto operator<=>(strong_ordering_totally_ordered_with const&) const noexcept = default;
+ std::strong_ordering operator<=>(totally_ordered_with_others const&) const noexcept;
operator totally_ordered_with_others() const;
};
constexpr explicit stride_counting_iterator(I current) : base_(std::move(current)) {}
- [[nodiscard]] constexpr I const& base() const& { return base_; }
+ constexpr I const& base() const& { return base_; }
- [[nodiscard]] constexpr I base() && { return std::move(base_); }
+ constexpr I base() && { return std::move(base_); }
constexpr difference_type stride_count() const { return stride_count_; }