diff --git a/src/util/range.hpp b/src/util/range.hpp index 9cb8a84a1706785ef05934129efe3327048c26cb..9249800df7125d03a4f589d7a1b5b6adc1e0b676 100644 --- a/src/util/range.hpp +++ b/src/util/range.hpp @@ -67,7 +67,7 @@ struct range { range& operator=(const range&) = default; range& operator=(range&&) = default; - bool empty() const { return size() == 0; } + bool empty() const { return left == right; } iterator begin() const { return left; } const_iterator cbegin() const { return left; } @@ -80,8 +80,7 @@ struct range { size() const { auto b = make_sentinel_iterator(begin(), end()); auto e = make_sentinel_end(begin(), end()); - auto dist = std::distance(b, e); - return (dist < 0) ? 0 : dist; + return std::distance(b, e); } constexpr size_type max_size() const { return std::numeric_limits<size_type>::max(); } diff --git a/tests/unit/test_counter.cpp b/tests/unit/test_counter.cpp index 7c97f2277e08a865ebb0be0a7e7b9d4db18f7360..600d86ca171980ce6d17036d1d74936cafbd1ed0 100644 --- a/tests/unit/test_counter.cpp +++ b/tests/unit/test_counter.cpp @@ -128,4 +128,3 @@ REGISTER_TYPED_TEST_CASE_P(counter_test, value, compare, arithmetic, iterator_tr using int_types = ::testing::Types<signed char, unsigned char, short, unsigned short, int, unsigned, std::size_t, std::ptrdiff_t>; INSTANTIATE_TYPED_TEST_CASE_P(int_types, counter_test, int_types); - diff --git a/tests/unit/test_range.cpp b/tests/unit/test_range.cpp index af6ac52df08892cc337369612ba46500a8d120b9..fb7c7fc7b34128468c1d66891b09267a160b298c 100644 --- a/tests/unit/test_range.cpp +++ b/tests/unit/test_range.cpp @@ -11,6 +11,7 @@ #include <tbb/tbb_stddef.h> #endif +#include <util/counter.hpp> #include <util/range.hpp> #include <util/sentinel.hpp> @@ -76,6 +77,11 @@ TEST(range, empty) { auto l = 2; auto r = 5; + auto empty_range = util::make_range(&xs[l], &xs[l]); + EXPECT_TRUE(empty_range.empty()); + EXPECT_TRUE(empty_range.size() == 0); + + EXPECT_TRUE(util::make_range(&xs[l], &xs[l]).empty()); EXPECT_TRUE(util::make_range(&xs[r], &xs[r]).empty()); EXPECT_TRUE(util::make_range(&xs[r], &xs[l]).empty()); @@ -140,6 +146,94 @@ TEST(range, sentinel) { EXPECT_TRUE(empty_cstr_range.empty()); } +template <typename V> +class counter_range: public ::testing::Test {}; + +TYPED_TEST_CASE_P(counter_range); + +TYPED_TEST_P(counter_range, max_size) { + using int_type = TypeParam; + using unsigned_int_type = typename std::make_unsigned<int_type>::type; + using counter = util::counter<int_type>; + + auto l = counter{int_type{1}}; + auto r = counter{int_type{10}}; + auto range = util::make_range(l, r); + EXPECT_EQ(std::numeric_limits<unsigned_int_type>::max(), + range.max_size()); + +} + +TYPED_TEST_P(counter_range, extreme_size) { + using int_type = TypeParam; + using signed_int_type = typename std::make_signed<int_type>::type; + using unsigned_int_type = typename std::make_unsigned<int_type>::type; + using counter = util::counter<signed_int_type>; + + auto l = counter{std::numeric_limits<signed_int_type>::min()}; + auto r = counter{std::numeric_limits<signed_int_type>::max()}; + auto range = util::make_range(l, r); + EXPECT_FALSE(range.empty()); + EXPECT_EQ(std::numeric_limits<unsigned_int_type>::max(), range.size()); + +} + + +TYPED_TEST_P(counter_range, size) { + using int_type = TypeParam; + using signed_int_type = typename std::make_signed<int_type>::type; + using counter = util::counter<signed_int_type>; + + auto l = counter{signed_int_type{-3}}; + auto r = counter{signed_int_type{3}}; + auto range = util::make_range(l, r); + EXPECT_FALSE(range.empty()); + EXPECT_EQ(6, range.size()); + +} + +TYPED_TEST_P(counter_range, at) { + using int_type = TypeParam; + using signed_int_type = typename std::make_signed<int_type>::type; + using counter = util::counter<signed_int_type>; + + auto l = counter{signed_int_type{-3}}; + auto r = counter{signed_int_type{3}}; + auto range = util::make_range(l, r); + EXPECT_EQ(range.front(), range.at(0)); + EXPECT_EQ(0, range.at(3)); + EXPECT_EQ(range.back(), range.at(range.size()-1)); + EXPECT_THROW(range.at(range.size()), std::out_of_range); + EXPECT_THROW(range.at(30), std::out_of_range); +} + +TYPED_TEST_P(counter_range, iteration) { + using int_type = TypeParam; + using signed_int_type = typename std::make_signed<int_type>::type; + using counter = util::counter<signed_int_type>; + + auto j = signed_int_type{-3}; + auto l = counter{signed_int_type{j}}; + auto r = counter{signed_int_type{3}}; + + for (auto i : util::make_range(l, r)) { + EXPECT_EQ(j++, i); + } +} + + +REGISTER_TYPED_TEST_CASE_P(counter_range, max_size, extreme_size, size, at, + iteration); + +using int_types = ::testing::Types<signed char, unsigned char, short, + unsigned short, int, unsigned, long, + std::size_t, std::ptrdiff_t>; + +using signed_int_types = ::testing::Types<signed char, short, + int, long, std::ptrdiff_t>; + +INSTANTIATE_TYPED_TEST_CASE_P(int_types, counter_range, int_types); + #ifdef WITH_TBB TEST(range, tbb_split) {