Skip to content

Commit

Permalink
allow use of ranges with parameterized tests
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverlee authored and kris-jusiak committed Oct 19, 2023
1 parent 6a3d4c1 commit 20f2c3f
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 20 deletions.
6 changes: 6 additions & 0 deletions example/parameterized.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/ut.hpp>
#include <ranges>
#include <string>
#include <tuple>
#include <type_traits>
Expand All @@ -26,6 +27,11 @@ int main() {
expect(arg > 0_i) << "all values greater than 0";
} | std::vector{1, 2, 3};

/// Alternative syntax
"views"_test = [](auto arg) {
expect(arg > 0_i) << "all values greater than 0";
} | std::views::iota(1, 4);

/// Alternative syntax
"types"_test = []<class T>() {
expect(std::is_integral_v<T>) << "all types are integrals";
Expand Down
25 changes: 13 additions & 12 deletions include/boost/ut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ constexpr auto is_valid(...) -> bool {
}

template <class T>
inline constexpr auto is_container_v =
inline constexpr auto is_range_v =
is_valid<T>([](auto t) -> decltype(t.begin(), t.end(), void()) {});

template <class T>
Expand Down Expand Up @@ -1345,7 +1345,7 @@ class printer {

template <class T,
type_traits::requires_t<not type_traits::has_user_print<T> and
type_traits::is_container_v<T>> = 0>
type_traits::is_range_v<T>> = 0>
auto& operator<<(T&& t) {
*this << '{';
auto first = true;
Expand Down Expand Up @@ -2606,12 +2606,12 @@ namespace operators {
return detail::neq_{lhs, rhs};
}

template <class T, type_traits::requires_t<type_traits::is_container_v<T>> = 0>
template <class T, type_traits::requires_t<type_traits::is_range_v<T>> = 0>
[[nodiscard]] constexpr auto operator==(T&& lhs, T&& rhs) {
return detail::eq_{static_cast<T&&>(lhs), static_cast<T&&>(rhs)};
}

template <class T, type_traits::requires_t<type_traits::is_container_v<T>> = 0>
template <class T, type_traits::requires_t<type_traits::is_range_v<T>> = 0>
[[nodiscard]] constexpr auto operator!=(T&& lhs, T&& rhs) {
return detail::neq_{static_cast<T&&>(lhs), static_cast<T&&>(rhs)};
}
Expand Down Expand Up @@ -2704,23 +2704,24 @@ template <class Test>
}

template <class F, class T,
type_traits::requires_t<type_traits::is_container_v<T>> = 0>
type_traits::requires_t<type_traits::is_range_v<T>> = 0>
[[nodiscard]] constexpr auto operator|(const F& f, const T& t) {
return [f, t](const auto name) {
for (const auto& arg : t) {
detail::on<F>(events::test<F, typename T::value_type>{.type = "test",
.name = name,
.tag = {},
.location = {},
.arg = arg,
.run = f});
detail::on<F>(events::test<F, decltype(arg)>{
.type = "test",
.name = name,
.tag = {},
.location = {},
.arg = arg,
.run = f});
}
};
}

template <
class F, template <class...> class T, class... Ts,
type_traits::requires_t<not type_traits::is_container_v<T<Ts...>>> = 0>
type_traits::requires_t<not type_traits::is_range_v<T<Ts...>>> = 0>
[[nodiscard]] constexpr auto operator|(const F& f, const T<Ts...>& t) {
return [f, t](const auto name) {
apply(
Expand Down
16 changes: 8 additions & 8 deletions test/ut/ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,14 +414,14 @@ int main() {

{
struct foo {};
static_assert(type_traits::is_container_v<std::vector<int>>);
static_assert(type_traits::is_container_v<std::array<bool, 0>>);
static_assert(type_traits::is_container_v<std::string>);
static_assert(type_traits::is_container_v<std::string_view>);
static_assert(type_traits::is_container_v<std::map<int, int>>);
static_assert(not type_traits::is_container_v<int>);
static_assert(not type_traits::is_container_v<foo>);
static_assert(not type_traits::is_container_v<void>);
static_assert(type_traits::is_range_v<std::vector<int>>);
static_assert(type_traits::is_range_v<std::array<bool, 0>>);
static_assert(type_traits::is_range_v<std::string>);
static_assert(type_traits::is_range_v<std::string_view>);
static_assert(type_traits::is_range_v<std::map<int, int>>);
static_assert(not type_traits::is_range_v<int>);
static_assert(not type_traits::is_range_v<foo>);
static_assert(not type_traits::is_range_v<void>);
}

{
Expand Down

0 comments on commit 20f2c3f

Please sign in to comment.