mirror of https://github.com/JAJames/Jupiter.git
Jessica James
8 years ago
3 changed files with 0 additions and 445 deletions
@ -1,441 +0,0 @@ |
|||||
/**
|
|
||||
* Copyright (C) 2013-2016 Jessica James. |
|
||||
* |
|
||||
* Permission to use, copy, modify, and/or distribute this software for any |
|
||||
* purpose with or without fee is hereby granted, provided that the above |
|
||||
* copyright notice and this permission notice appear in all copies. |
|
||||
* |
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
|
||||
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
|
||||
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
|
||||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
||||
* |
|
||||
* Written by Jessica James <jessica.aj@outlook.com> |
|
||||
*/ |
|
||||
|
|
||||
#if !defined _SLLIST_H_HEADER |
|
||||
#define _SLLIST_H_HEADER |
|
||||
|
|
||||
/**
|
|
||||
* @file SLList.h |
|
||||
* @brief Provides a generic Singly Linked List implementation using the List interface. |
|
||||
*/ |
|
||||
|
|
||||
#include "Jupiter.h" |
|
||||
#include "List.h" |
|
||||
|
|
||||
namespace Jupiter |
|
||||
{ |
|
||||
/**
|
|
||||
* @brief Provides a Singly Linked List implementation using the List interface. |
|
||||
*/ |
|
||||
template<typename T> class SLList : public List<T> |
|
||||
{ |
|
||||
public: |
|
||||
|
|
||||
/**
|
|
||||
* @brief Stores a pointer to data, and a pointer to the next node in the list. |
|
||||
*/ |
|
||||
struct Node |
|
||||
{ |
|
||||
Node *next = nullptr; |
|
||||
T *data = nullptr; |
|
||||
}; |
|
||||
|
|
||||
/*
|
|
||||
* @brief Returns the head of the list |
|
||||
* |
|
||||
* @return Head of the list |
|
||||
*/ |
|
||||
Node *getHead() const; |
|
||||
|
|
||||
/*
|
|
||||
* @brief Returns the tail of the list |
|
||||
* |
|
||||
* @return Tail of the list |
|
||||
*/ |
|
||||
Node *getTail() const; |
|
||||
|
|
||||
/**
|
|
||||
* @brief Returns the Node at the specified index in the list. |
|
||||
* |
|
||||
* @param index Index of the node to return. |
|
||||
* @return Node at specified index in the list. |
|
||||
*/ |
|
||||
Node *getNode(size_t index) const; |
|
||||
|
|
||||
/**
|
|
||||
* @brief Gets the data at a specified index. |
|
||||
* |
|
||||
* @param index Index of the data to get. |
|
||||
* @return Data stored at the specified index. |
|
||||
*/ |
|
||||
T *get(size_t index) const; |
|
||||
|
|
||||
/**
|
|
||||
* @brief Removes the head of the list |
|
||||
* |
|
||||
* @return Value that was stored in the head of the list |
|
||||
*/ |
|
||||
T *removeHead(); |
|
||||
|
|
||||
/**
|
|
||||
* @brief Removes the n'th Node in the list, and returns its contents. |
|
||||
* |
|
||||
* @param n Index of the node to remove. |
|
||||
* @return Contents of the node removed. |
|
||||
*/ |
|
||||
T *remove(size_t n); |
|
||||
|
|
||||
/**
|
|
||||
* @brief Removes the next node in the list. |
|
||||
* |
|
||||
* @param data Node that preceeds the node to be removed. |
|
||||
* @return Contents of the node removed if the node exists, nullptr otherwise. |
|
||||
*/ |
|
||||
T *removeNext(Node *data); |
|
||||
|
|
||||
/**
|
|
||||
* @brief Adds data to the end of the list. |
|
||||
* |
|
||||
* @param data Data to add to the list. |
|
||||
*/ |
|
||||
void add(T *data); |
|
||||
|
|
||||
/**
|
|
||||
* @brief Inserts data to the specified index in the list. |
|
||||
* |
|
||||
* @param data Data to insert into the list. |
|
||||
* @param index Position in the list to insert data to. |
|
||||
*/ |
|
||||
void add(T *data, size_t index); |
|
||||
|
|
||||
/**
|
|
||||
* @brief Inserts data to the head of the list. |
|
||||
* |
|
||||
* @param data Data to insert into the list. |
|
||||
*/ |
|
||||
void addHead(T *data); |
|
||||
|
|
||||
/**
|
|
||||
* @breif Erases all entries in the list |
|
||||
*/ |
|
||||
void erase(); |
|
||||
|
|
||||
/**
|
|
||||
* @breif Erases and deletes all entries in the list |
|
||||
*/ |
|
||||
void eraseAndDelete(); |
|
||||
|
|
||||
SLList &operator=(const SLList &in_list); |
|
||||
SLList &operator=(SLList &&in_list); |
|
||||
|
|
||||
/**
|
|
||||
* @brief Default constructor for the SLList class. |
|
||||
*/ |
|
||||
SLList() = default; |
|
||||
|
|
||||
/**
|
|
||||
* @brief Copy constructor for the SLList class. |
|
||||
* |
|
||||
* @param in_list List to copy data from |
|
||||
*/ |
|
||||
SLList(const SLList<T> &in_list); |
|
||||
|
|
||||
/**
|
|
||||
* @brief Move constructor for the SLList class |
|
||||
* |
|
||||
* @param in_list List to move data from |
|
||||
*/ |
|
||||
SLList(SLList<T> &&in_list); |
|
||||
|
|
||||
/**
|
|
||||
* @brief Destructor for the SLList class. |
|
||||
* Note: This does not delete data added to the list. |
|
||||
*/ |
|
||||
~SLList(); |
|
||||
|
|
||||
/** Private members */ |
|
||||
private: |
|
||||
void copy_from_internal(const SLList<T> &in_list); |
|
||||
|
|
||||
Node *m_head = nullptr; |
|
||||
Node *m_tail = nullptr; |
|
||||
}; |
|
||||
|
|
||||
} |
|
||||
|
|
||||
// Implementation
|
|
||||
|
|
||||
template<typename T> typename Jupiter::SLList<T>::Node *Jupiter::SLList<T>::getHead() const |
|
||||
{ |
|
||||
return m_head; |
|
||||
} |
|
||||
|
|
||||
template<typename T> typename Jupiter::SLList<T>::Node *Jupiter::SLList<T>::getTail() const |
|
||||
{ |
|
||||
return m_tail; |
|
||||
} |
|
||||
|
|
||||
template<typename T> typename Jupiter::SLList<T>::Node *Jupiter::SLList<T>::getNode(size_t in_index) const |
|
||||
{ |
|
||||
if (in_index == Jupiter::SLList<T>::length) |
|
||||
return m_tail; |
|
||||
|
|
||||
Jupiter::SLList<T>::Node *node = m_head; |
|
||||
|
|
||||
while (in_index != 0) |
|
||||
{ |
|
||||
node = node->next; |
|
||||
--in_index; |
|
||||
} |
|
||||
|
|
||||
return node; |
|
||||
} |
|
||||
|
|
||||
template<typename T> T *Jupiter::SLList<T>::get(size_t in_index) const |
|
||||
{ |
|
||||
return Jupiter::SLList<T>::getNode(in_index)->data; |
|
||||
} |
|
||||
|
|
||||
template<typename T> T *Jupiter::SLList<T>::removeHead() |
|
||||
{ |
|
||||
if (m_head == nullptr) |
|
||||
return nullptr; |
|
||||
|
|
||||
T *result = m_head->data; |
|
||||
|
|
||||
Jupiter::SLList<T>::Node *node = m_head; |
|
||||
m_head = m_head->next; |
|
||||
delete node; |
|
||||
--Jupiter::List<T>::length; |
|
||||
|
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
template<typename T> T *Jupiter::SLList<T>::remove(size_t in_index) |
|
||||
{ |
|
||||
if (in_index == 0) |
|
||||
return Jupiter::SLList<T>::removeHead(); |
|
||||
|
|
||||
Jupiter::SLList<T>::Node *node = m_head; |
|
||||
|
|
||||
while (in_index != 1) |
|
||||
{ |
|
||||
node = node->next; |
|
||||
--in_index; |
|
||||
} |
|
||||
|
|
||||
Jupiter::SLList<T>::Node *tmp = node->next; |
|
||||
T *result = tmp->data; |
|
||||
|
|
||||
node->next = tmp->next; |
|
||||
delete tmp; |
|
||||
--Jupiter::List<T>::length; |
|
||||
|
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
template<typename T> T *Jupiter::SLList<T>::removeNext(Node *in_data) |
|
||||
{ |
|
||||
Jupiter::SLList<T>::Node *node = in_data->next; |
|
||||
|
|
||||
if (node == nullptr) |
|
||||
return nullptr; |
|
||||
|
|
||||
T *result = node->data; |
|
||||
|
|
||||
in_data->next = node->next; |
|
||||
delete node; |
|
||||
--Jupiter::List<T>::length; |
|
||||
|
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
template<typename T> void Jupiter::SLList<T>::add(T *data) |
|
||||
{ |
|
||||
Jupiter::SLList<T>::Node *node = new Jupiter::SLList<T>::Node(); |
|
||||
node->data = data; |
|
||||
|
|
||||
if (m_head == nullptr) |
|
||||
m_head = node; |
|
||||
else |
|
||||
m_tail->next = node; |
|
||||
|
|
||||
m_tail = node; |
|
||||
++Jupiter::List<T>::length; |
|
||||
} |
|
||||
|
|
||||
template<typename T> void Jupiter::SLList<T>::add(T *in_data, size_t in_index) |
|
||||
{ |
|
||||
if (in_index == 0) |
|
||||
{ |
|
||||
Jupiter::SLList<T>::addHead(in_data); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if (in_index >= Jupiter::List<T>::length) |
|
||||
{ |
|
||||
Jupiter::SLList<T>::add(in_data); |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
Jupiter::SLList<T>::Node *node = new Jupiter::SLList<T>::Node(); |
|
||||
node->data = in_data; |
|
||||
|
|
||||
Jupiter::SLList<T>::Node *itr = m_head; |
|
||||
|
|
||||
while (in_index != 1) |
|
||||
{ |
|
||||
itr = itr->next; |
|
||||
--in_index; |
|
||||
} |
|
||||
|
|
||||
node->next = itr->next; |
|
||||
itr->next = node; |
|
||||
|
|
||||
++Jupiter::List<T>::length; |
|
||||
} |
|
||||
|
|
||||
template<typename T> void Jupiter::SLList<T>::addHead(T *data) |
|
||||
{ |
|
||||
Jupiter::SLList<T>::Node *node = new Jupiter::SLList<T>::Node(); |
|
||||
node->data = data; |
|
||||
node->next = m_head; |
|
||||
m_head = node; |
|
||||
|
|
||||
if (m_tail == nullptr) |
|
||||
m_tail = node; |
|
||||
|
|
||||
++Jupiter::List<T>::length; |
|
||||
} |
|
||||
|
|
||||
template<typename T> void Jupiter::SLList<T>::erase() |
|
||||
{ |
|
||||
Jupiter::SLList<T>::Node *node = m_head; |
|
||||
|
|
||||
if (node == nullptr) |
|
||||
return; |
|
||||
|
|
||||
Jupiter::SLList<T>::Node *tmp; |
|
||||
|
|
||||
do |
|
||||
{ |
|
||||
tmp = node; |
|
||||
node = node->next; |
|
||||
delete tmp; |
|
||||
} while (node != nullptr); |
|
||||
|
|
||||
m_head = nullptr; |
|
||||
m_tail = nullptr; |
|
||||
Jupiter::List<T>::length = 0; |
|
||||
} |
|
||||
|
|
||||
template<typename T> void Jupiter::SLList<T>::eraseAndDelete() |
|
||||
{ |
|
||||
Jupiter::SLList<T>::Node *node = m_head; |
|
||||
|
|
||||
if (node == nullptr) |
|
||||
return; |
|
||||
|
|
||||
Jupiter::SLList<T>::Node *tmp; |
|
||||
|
|
||||
do |
|
||||
{ |
|
||||
tmp = node; |
|
||||
node = node->next; |
|
||||
delete tmp->data; |
|
||||
delete tmp; |
|
||||
} while (node != nullptr); |
|
||||
|
|
||||
m_head = nullptr; |
|
||||
m_tail = nullptr; |
|
||||
Jupiter::List<T>::length = 0; |
|
||||
} |
|
||||
|
|
||||
template<> struct _Jupiter_DataBuffer_partial_specialization_impl<Jupiter::SLList> |
|
||||
{ |
|
||||
template<typename Y> static void push(Jupiter::DataBuffer *buffer, const Jupiter::SLList<Y> *data) |
|
||||
{ |
|
||||
buffer->push<size_t>(data->size()); |
|
||||
Jupiter::SLList<Y>::Node *head = data->getHead(); |
|
||||
while (head != nullptr) |
|
||||
buffer->push<Y>(*head++->data); |
|
||||
}; |
|
||||
|
|
||||
template<typename Y> static Jupiter::SLList<Y> interpret(uint8_t *&head) |
|
||||
{ |
|
||||
size_t size_ = *reinterpret_cast<size_t *>(head); |
|
||||
head += sizeof(size_t); |
|
||||
Jupiter::SLList<Y> r; |
|
||||
while (size_-- != 0) |
|
||||
r.add(Jupiter::DataBuffer::interpret_data<Y>(head)); |
|
||||
return r; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
template<typename T> Jupiter::SLList<T> &Jupiter::SLList<T>::operator=(const SLList &in_list) |
|
||||
{ |
|
||||
Jupiter::SLList<T>::erase(); |
|
||||
|
|
||||
Jupiter::SLList<T>::copy_from_internal(in_list); |
|
||||
|
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
template<typename T> Jupiter::SLList<T> &Jupiter::SLList<T>::operator=(SLList &&in_list) |
|
||||
{ |
|
||||
m_head = in_list.m_head; |
|
||||
m_tail = in_list.m_tail; |
|
||||
|
|
||||
return *this; |
|
||||
} |
|
||||
|
|
||||
template<typename T> Jupiter::SLList<T>::SLList(const Jupiter::SLList<T> &in_list) |
|
||||
{ |
|
||||
Jupiter::SLList<T>::copy_from_internal(in_list); |
|
||||
} |
|
||||
|
|
||||
template<typename T> Jupiter::SLList<T>::SLList(Jupiter::SLList<T> &&in_list) |
|
||||
{ |
|
||||
m_head = in_list.m_head; |
|
||||
m_tail = in_list.m_tail; |
|
||||
|
|
||||
in_list.m_head = nullptr; |
|
||||
in_list.m_tail = nullptr; |
|
||||
} |
|
||||
|
|
||||
template<typename T> Jupiter::SLList<T>::~SLList() |
|
||||
{ |
|
||||
Jupiter::SLList<T>::erase(); |
|
||||
} |
|
||||
|
|
||||
/** Internal */ |
|
||||
|
|
||||
template<typename T> void Jupiter::SLList<T>::copy_from_internal(const SLList<T> &in_list) |
|
||||
{ |
|
||||
Jupiter::SLList<T>::Node *source_node = in_list.m_head; |
|
||||
|
|
||||
if (source_node == nullptr) |
|
||||
return; |
|
||||
|
|
||||
Jupiter::SLList<T>::Node *node = new Jupiter::SLList<T>::Node(); |
|
||||
node->data = source_node->data; |
|
||||
source_node = source_node->next; |
|
||||
|
|
||||
while (source_node != nullptr) |
|
||||
{ |
|
||||
node->next = new Jupiter::SLList<T>::Node(); |
|
||||
node = node->next; |
|
||||
node->data = source_node->data; |
|
||||
source_node = source_node->next; |
|
||||
} |
|
||||
|
|
||||
m_tail = node; |
|
||||
Jupiter::List<T>::length = in_list.length; |
|
||||
} |
|
||||
|
|
||||
#endif // _SLLIST_H_HEADER
|
|
Loading…
Reference in new issue