Click here to Skip to main content
15,887,928 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
#include <exception>
#include <functional>
#include <iostream>
#include <stdexcept>
#include <string>

template<typename T>
class DEQeue
{
public:

    enum class Iterate { BackToFront, FrontToBack };

    DEQeue()
    {
        first_ = NULL;
        last_ = NULL;
    }

    void push_front(const T& item)
    {
        if (first_ == NULL)
        {
            first_ = new Node();
            first_ -> item = item;
            first_ -> prev = NULL;
            first_ -> next = NULL;
            last_ = first_;
        }
        else
        {
            Node* oldFirst = first_;
            first_ = new Node();
            first_ -> item = item;
            first_ -> prev = NULL;
            first_ -> next = oldFirst;
            oldFirst -> prev = first_;
        }
    }

    void push_back(const T& item)
    {
        if (last_ == NULL)
        {
            last_ = new Node();
            last_ -> item = item;
            last_ -> prev = NULL;
            last_ -> next = NULL;
            first_ = last_;
        }
        else
        {
            Node* oldLast = last_;
            last_ = new Node();
            last_ -> item = item;
            last_ -> prev = oldLast;
            last_ -> next = NULL;
            oldLast -> next = last_;
        }
    }

    T pop_front() 
    {
        if (isEmpty()) throw std::out_of_range("OMFG! The DEQeue was empty.");
        T item = first_ -> item;
        first_ = first_ -> next;
        if (first_ == NULL) last_ = NULL;
        return item;
    }

    T pop_back() 
    {
        if (isEmpty()) throw std::out_of_range("OMFG! The DEQeue was empty.");
        T item = last_ -> item;
        last_ = last_ -> prev;
        if (last_ == NULL) first_ = NULL;
        return item;
    }

    bool isEmpty()
    {
        return first_ == NULL;
    }

    void each(std::function<void(T)> function, Iterate it = Iterate::FrontToBack)
    {
        if (it == Iterate::FrontToBack)
        {
            Node* node = first_;
            while (node != NULL)
            {
                function(node -> item);
                node = node -> next;
            }
        }
        else 
        {
            Node* node = last_;
            while (node != NULL)
            {
                function(node -> item);
                node = node -> prev;
            }
        }
    }

private:
    struct Node
    {
        T item;
        Node* prev;
        Node* next;
    };

    Node* first_;
    Node* last_;
};

int main(int argc, char const *argv[])
{
    enum class Latice { sc, bcc, fcc, hcp };
    DEQeue<Latice> deqi;

    for (int i = 10000000; i > 0; i --)
        deqi.push_back(Latice::sc);

    deqi.each([](Latice lt){
        switch (lt)
        {
            case Latice::sc:
                std::cout << "sc";
                break;
            case Latice::fcc:
                std::cout << "fcc";
                break;
            case Latice::bcc:
                std::cout << "bcc";
                break;
            case Latice::hcp:
                std::cout << "hcp";
                break;
        }
        std::cout << std::endl;
    });

    return 0;
}
Posted
Comments
nv3 26-Oct-15 4:10am    
Start with your Node struct. You just have to convert the classes member functions into C functions. The member data of the class goes into a separate struct, a pointer of which you pass as the first argument of each of these C functions.
Philippe Mori 27-Oct-15 18:52pm    
Usually a bad idea except if you have to support hardware where C++ is not available.

1 solution

The golden rule is, that a class gets a struct and the class functions getting a "this" parameter at first added, in which a pointer to the structure is given.

The template cant be solved. So you must use a pointer. Maybe an union helps.

It isnt the best idea to loose that feature, but maybe you need it.
 
Share this answer
 
Comments
Philippe Mori 27-Oct-15 18:55pm    
Well, macro might be used for "templates" if you need that stuff for a few cases. However, it might be much harder to optimize or adapt code for specific types (for example, to reuse a "void *" implementation for any deque of pointers).

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900