blob: bad0db02d7cca236681d9b8394bd2795e7a04b87 [file] [edit]
// SPDX-FileCopyrightText: 2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// SPDX-FileCopyrightText: 2010 Hauke Heibel <hauke.heibel@gmail.com>
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
#ifndef EIGEN_STL_CONTAINER_TEST_HELPERS_H
#define EIGEN_STL_CONTAINER_TEST_HELPERS_H
#include <cstdint>
#include <iterator>
#include <vector>
#include <Eigen/Geometry>
template <typename Container>
typename Container::reference stl_container_at(Container& container, std::size_t index,
std::random_access_iterator_tag) {
return container[index];
}
template <typename Container>
typename Container::reference stl_container_at(Container& container, std::size_t index,
std::bidirectional_iterator_tag) {
auto iterator = container.begin();
std::advance(iterator, index);
return *iterator;
}
template <typename Container>
typename Container::reference stl_container_at(Container& container, std::size_t index) {
using Category = typename std::iterator_traits<typename Container::iterator>::iterator_category;
return stl_container_at(container, index, Category{});
}
template <typename Derived>
const Derived& stl_container_coeffs(const Eigen::MatrixBase<Derived>& value) {
return value.derived();
}
template <typename Scalar, int Dim, int Mode, int Options>
const typename Eigen::Transform<Scalar, Dim, Mode, Options>::MatrixType& stl_container_coeffs(
const Eigen::Transform<Scalar, Dim, Mode, Options>& value) {
return value.matrix();
}
template <typename Derived>
auto stl_container_coeffs(const Eigen::QuaternionBase<Derived>& value) -> decltype(value.coeffs()) {
return value.coeffs();
}
template <typename Container>
void verify_stl_contiguity(const Container&) {}
template <typename Value, typename Allocator>
void verify_stl_contiguity(const std::vector<Value, Allocator>& values) {
VERIFY(reinterpret_cast<std::uintptr_t>(&values[22]) ==
reinterpret_cast<std::uintptr_t>(&values[21]) + sizeof(Value));
}
template <typename Container, typename... Initializers>
void check_stl_container_front(Container& values, Container& other, const typename Container::value_type& x,
const typename Container::value_type& y, const Initializers&... initializers) {
values.front() = x;
other.front() = other.back();
VERIFY_IS_APPROX(other.front(), other.back());
values = other;
auto iterator = values.begin();
auto other_iterator = other.begin();
for (int i = 0; i < 20; ++i, ++iterator, ++other_iterator) VERIFY_IS_APPROX(*iterator, *other_iterator);
values.resize(21, initializers...);
values.back() = x;
VERIFY_IS_APPROX(values.back(), x);
values.resize(22, y);
VERIFY_IS_APPROX(values.back(), y);
values.push_back(x);
VERIFY_IS_APPROX(values.back(), x);
}
template <typename Container, typename... Initializers>
void check_stl_container_indexed(Container& values, Container& other, const typename Container::value_type& x,
const typename Container::value_type& y, const Initializers&... initializers) {
stl_container_at(values, 5) = x;
stl_container_at(other, 6) = stl_container_at(values, 5);
VERIFY_IS_APPROX(stl_container_at(other, 6), stl_container_at(values, 5));
values = other;
for (int i = 0; i < 20; ++i) VERIFY_IS_APPROX(stl_container_at(other, i), stl_container_at(values, i));
values.resize(21, initializers...);
stl_container_at(values, 20) = x;
VERIFY_IS_APPROX(stl_container_at(values, 20), x);
values.resize(22, y);
VERIFY_IS_APPROX(stl_container_at(values, 21), y);
values.push_back(x);
VERIFY_IS_APPROX(stl_container_at(values, 22), x);
verify_stl_contiguity(values);
// The old loop compared an address in the unchanged source, so it always appended 300 entries.
for (int i = 0; i < 300; ++i) values.push_back(stl_container_at(other, i % other.size()));
for (std::size_t i = 23; i < values.size(); ++i) {
VERIFY(stl_container_coeffs(stl_container_at(values, i)) ==
stl_container_coeffs(stl_container_at(other, (i - 23) % other.size())));
}
}
#endif // EIGEN_STL_CONTAINER_TEST_HELPERS_H