Notice: If you are member of any public project or group, please make sure that your GitLab username is not the same as the LRZ identifier/Kennung (see https://gitlab.lrz.de/profile/account). Please change your username if necessary. For more information see the section "Public projects / Öffentliche Projekte" at https://doku.lrz.de/display/PUBLIC/GitLab . Thank you!

Commit 43bffa07 authored by David's avatar David

Further iterator implementation

Now not using some hacky std iterator, but a iterator, which properly wraps pointer to DataContainer
parent 8dc57d26
......@@ -278,7 +278,7 @@ namespace elsa {
template <typename data_t>
typename DataContainer<data_t>::const_iterator DataContainer<data_t>::begin() const
{
return const_iterator(&(*this)[0]);
return cbegin();
}
template <typename data_t>
......@@ -290,55 +290,55 @@ namespace elsa {
template <typename data_t>
typename DataContainer<data_t>::iterator DataContainer<data_t>::end()
{
return ++iterator(&(*this)[getSize()-1]);
return iterator(&(*this)[0] + getSize());
}
template <typename data_t>
typename DataContainer<data_t>::const_iterator DataContainer<data_t>::end() const
{
return ++const_iterator(&(*this)[getSize()-1]);
return cend();
}
template <typename data_t>
typename DataContainer<data_t>::const_iterator DataContainer<data_t>::cend() const
{
return ++const_iterator(&(*this)[getSize()-1]);
return const_iterator(&(*this)[0] + getSize());
}
template <typename data_t>
typename DataContainer<data_t>::reverse_iterator DataContainer<data_t>::rbegin()
{
return reverse_iterator(end());
return reverse_iterator(iterator(&(*this)[0] + getSize() - 1));
}
template <typename data_t>
typename DataContainer<data_t>::const_reverse_iterator DataContainer<data_t>::rbegin() const
{
return const_reverse_iterator(cend());
return crbegin();
}
template <typename data_t>
typename DataContainer<data_t>::const_reverse_iterator DataContainer<data_t>::crbegin() const
{
return const_reverse_iterator(cend());
return const_reverse_iterator(const_iterator(&(*this)[0] + getSize() - 1));
}
template <typename data_t>
typename DataContainer<data_t>::reverse_iterator DataContainer<data_t>::rend()
{
return reverse_iterator(begin());
return reverse_iterator(iterator(&(*this)[0] - 1));
}
template <typename data_t>
typename DataContainer<data_t>::const_reverse_iterator DataContainer<data_t>::rend() const
{
return const_reverse_iterator(cbegin());
return crend();
}
template <typename data_t>
typename DataContainer<data_t>::const_reverse_iterator DataContainer<data_t>::crend() const
{
return const_reverse_iterator(cbegin());
return const_reverse_iterator(&(*this)[0] - 1);
}
// ------------------------------------------
......
......@@ -7,6 +7,7 @@
#include <memory>
#include <type_traits>
#include <iterator>
namespace elsa
{
......@@ -27,6 +28,12 @@ namespace elsa
template <typename data_t = real_t>
class DataContainer {
public:
using value_type = data_t;
using pointer = data_t*;
using const_pointer = const data_t*;
using reference = data_t&;
using const_reference = const data_t&;
using difference_type = std::ptrdiff_t;
/**
* \brief type of the DataHandler used to store the actual data
*
......@@ -193,49 +200,139 @@ namespace elsa
/* Iterators */
/// alias for iterator type, use a random vector access iterator
using iterator = typename std::vector<data_t>::iterator;
/// alias for const iterator type
using const_iterator = typename std::vector<data_t>::const_iterator;
/**
* Iterator class for the DataContainer. It Wraps a pointer and assumes continuous memory
*/
class iterator
{
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = DataContainer<data_t>::value_type;
using difference_type = DataContainer<data_t>::difference_type;
using pointer = DataContainer<data_t>::pointer;
using reference = DataContainer<data_t>::reference;
iterator(pointer ptr) : ptr_(ptr) { }
reference operator*() {return *ptr_;}
const_reference operator*() const {return *ptr_;}
pointer operator->() {return ptr_;}
const_pointer operator->() const {return ptr_;}
reference operator[](int m) {return ptr_[m];}
const_reference operator[](int m) const {return ptr_[m];}
iterator operator++() { auto i = *this; ptr_++; return i; }
iterator operator++(int junk) { ptr_++; return *this; }
iterator operator--() { auto i = *this; ptr_--; return i; }
iterator operator--(int junk) { ptr_--; return *this; }
iterator& operator+=(int n) { ptr_ += n; return *this;}
iterator& operator-=(int n) { ptr_ += n; return *this;}
iterator operator+(int n) const { iterator r(*this); return r += n;}
iterator operator-(int n) const { iterator r(*this); return r -= n;}
difference_type operator-(iterator const& r) const { return ptr_ - r.ptr_; }
// Note: comparing iterator from different containers
// is undefined behavior so we don't need to check
// if they are the same container.
bool operator< (const iterator& r) const { return ptr_ < r.ptr_; }
bool operator<=(const iterator& r) const { return ptr_ <= r.ptr_; }
bool operator> (const iterator& r) const { return ptr_ > r.ptr_; }
bool operator>=(const iterator& r) const { return ptr_ >= r.ptr_; }
bool operator!=(const iterator &r) const { return ptr_ != r.ptr_; }
bool operator==(const iterator &r) const { return ptr_ == r.ptr_; }
private:
pointer ptr_ {};
};
/**
* Const Iterator class for the DataContainer. It Wraps a pointer and assumes continuous memory,
* but can't mutate underlying memory
*/
class const_iterator
{
public:
using iterator_category = std::random_access_iterator_tag;
using value_type = DataContainer<data_t>::value_type;
using difference_type = DataContainer<data_t>::difference_type;
using pointer = DataContainer<data_t>::const_pointer;
using reference = DataContainer<data_t>::const_reference;
/* implicit */ const_iterator(const_pointer ptr) : ptr_(ptr) { }
reference operator*() const {return *ptr_;}
pointer operator->() const {return ptr_;}
reference operator[](int m) const {return ptr_[m];}
const_iterator operator++() { auto i = *this; ptr_++; return i; }
const_iterator operator++(int junk) { ptr_++; return *this; }
const_iterator operator--() { auto i = *this; ptr_--; return i; }
const_iterator operator--(int junk) { ptr_--; return *this; }
const_iterator& operator+=(int n) { ptr_ += n; return *this;}
const_iterator& operator-=(int n) { ptr_ += n; return *this;}
const_iterator operator+(int n) const { const_iterator r(*this); return r += n;}
const_iterator operator-(int n) const { const_iterator r(*this); return r -= n;}
difference_type operator-(const_iterator const& r) const { return ptr_ - r.ptr_; }
// Note: comparing iterator from different containers
// is undefined behavior so we don't need to check
// if they are the same container.
bool operator< (const const_iterator& r) const { return ptr_ < r.ptr_; }
bool operator<=(const const_iterator& r) const { return ptr_ <= r.ptr_; }
bool operator> (const const_iterator& r) const { return ptr_ > r.ptr_; }
bool operator>=(const const_iterator& r) const { return ptr_ >= r.ptr_; }
bool operator!=(const const_iterator &r) const { return ptr_ != r.ptr_; }
bool operator==(const const_iterator &r) const { return ptr_ == r.ptr_; }
private:
pointer ptr_ {};
};
/// alias for reverse iterator
using reverse_iterator = std::reverse_iterator<iterator>;
/// alias for const reverse iterator
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
/// returns iterator to beginning of vector
/// returns iterator to the first element of vector
iterator begin();
/// returns iterator to beginning of vector, which can't mutate data
/// returns iterator to the first element of the vector, which can't mutate data
const_iterator begin() const;
/// returns iterator to beginning of vector, which can't mutate data
/// returns iterator to the first element of the vector, which can't mutate data
const_iterator cbegin() const;
/// returns iterator to end of vector
/// returns iterator to one past the last element of the vector
iterator end();
/// returns iterator to end of vector, which can't mutate data
/// returns iterator to one past the last element of the vector, which can't mutate data
const_iterator end() const;
/// returns iterator to end of vector, which can't mutate data
/// returns iterator to one past the last element of the vector, which can't mutate data
const_iterator cend() const;
/// returns reversed iterator to end of vector
/// returns reversed iterator to the last element of the vector
reverse_iterator rbegin();
/// returns reversed iterator to end of vector, which can't mutate data
/// returns reversed iterator to the last element of the vector, which can't mutate data
const_reverse_iterator rbegin() const;
/// returns reversed iterator to end of vector, which can't mutate data
/// returns reversed iterator to the last element of the vector, which can't mutate data
const_reverse_iterator crbegin() const;
/// returns reversed iterator to beginning of vector
/// returns reversed iterator to one past the first element of vector
reverse_iterator rend();
/// returns reversed iterator to beginning of vector, which can't mutate data
/// returns reversed iterator to one past the first element of vector, which can't mutate data
const_reverse_iterator rend() const;
/// returns reversed iterator to beginning of vector, which can't mutate data
/// returns reversed iterator to one past the first element of vector, which can't mutate data
const_reverse_iterator crend() const;
......
......@@ -395,8 +395,8 @@ SCENARIO("Testing iterators for DataContainer") {
THEN("We can iterate forward") {
int i = 0;
for(auto v : dc1) {
REQUIRE(v == randVec1[i++]);
for(auto v=dc1.cbegin(); v != dc1.cend(); v++) {
REQUIRE(*v == randVec1[i++]);
}
REQUIRE(i == size);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment