#include "base/containers/checked_iterators.h"
#include <algorithm>
#include <iterator>
#include "base/check_op.h"
#include "base/ranges/algorithm.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
TEST(CheckedContiguousIterator, StaticComparisonOperators) {
static constexpr int arr[] = {0};
constexpr CheckedContiguousConstIterator<int> begin(arr, arr, arr + 1);
constexpr CheckedContiguousConstIterator<int> end(arr, arr + 1, arr + 1);
static_assert(begin == begin, "");
static_assert(end == end, "");
static_assert(begin != end, "");
static_assert(end != begin, "");
static_assert(begin < end, "");
static_assert(begin <= begin, "");
static_assert(begin <= end, "");
static_assert(end <= end, "");
static_assert(end > begin, "");
static_assert(end >= end, "");
static_assert(end >= begin, "");
static_assert(begin >= begin, "");
}
TEST(CheckedContiguousIterator, ConvertingComparisonOperators) {
static int arr[] = {0};
CheckedContiguousIterator<int> begin(arr, arr, arr + 1);
CheckedContiguousConstIterator<int> cbegin(arr, arr, arr + 1);
CheckedContiguousIterator<int> end(arr, arr + 1, arr + 1);
CheckedContiguousConstIterator<int> cend(arr, arr + 1, arr + 1);
EXPECT_EQ(begin, cbegin);
EXPECT_EQ(cbegin, begin);
EXPECT_EQ(end, cend);
EXPECT_EQ(cend, end);
EXPECT_NE(begin, cend);
EXPECT_NE(cbegin, end);
EXPECT_NE(end, cbegin);
EXPECT_NE(cend, begin);
EXPECT_LT(begin, cend);
EXPECT_LT(cbegin, end);
EXPECT_LE(begin, cbegin);
EXPECT_LE(cbegin, begin);
EXPECT_LE(begin, cend);
EXPECT_LE(cbegin, end);
EXPECT_LE(end, cend);
EXPECT_LE(cend, end);
EXPECT_GT(end, cbegin);
EXPECT_GT(cend, begin);
EXPECT_GE(end, cend);
EXPECT_GE(cend, end);
EXPECT_GE(end, cbegin);
EXPECT_GE(cend, begin);
EXPECT_GE(begin, cbegin);
EXPECT_GE(cbegin, begin);
}
}
#if defined(_LIBCPP_VERSION) && !BUILDFLAG(IS_NACL) && !BUILDFLAG(IS_CHROMEOS)
namespace {
template <typename Iterator>
struct DisableDerefAndIncr : Iterator {
using Iterator::Iterator;
constexpr DisableDerefAndIncr(const Iterator& iter) : Iterator(iter) {}
constexpr typename Iterator::reference operator*() {
CHECK(false);
return Iterator::operator*();
}
constexpr Iterator& operator++() {
CHECK(false);
return Iterator::operator++();
}
constexpr Iterator operator++(int i) {
CHECK(false);
return Iterator::operator++(i);
}
};
}
namespace std {
template <typename Iter>
struct __is_cpp17_contiguous_iterator<DisableDerefAndIncr<Iter>>
: __is_cpp17_contiguous_iterator<Iter> {};
template <typename Iter>
struct pointer_traits<DisableDerefAndIncr<Iter>> : pointer_traits<Iter> {};
}
namespace base {
TEST(CheckedContiguousIterator, OptimizedCopy) {
using Iter = DisableDerefAndIncr<CheckedContiguousIterator<int>>;
int arr_in[5] = {1, 2, 3, 4, 5};
int arr_out[5];
Iter in_begin(std::begin(arr_in), std::end(arr_in));
Iter in_end(std::begin(arr_in), std::end(arr_in), std::end(arr_in));
Iter out_begin(std::begin(arr_out), std::end(arr_out));
Iter out_end = std::copy(in_begin, in_end, out_begin);
EXPECT_EQ(out_end, out_begin + (in_end - in_begin));
EXPECT_TRUE(ranges::equal(arr_in, arr_out));
}
}
#endif