// slist.h (UNFINISHED)
// Glenn G. Chappell
// 12 Apr 2008
// Header for SList Class Template
// Singly Linked List with client-specified value type

#ifndef FILE_SLIST_H_INCLUDED
#define FILE_SLIST_H_INCLUDED

#include <cstdlib>    // for std::size_t
#include <algorithm>  // for std::swap


// SList
// Singly Linked List class template
template <typename T>
class SList {

// ***** SList: types *****
public:

    typedef T value_type;           // Type of data item in the list
    typedef std::size_t size_type;  // Type of the size of a list

// ***** SList: ctors, dctor, op= *****
public:

    // default ctor
    SList()
        :head_(0),
         size_(0)
    {}

    // copy ctor
    SList(const SList & other)
    {
        // WRITE THIS!!!
    }

    // copy assignment
    SList & operator=(const SList & rhs)
    {
        if (this != &rhs)
        {
            SList tmp(rhs);
            swap(tmp);
        }
        return *this;
    }

    // dctor
    ~SList()
    { delete head_; }

// ***** SList: general public functions - required *****
public:

    // size
    size_type size() const
    { return size_; }

    // read
    template <typename InputIterator>
    void read(InputIterator first, InputIterator last)
    {
        // WRITE THIS!!!
    }
    
    // write
    template <typename OutputIterator>
    void write(OutputIterator dest) const
    {
        // WRITE THIS!!!
    }

    // reverse
    void reverse()
    {
        // WRITE THIS!!!
    }

// ***** SList: general public functions - additional *****
public:

    // swap
    void swap(SList & other)
    {
        std::swap(head_, other.head_);
        std::swap(size_, other.size_);
    }

// ***** SList: node type *****
private:

    // struct Node
    // Node type for SList
    // A Node<T> is a Singly Linked List Node with
    //  value type T and a pointer to another Node<T>.
    template <typename T>
    struct Node {

        // Constructor
        // For convenience
        Node(const T & theData,
             Node * theNext)
            :data_(theData),
             next_(theNext)
        {}

        // Destructor
        ~Node()
        { delete next_; }

        // Data members
        T data_;       // Our data item
        Node * next_;  // Pointer to next node, or NULL if none
    };

// ***** SList: data members *****
private:

    Node<value_type> * head_;  // Pointer to first node in list, or NULL if none
    size_type size_;           // Number of items in list

};  // end class SList

#endif  //#ifndef FILE_SLIST_H_INCLUDED