Simple Iterator class

Posts 1–3 of 3 · Page 1 of 1
Simple Iterator class

Just a simple iterator class I wrote for my framework, the iterators are compatible with range based
for loops if your class is done correct, working example found below.


block.h
Code:
template<typename T>
	class YDataAllocator
	{
	public:
		typedef T value_type;
		typedef value_type* pointer;
		typedef value_type& reference;
		typedef const value_type& const_reference;
		void operator=(const YDataAllocator&) = delete;
		pointer address(reference x) { return &x; };
		pointer allocate(size_t n)
		{
			void* p = std::malloc(n * sizeof(value_type));
			if (!p)
				throw std::bad_alloc();
			return static_cast<pointer>(p);
		}
		void deallocate(pointer p)
		{
			std::free(static_cast<void*>(p));
		}
		size_t max_size()
		{
			return static_cast<size_t>(-1) / static_cast<size_t>(value_type);
		}
		pointer construct(pointer p, const_reference v)
		{
			new(p) value_type(v);
			return p;
		}
		void deconstruct(pointer p)
		{
			p->~value_type();
		}

	};
Iterator.h
Code:
#pragma once
#include <iostream>

namespace Yami { 
	template<typename Px>
	class YIterator
	{
	private:
		template<typename Px>
		friend YIterator<Px> CreateIterator(Px*, size_t, size_t);
		Px* _arr;
		size_t _len;
		size_t _count;

	public:
		YIterator() : _arr(nullptr), _count(0), _len(0) {}
		Px* get()
		{
			return reinterpret_cast<Px*>(_arr + _count);
		}
		const size_t& length()
		{
			return _len;
		}
		const size_t& index()
		{
			return _count;
		}
	public: // Operators
		YIterator<Px> operator-(const size_t& off)
		{
			return (CreateIterator(_arr, _len, _count - off));
		}
		YIterator<Px> operator+(const size_t& off)
		{
			return (CreateIterator(_arr, _len, _count + off));
		}
		YIterator<Px>& operator+=(const size_t& off)
		{
			this->index() += off;
			return (*this);
		}
		YIterator<Px>& operator-=(const size_t& off)
		{
			this->index() -= off;
			return (*this);
		}
		Px& operator*()
		{
			return (_arr[_count]);
		};
		Px* operator->()
		{
			return get();
		}
		bool operator++()
		{
			if (_count >= _len)
				return false;
			++_count;
			return true;
		}
		bool operator--()
		{
			if (_count <= 0)
				return false;
			--_count;
			return true;
		}
		bool operator==(const YIterator<Px>& lhs) const
		{
			return (this->_arr + _count) == (lhs._arr + lhs._count);
		}
		bool operator!=(const YIterator<Px>& lhs) const
		{
			return !operator==(lhs);
		}
		bool operator>(const YIterator<Px>& lhs) const
		{
			return (this->_count > lhs._count);
		}
		bool operator>=(const YIterator<Px>& lhs) const
		{
			return (this->_count >= lhs._count);
		}
		bool operator<(const YIterator<Px>& lhs) const
		{
			return (this->_count < lhs._count);
		}
		bool operator<=(const YIterator<Px>& lhs) const
		{
			return (this->_count <= lhs._count);
		}
		YIterator<Px> operator[](const size_t& off)
		{
			return CreateIterator(_arr, _count, off);
		}
	};

	template<typename Px>
	class YReverseIterator
	{
		template<typename Px>
		friend YReverseIterator<Px> CreateReverseIterator(Px*, size_t, size_t);
		Px* _arr;
		size_t _len;
		size_t _count;

