Exercising the LinkedList template class, reverses the text that is entered - C++ template

C++ examples for template:template class

Description

Exercising the LinkedList template class, reverses the text that is entered

Demo Code

#include <string>
#include <iostream>

#include <memory>

using std::string;

template<typename T> class LinkedList
{
  class Node;                                                // Declaration required because class is not yet defined
  using PNode = std::shared_ptr<Node>;                       // and we refeence it here
private:/* ww w.ja va  2 s.  c  om*/
  PNode pHead {};                                            // Pointer to first element node
  PNode pTail {};                                            // Pointer to last element node
  PNode pLast {};                                            // Pointer to last node accessed

public:
  LinkedList() = default;                                    // Constructor
  LinkedList(const LinkedList& list);                        // Copy constructor
  LinkedList& operator=(const LinkedList& list);             // Assignment operator
  void addHead(T* pObj);                                     // Add an object to the head
  void addTail(T* pObj);                                     // Add an object to the tail
  T* getHead();                                              // Get the object at the head
  T* getTail();                                              // Get the object at the head
  T* getNext();                                              // Get the next object
  T* getPrevious();                                          // Get the previous object

private:
  // Node class definition
  class Node
  {
  public:
    int index {};                                          // Index of element
    T* pObject {};                                            // Reference to object
    PNode pNext {};                                           // Pointer to next node
    PNode pPrevious {};                                       // Pointer to previous node

    Node(T* pObj) : pObject {new T {*pObj}} {}                 // Constructor
    Node(const Node& node) : index {node.index}, pObject {new T {*node.pObject}} {}  // Copy constructor

    ~Node() { delete pObject; }                                // Destructor
  };
};


// Copy constructor template
template<typename T> LinkedList<T>::LinkedList(const LinkedList& list)
{
  if (list.pHead)
  {                                  // If there is a first element
    pTail = pHead = std::make_shared<Node>(*list.pHead);         // Duplicate it

    PNode pTemp;
    PNode pCurrent = list.pHead;
    while (pCurrent = pCurrent->pNext)
    {                                                            // Duplicate any further nodes
      pTemp = pTail;                                             // Save the address of the last
      pTail = std::make_shared<Node>(*pCurrent);                 // Make the new one the last
      pTemp->pNext = pTail;                                      // Set the next pointer of old last
      pTail->pPrevious = pTemp;                                  // Set previous pointer of new last
    }
  }
}

// Assignment operator template
template<typename T> LinkedList<T>& LinkedList<T>::operator=(const LinkedList& list)
{
  if (this == &list)                                             // Check for rhs same as lhs
    return *this;

  PNode pCurrent;
  if (list.pHead)
  {
    pTail = pHead = std::make_shared<Node>(*list.pHead);
    Node* pTemp {};
    pCurrent = list.pHead;
    while (pCurrent = pCurrent->pNext)
    {
      pTemp = pTail;
      pTail = std::make_shared<Node>(*pCurrent);
      pTemp->pNext = pTail;
      pTail->pPrevious = pTemp;
      pTemp = pTail;
    }
  }
  return *this;
}

// Template function member to add an object to the head of the list
template<typename T> void LinkedList<T>::addHead(T* pObj)
{
  if (pHead)
  {
    pHead->pPrevious = std::make_shared<Node>(pObj);
    pHead->pPrevious->pNext = pHead;
    pHead = pHead->pPrevious;
  }
  else
    pHead = pTail = std::make_shared<Node>(pObj);
  pLast = pHead;
}

// Template function member to add an object to the tail of the list
template<typename T> void LinkedList<T>::addTail(T* pObj)
{
  if (pTail)
  {
    pTail->pNext = std::make_shared<Node>(pObj);
    pTail->pNext->pPrevious = pTail;
    pTail = pTail->pNext;
  }
  else
    pHead = pTail = std::make_shared<Node>(pObj);
  pLast = pTail;
}

// Template function member to get the object at the head of the list
template<typename T> T* LinkedList<T>::getHead()
{
  pLast = pHead;
  if (pHead)
    return pHead->pObject;
  else
    return nullptr;
}

// Template function member to get the object at the tail of the list
template<typename T> T* LinkedList<T>::getTail()
{
  pLast = pTail;
  if (pTail)
    return pTail->pObject;
  else
    return nullptr;
}

// Template function member to get the next object
template<typename T> T* LinkedList<T>::getNext()
{
  if (pLast)
    if (pLast = pLast->pNext)
      return pLast->pObject;
  return nullptr;
}

// Template function member to get the previous object
template<typename T> T* LinkedList<T>::getPrevious()
{
  if (pLast)
    if (pLast = pLast->pPrevious)
      return pLast->pObject;
  return nullptr;
}

int main()
{
  string text {"this is a test"};

  LinkedList<string> words;                      // List to store words

  // Extract words and store in the list
  string separators(" ,.\"?!;:\n");              // Separators between words
  int start {};                               // Start of a word
  int end {};                                 // separator position after a word
  while(string::npos != (start = text.find_first_not_of(separators, start)))
  {
    end = text.find_first_of(separators, start+1);
    words.addTail(&text.substr(start,end-start));
    start = end;
  }

  // List the words 5 to a line
  std::cout << "\nThe words are:\n\n";
  auto pStr = words.getHead();
  int count {};                               // Word counter
  const int perline {5};                      // Worde per line
  while (pStr)
  {
    std::cout << *pStr << ' ';
    if (!(++count % perline))
      std::cout << std::endl;
    pStr = words.getNext();
  }
  std::cout << std::endl;

  // List the words in reverse order 5 to a line
  std::cout << "\nIn reverse order, the words are:\n\n";
  pStr = words.getTail();
  count = 0;
  while(pStr)
  {
    std::cout << *pStr << ' ';
    if(!(++count % perline))
      std::cout << std::endl;
    pStr = words.getPrevious();
  }
  std::cout << std::endl;
}

Result


Related Tutorials