ForwardList.hpp #4

  • //
  • guest/
  • ShadauxCat/
  • Sprawl/
  • Mainline/
  • collections/
  • ForwardList.hpp
  • View
  • Commits
  • Open Download .zip Download (3 KB)
#pragma once

#include "list/ForwardListItem.hpp"
#include "iterator/ListIterator.hpp"

namespace sprawl
{
	namespace collections
	{
		template<typename T>
		class ForwardList;
	}
}

template<typename T>
class sprawl::collections::ForwardList
{
public:
	typedef detail::ForwardListItem<T> ItemType;
	typedef ListIterator<T, ItemType, std::forward_iterator_tag> iterator;
	typedef ListIterator<T, ItemType, std::forward_iterator_tag> const const_iterator;

	ForwardList()
		: m_first(nullptr)
		, m_size(0)
	{
		//
	}

	~ForwardList()
	{
		Clear();
	}

	ForwardList(ForwardList const& other)
		: m_first(nullptr)
		, m_size(0)
	{
		m_first = new ItemType(other.m_first->m_value);
		ItemType* item = m_first;
		ItemType* otherItem = other.m_first;
		while(otherItem->next)
		{
			item->next = new ItemType(otherItem->next->m_value);
			item = item->next;
			otherItem = otherItem->next;
		}
	}

	ForwardList(ForwardList&& other)
		: m_first(other.m_first)
		, m_size(other.m_size)
	{
		other.m_first = nullptr;
		other.m_size = 0;
	}

	void PushFront(T const& item)
	{
		ItemType* newItem = new ItemType(item);
		if(m_first == nullptr)
		{
			m_first = newItem;
			++m_size;
		}
		else
		{
			insertBefore_(newItem, m_first);
		}
	}

	void PushFront(T&& item)
	{
		ItemType* newItem = new ItemType(std::move(item));
		if(m_first == nullptr)
		{
			m_first = newItem;
		}
		else
		{
			insertBefore_(newItem, m_first);
		}
	}

	void PopFront()
	{
		ItemType* item = m_first;
		m_first = m_first->next;
		delete item;
	}

	void Insert(const_iterator& insertAfter, T const& item)
	{
		ItemType* newItem = new ItemType(item);
		ItemType* insertAfterItem = insertAfter.m_currentItem;
		insertAfter_(newItem, insertAfterItem);
	}

	void Insert(const_iterator& insertAfter, T&& item)
	{
		ItemType* newItem = new ItemType(std::move(item));
		ItemType* insertAfterItem = insertAfter.m_currentItem;
		insertAfter_(newItem, insertAfterItem);
	}

	void EraseAfter(const_iterator& iter)
	{
		ItemType* item = iter.m_currentItem;
		if(!item)
		{
			return;
		}
		ItemType* eraseItem = item->next;
		if(!eraseItem)
		{
			return;
		}
		item->next = eraseItem->next;
		delete eraseItem;
		--m_size;
	}

	size_t Size()
	{
		return m_size;
	}

	bool Empty()
	{
		return m_size == 0;
	}

	T& Front()
	{
		return m_first->m_value;
	}

	T const& Front() const
	{
		return m_first->m_value;
	}

	void Clear()
	{
		ItemType* item = m_first;
		while(item)
		{
			ItemType* del = item;
			item = item->next;
			delete del;
		}
		m_first = nullptr;
		m_size = 0;
	}

	iterator begin()
	{
		return iterator(m_first);
	}

	iterator end()
	{
		return iterator(nullptr);
	}

	const_iterator begin() const
	{
		return const_iterator(m_first);
	}

	const_iterator end() const
	{
		return const_iterator(nullptr);
	}

	const_iterator cbegin()
	{
		return const_iterator(m_first);
	}

	const_iterator cend()
	{
		return const_iterator(nullptr);
	}

private:
	void insertAfter_(ItemType* newItem, ItemType* insertAfter)
	{
		if(insertAfter->next)
		{
			newItem->next = insertAfter->next;
		}
		insertAfter->next = newItem;
		++m_size;
	}

	void insertBefore_(ItemType* newItem, ItemType* insertBefore)
	{
		newItem->next = insertBefore;
		if(newItem->next == m_first)
		{
			m_first = newItem;
		}
		++m_size;
	}

	ItemType* m_first;
	size_t m_size;
};
# Change User Description Committed
#7 14163 ShadauxCat -Renamed HashMap functions to follow coding style.
Only begin, end, find, and variants are left lowercase, in keeping with C++ algorithm and range-based for support.
-Fixed some accounting issues with list and forwardlist; size wasn't properly being maintained.
-Made a small pedantic change to ThreadManager to ensure that m_numThreadsSynced got reset to 0 before the NotifyAll() to eliminate the miniscule potential for deadlock it would cause if it happened after another thread had already woken up.

#review-14164
#6 14144 ShadauxCat Switching unit tests to gtest.
100 is a decent number of tests to start with, but it needs to be more like 400 to test the current codebase.

#review-14145
#5 14100 ShadauxCat -Added Deque implementation using circular buffer.
-Fixed List::Insert() and ForwardList::Insert() inserting after the iterator instead of before it. Adjusted the unit tests to compensate.
-Fixed a couple of small vector bugs

#review-14101
#4 14091 ShadauxCat -Created Vector class, iterator, and unit test
-Made list iterator a bidirectional iterator when created from a doubly-linked list. (It still has operator-- when created from singly-linked list, but it won't compile if it's used.)
-Changed front() and back() in list classes to Front() and Back()

#review-14083
#3 14081 ShadauxCat -Switching order of keys and values in HashMap::insert().
Keys now come first - a number of parameters equal to the number of keys. (Simple case is simply insert(key, value))
-Added move constructors to AccessorGroup so things can be inserted into the map via rvalue references
-Fixed ForwardList's copy constructor copying things in reverse and added a unit test to make sure it doesn't happen again.

#review-14079
#2 12508 ShadauxCat -Added threading library.
Currently only functional for Linux; Windows will fail to link. (I will fix this soon.)
-Fixed missing move and copy constructors in List and ForwardList
-Fixed broken move constructor in HashMap
-Fixed missing const get() in HashMap
-Fixed broken operator-> in ListIterator
-Added sprawl::noncopyable
-Added sketch headers for filesystem library
-Made StringLiteral hashable, added special hashes for pointers and integers in murmur3
-Fixed compiler warning in async_network
-Updated memory allocators to use new threading library for mutexes
-Added accessibility to sprawl::StringLiteral to be able toa ccess its pointer and length and perform pointer comparisons

#review-12504
#1 11496 ShadauxCat Initial checkin: Current states for csbuild and libSprawl