	public:
		YReverseIterator() : _arr(nullptr), _count(0), _len(0) {}
		Px* get()
		{
			return reinterpret_cast<Px*>(_arr + (_len - 1) - _count);
		}
		const size_t& length()
		{
			return _len;
		}
		const size_t& index()
		{
			return _count;
		}
	public: // Operators
		YReverseIterator<Px> operator-(const size_t& off)
		{
			return (CreateReverseIterator(_arr, _len, _count - off));
		}
		YReverseIterator<Px> operator+(const size_t& off)
		{
			return (CreateReverseIterator(_arr, _len, _count + off));
		}
		YReverseIterator<Px>& operator+=(const size_t& off)
		{
			this->index() += off;
			return (*this);
		}
		YReverseIterator<Px>& operator-=(const size_t& off)
		{
			this->index() -= off;
			return (*this);
		}
		Px& operator*()
		{
			return *get();
		};
		Px* operator->()
		{
			return get();
		}
		bool operator++()
		{
			if (_count >= _len)
				return false;
			++_count;
			return true;
		}
		bool operator--()
		{
			if (_count <= 0)
				return false;
			--_count;
			return true;
		}
		bool operator==(const YReverseIterator<Px>& other) const
		{
			return (this->_arr + _len - _count) == (other._arr + other._len - other._count);
		}
		bool operator!=(const YReverseIterator<Px>& other) const
		{
			return !operator==(other);
		}
		bool operator>(const YIterator<Px>& lhs) const
		{
			return (this->_count > lhs._count);
		}
		bool operator>=(const YIterator<Px>& lhs) const
		{
			return (this->_count >= lhs._count);
		}
		bool operator<(const YIterator<Px>& lhs) const
		{
			return (this->_count < lhs._count);
		}
		bool operator<=(const YIterator<Px>& lhs) const
		{
			return (this->_count <= lhs._count);
		}
		YReverseIterator<Px> operator[](const size_t& off)
		{
			return CreateReverseIterator(_arr, _count, off);
		}
	};
	template<typename Px>
	static YIterator<Px> CreateIterator(Px* array = nullptr, size_t length = 0, size_t offset = 0)
	{
		YIterator<Px> iter;
		iter._arr = array;
		iter._len = length;
		iter._count = offset;
		return (iter);
	}
	template<typename Px>
	static YReverseIterator<Px> CreateReverseIterator(Px* array = nullptr, size_t length = 0, size_t offset = 0)
	{
		YReverseIterator<Px> iter;
		iter._arr = array;
		iter._len = length;
		iter._count = offset;
		return (iter);
	}
}

Example of working class:
Code:
#include "Iterator.h"
#include "block.h"
#include <vector>


using namespace Yami;


// Simple class
template<typename T = int, size_t size = 0, typename Iter = YIterator<T>, typename RIter = YReverseIterator<T>, typename Alloc = YDataAllocator<T>>
class Array
{
private:
	T *_array; // Array
	Alloc _Alloc;

public:
	Array() { 
		_array = _Alloc.allocate(size);
		
		for (auto it = begin(); it != end(); ++it)
			_Alloc.construct(&(*it), 0);
		
	} // Allocate
	~Array() {
		_Alloc.deallocate(_array);
	} // Deallocate

	// Create a iterator for the first element
	Iter begin() { return CreateIterator(_array, size); } 
	// Create a iterator for the last element
	Iter end() { return CreateIterator(_array, size, size); }
	// Create a reverse iterator for the last element in the array (Goes from last to first)
	RIter rbegin() { return CreateReverseIterator(_array, size); };
	// Create a reverse iterator for the first element in the array
	RIter rend() { return CreateReverseIterator(_array, size, size); }

	T& at(size_t ind) { return _array[ind]; }
	size_t getSize() { return size; }
};


int main()
{
	Array<int, 5> arr;

	size_t c = 0;
	for (auto& el : arr) 
	{
		++c; // Dont mind this, just some random shit
		el = ((rand() % 45) + 1) + c;
		++c; // Dont mind this, just some random shit
	}
	std::cout << "Forward iterator:\n";

	for (auto it = arr.begin(); it != arr.end(); ++it) 
		std::cout << "Iterator " << it.index() << ": " << (*it) << std::endl;
	

	std::cout << "\nReverse iterator:\n";

	for (auto it = arr.rbegin(); it != arr.rend(); ++it)
		// The index will always start from zero, to get the backwards index take the length -1 -index
		std::cout << "Reverse Iterator " << (it.length() - it.index() - 1) << ": " << (*it) << std::endl;
	
	std::cin.get();
}
}
EDIT:
Added block.h & changed the Array class to use it for allocation :P


Any questions/Feedback is appreciated, just post it in the thread and I will try my best to reply.
std::allocator does more or less what your custom allocator class, YDataAllocator, does. I'd also suggest implementing std::iterator using the available tags in the std namespace but I've never really used standard iterators but implemented my own so I can't blame you.

Looks good (:

Edit: std::address_of also seems to be a more generic approach of getting the address of any type when dealing with templated classes.
Quote Originally Posted by maktm View Post
std::allocator does more or less what your custom allocator class, YDataAllocator, does. I'd also suggest implementing std::iterator using the available tags in the std namespace but I've never really used standard iterators but implemented my own so I can't blame you.

Looks good (:

Edit: std::address_of also seems to be a more generic approach of getting the address of any type when dealing with templated classes.
Thanks for feedback, I dont really use these clases ever, I just create them to sort of 'learn' or train new stuff I read about.
Posts 1–3 of 3 · Page 1 of 1

Post a Reply

Similar Threads

Tags for this Thread

None

Talk with us