summaryrefslogtreecommitdiff
path: root/Runtime/Utilities/StrideIterator.h
blob: c36877e07569995b1b34769c4736e9a273d85a52 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#ifndef STRIDE_ITERATOR_H_
#define STRIDE_ITERATOR_H_

#include <iterator>

template<class T>
class StrideIterator : public std::iterator<std::random_access_iterator_tag, T>
{
public:
	//@TODO: Get rid of all stl usage and remove this crap.
	typedef std::iterator<std::random_access_iterator_tag, T> base_iterator;
	typedef typename base_iterator::value_type value_type;
	typedef typename base_iterator::difference_type difference_type;
	typedef typename base_iterator::pointer pointer;
	typedef typename base_iterator::reference reference;
	typedef typename base_iterator::iterator_category iterator_category;
	
	StrideIterator () : m_Pointer(NULL), m_Stride(1) {}
	StrideIterator (void* p, int stride) : m_Pointer (reinterpret_cast<UInt8*> (p)), m_Stride (stride) {}
	StrideIterator (StrideIterator const& arg) : m_Pointer(arg.m_Pointer), m_Stride(arg.m_Stride) {}
    
    void operator = (StrideIterator const& arg) { m_Pointer = arg.m_Pointer; m_Stride = arg.m_Stride; }
    
    bool operator == (StrideIterator const& arg) const { return m_Pointer == arg.m_Pointer; }
    bool operator != (StrideIterator const& arg) const { return m_Pointer != arg.m_Pointer; }

	bool operator < (StrideIterator const& arg) const { return m_Pointer < arg.m_Pointer; }
	
	void operator++()                       { m_Pointer += m_Stride; }
	void operator++(int)                    { m_Pointer += m_Stride; }

	StrideIterator operator + (difference_type n) const { return StrideIterator (m_Pointer + m_Stride * n, m_Stride); }
	void operator += (difference_type n)                { m_Pointer += m_Stride * n; }
	
	difference_type operator-(StrideIterator const& it) const
	{
		Assert (m_Stride == it.m_Stride && "Iterators stride must be equal");
		Assert (m_Stride != 0 && "Stide must not be zero");
		return ((uintptr_t)m_Pointer - (uintptr_t)it.m_Pointer) / m_Stride;
	}
	
	T& operator[](size_t index)             { return *reinterpret_cast<T*> (m_Pointer + m_Stride * index); }
	const T& operator[](size_t index) const { return *reinterpret_cast<const T*> (m_Pointer + m_Stride * index); }
	
	T& operator*()                          { return *reinterpret_cast<T*> (m_Pointer); }
	const T& operator*() const              { return *reinterpret_cast<const T*> (m_Pointer); }
	
	T* operator->()                         { return reinterpret_cast<T*> (m_Pointer); }
	const T* operator->() const             { return reinterpret_cast<const T*> (m_Pointer); }
	
	// Iterator is NULL if not valid
	bool IsNull () const { return m_Pointer == 0; }
	void* GetPointer() const { return m_Pointer; }
	int GetStride() const { return m_Stride; }

private:
	UInt8* m_Pointer;
	int    m_Stride;
};

template<class T>
void strided_copy (const T* src, const T* srcEnd, StrideIterator<T> dst)
{
	for (; src != srcEnd ; src++, ++dst)
		*dst = *src;
}

template<class T>
void strided_copy (StrideIterator<T> src, StrideIterator<T> srcEnd, StrideIterator<T> dst)
{
	for (; src != srcEnd ; ++src, ++dst)
		*dst = *src;
}

template<class T>
void strided_copy (StrideIterator<T> src, StrideIterator<T> srcEnd, T* dst)
{
	for (; src != srcEnd ;  ++src, ++dst)
		*dst = *src;
}

template<class T, class T2>
void strided_copy_convert (const T* src, const T* srcEnd, StrideIterator<T2> dst)
{
	for (; src != srcEnd ;  ++src, ++dst)
		*dst = *src;
}

#endif // STRIDE_ITERATOR_H_