Double LinkedList

This is my program but it does not compile can you guys help me, if you need more code let me know I can add it in another comment.

iterator.h
#ifndef ITERATOR_H
#define ITERATOR_H
#include "dnode.h"
template<class Item>
class dlist;
template <class Item>
class node_iterator: public std::iterator<std::bidirectional_iterator_tag, Item>{
public:
friend class dlist<Item>;
node_iterator(dnode<Item>* init = NULL){current = init;}
Item& operator *() const{return current -> data();}
node_iterator& operator ++(){
current = current -> next();
return *this;
}
node_iterator& operator ++(int){
node_iterator<Item> original(current);
current = current -> next();
return original;
}
node_iterator& operator --(){
current = current -> previous();
return *this;
}
node_iterator& operator --(int){
node_iterator<Item> original(current);
current = current -> previous();
return original;
}
bool operator ==(const node_iterator<Item> other) const{return current == other.current;}
bool operator !=(const node_iterator<Item> other) const{return current != other.current;}
private:
dnode<Item>* current;
};

template <class Item>
class const_node_iterator: public std::iterator<std::bidirectional_iterator_tag, Item>{
public:
friend class dlist<Item>;
const_node_iterator(dnode<Item>* init = NULL){current = init;}
const Item& operator *() const{return current -> data();}
const_node_iterator& operator ++(){
current = current -> next();
return *this;
}
const_node_iterator& operator ++(int){
node_iterator<Item> original(current);
current = current -> next();
return original;
}
const_node_iterator& operator --(){
current = current -> previous();
return *this;
}
const_node_iterator& operator --(int){
node_iterator<Item> original(current);
current = current -> previous();
return original;
}
bool operator ==(const node_iterator<Item> other) const{return current == other.current;}
bool operator !=(const node_iterator<Item> other) const{return current != other.current;}
private:
const dnode<Item>* current;
};
#endif

dlist.h
#ifndef DLIST_H
#define DLIST_H
#include "dnode.h"
#include "iterator.h"
template<class Item>
class dlist{
public:
typedef node_iterator<Item> iterator;
typedef const_node_iterator<Item> const_iterator;
dlist();
dlist(const dlist& source);
~dlist();
void operator =(const dlist& source);
void rear_insert(const Item& entry);
void show();
void front_insert(const Item& entry);
void front_remove();
void rear_remove();
void insert_before(iterator position, const Item& entry);
void insert_after(iterator position, const Item& entry);
void remove(iterator position);
int size();
iterator begin(){return iterator(head);}
const_iterator begin() const{return iterator(head);}
iterator end(){return iterator();}
const_iterator end() const{return iterator();}
iterator r_begin(){return iterator(tail);}
const_iterator r_begin() const{return iterator(tail);}
iterator r_end(){return iterator();}
const_iterator r_end() const{return iterator();}
private:
dnode<Item>* head;
dnode<Item>* tail;
};
#include "dlist.template"
#endif

dlist.template
template <class Item>
dlist<Item>::dlist(){
head = NULL;
tail = NULL;
}

template<class Item>
dlist<Item>::dlist(const dlist& source){
head = NULL;
tail = NULL;
if(source.head == NULL){
return;
}
dnode<Item>* sourceCursor = source.head;
while(sourceCursor != NULL){
rear_insert(sourceCursor -> data());
sourceCursor = sourceCursor -> next();
}
}

template<class Item>
dlist<Item>::~dlist(){
dnode<Item>* cursor = head;
dnode<Item>* remove_ptr;
while(cursor != NULL){
remove_ptr = cursor;
cursor = cursor -> next();
delete remove_ptr;
}
}

template<class Item>
void dlist<Item>::operator =(const dlist& source){
if(this == &source){
return;
}
dnode<Item>* cursor = head;
dnode<Item>* remove_ptr;
while(cursor != NULL){
remove_ptr = cursor;
cursor = cursor -> next();
delete remove_ptr;
}
if(source.head == NULL){
return;
}
head = NULL;
tail = NULL;
dnode<Item>* sourceCursor = source.head;
while(sourceCursor -> next() != NULL){
rear_insert(sourceCursor -> data());
sourceCursor = sourceCursor -> next();
}
}

template <class Item>
void dlist<Item>::rear_insert(const Item& entry){
if(head == NULL){
head = new dnode<Item>(entry);
tail = head;
}else{
tail -> set_next(new dnode<Item>(entry, NULL, tail));
tail = tail -> next();
}
}

template <class Item>
void dlist<Item>::show(){
dnode<Item>* cursor;
for(cursor = head; cursor != NULL; cursor = cursor -> next()){
std::cout << cursor -> data() << std::endl;
}
}

template <class Item>
void dlist<Item>::front_insert(const Item& entry){
if(head == NULL){
head = new dnode<Item>(entry);
tail = head;
}else{
head -> set_previous(new dnode<Item>(entry, head, NULL));
head = head -> previous();
}
}

template <class Item>
void dlist<Item>::front_remove() {
if(head == NULL) {
return;
}
if(head == tail) {
return;
}
head = head -> set_next();
head -> set_previous(NULL);
return;
}

template <class Item>
void dlist<Item>::rear_remove() {
if(tail == NULL) {
return;
}
if(head == tail) {
return;
}
tail = tail -> previous();
tail -> set_next(NULL);
return;
}

template<class Item>
void dlist<Item>::insert_before(iterator it, const Item& entry) {
if(it == begin() || it == r_end() || it == r_begin()) {
front_insert(entry);
}
dnode<Item> *tmp2 = new dnode<Item>;
tmp2 -> set_data(entry);
tmp2 -> set_next(it.current);
tmp2 -> set_previous(it.current -> previous());
it.current -> previous() -> set_next(tmp2);
it.current -> set_previous(tmp2);
}

template<class Item>
void dlist<Item>::insert_after(iterator it, const Item& entry) {
if(it == end() || it == r_end() || it == r_begin()) {
rear_insert(entry);
}
dnode<Item> *tmp2 = new dnode<Item>;
tmp2 -> set_data(entry);
tmp2 -> set_next(it.current -> next());
tmp2 -> set_previous(it.current);
it.current -> next() -> set_previous(tmp2);
it.current -> set_next(tmp2);
}

template <class Item>
void dlist<Item>::remove(iterator spot){
dnode<Item> *rmptr = spot.current;
if(rmptr){
if(head == NULL)
std::cout << "Can't remove anything, list is empty.\n";
else if(rmptr == head && rmptr == tail){
delete rmptr;
head = tail = NULL;
}else if(rmptr == head){
dnode<Item> *new_head = head;
head = head->next();
delete new_head;
head->set_previous(NULL);
}else if(rmptr == tail){
dnode<Item> *new_tail = tail;
tail = tail->previous();
tail->set_next(NULL);
delete new_tail;
new_tail = NULL;
}else{
rmptr->previous()->set_next(rmptr->next());
rmptr->next()->set_previous(rmptr->previous());
delete rmptr;
rmptr = NULL;
}
}
}

template<class Item>
int dlist<Item>::size(){
int total = 0;
iterator it;
for(it = begin(); it != end(); ++it){
total++;
}
return total;
}

Here the other part of the program
dnode.h
#ifndef DNODE_H
#define DNODE_H
template<class Item>
class dnode{
public:
dnode(const Item& init_data = Item(), dnode* init_next = NULL, dnode* init_prev = NULL){
data_field = init_data;
next_field = init_next;
previous_field = init_prev;
}
Item& data(){return data_field;}
const Item& data() const{return data_field;}
const dnode* next() const{return next_field;}
dnode* next(){return next_field;}
const dnode* previous() const{return previous_field;}
dnode* previous(){return previous_field;}
void set_data(const Item& new_data){data_field = new_data;}
void set_next(dnode* new_link){next_field = new_link;}
void set_previous(dnode* new_link){previous_field = new_link;}
private:
Item data_field;
dnode* next_field;
dnode* previous_field;
};

main2.cc
#include <iostream>
#include <fstream>
#include "dlist.h"
#include "swatches.h"

using namespace std;

int main()
{
dlist<Swatch> swatches;
dlist<Swatch>::iterator it;
ifstream fin;
fin.open("swatches.txt");
if (fin.fail())
{
cout << "Could not open input file." << endl;
return 1;
}
Swatch tmp;
while (fin >> tmp)
{
int red = tmp.get_red();
int green = tmp.get_green();
int blue = tmp.get_blue();

if ( (green >= red) && (green >= blue) ) // green is dominant
{
swatches.rear_insert(tmp);
}
else if ( (red >= green) && (red>=blue) )
// red is dominant
{
swatches.front_insert(tmp);
}
else // blue is dominant
{
it = swatches.begin();
for(int i = 0;i < swatches.size()/2;i++)
++it; // loop moves iterator to the middle
if(swatches.size()%2 == 1){
swatches.insert_before(it,tmp);
}
else{
swatches.insert_after(it,tmp);
}
}
}
fin.close();

dlist<Swatch> copy(swatches); // make a copy

// remove the front, back, and centermost swatch from the copy
copy.front_remove();
copy.rear_remove();
it = copy.begin();
for(int i =0; i < copy.size()/2; ++i)
++it;
//if(copy.size()%2 ==1) ++it; // if list has a true middle
// step up into it
copy.remove(it);


// output the original list frontwards
for (dlist<Swatch>::iterator i=swatches.begin(); i != swatches.end(); ++i)
{
cout << *i << endl;
}

cout << endl << endl; // some space

// output the copy frontwards
for (dlist<Swatch>::iterator i=copy.begin(); i != copy.end(); ++i)
{
cout << *i << endl;
}

cout << endl << endl; // some space

// output the original backwards
for (dlist<Swatch>::iterator i=swatches.r_begin(); i != swatches.r_end(); --i)
{
cout << *i << endl;
}

cout << endl << endl; // some space

// destroy the original list by alternating between removal of first and
// last items. Print each item as it is removed
int counter=0;
while (swatches.size() > 0)
{
cout<<*swatches.begin()<<endl;
swatches.front_remove();
if(swatches.size() > 0){
cout<<*swatches.r_begin()<<endl;
swatches.rear_remove();
}
}

cout << endl << endl; // some space

// output the copy backwards
for (dlist<Swatch>::iterator i=copy.r_begin(); i != copy.r_end(); --i)
{
cout << *i << endl;
}

return 0;
}
swatches.cc
#include "swatches.h"
#include <iomanip>
#include <cstdlib>
#include <cstdio>
using namespace std;

// CONSTRUCTORS
Swatch::Swatch(){
color=0;
red=green=blue=0;
width=0;
length=0;
}
Swatch::Swatch(unsigned long n_color, int n_width, int n_length){
color=n_color;
red = n_color/TWO_COLOR;
blue = n_color%ONE_COLOR;
green = (n_color/ONE_COLOR)%ONE_COLOR;
width=n_width;
length=n_length;
}
// ACCESSOR FUNCTIONS
//This function returns the color as a number which is how it is
//actually stored
unsigned long Swatch::get_color(){
return color;
}
//This function returns a string version of the color number in standard
// RGB format
std::string Swatch::color_string(){
char a_c_string[10];
sprintf(a_c_string,"%x",color);
std::string tmp(a_c_string);
int leading = 6 - tmp.length();
if(leading <= 0) return tmp;
else{
std::string padding;
for(int i=0; i<leading; ++i){
padding += '0';
}
padding += tmp;
return padding;
}
}
//Return amount of red in swatch
unsigned long Swatch::get_red(){
return red;
}
//Return amount of green in a swatch
unsigned long Swatch::get_green(){
return green;
}
//Return amount of blue in a swatch
unsigned long Swatch::get_blue(){
return blue;
}
// Return width of the swatch
int Swatch::get_width(){
return width;
}
// Returns length of the swatch
int Swatch::get_length(){
return length;
}
// MODIFICATION FUNCTIONS
// Sets color to value of the argument
void Swatch::set_color(unsigned long n_color){
color = n_color;
red = n_color/TWO_COLOR;
blue = n_color%ONE_COLOR;
green = (n_color/ONE_COLOR)%ONE_COLOR;

}
// Sets color to value created when string is converted to a hex number
void Swatch::set_color(std::string n_color){
//The strol function will work with any base from 2 to 36.
//The 16 here denotes that we are converting from a
//hexadecimal representation.
color = strtol(n_color.c_str(), (char **)NULL, 16);
red = color/TWO_COLOR;
blue = color%ONE_COLOR;
green = (color/ONE_COLOR)%ONE_COLOR;

}
// Sets width to value of the argument
void Swatch::set_width(int n_width){
width=n_width;
}
// Sets length to value of argument
void Swatch::set_length(int n_length){
length=n_length;
}

std::ostream& operator <<(std::ostream& outs,const Swatch& sw){
char a_c_string[10];
sprintf(a_c_string,"%x",sw.color);
std::string tmp(a_c_string);
int leading = 6 - tmp.length();
if(leading <= 0) outs<<tmp;
else{
std::string padding;
for(int i=0; i<leading; ++i){
padding += '0';
}
padding += tmp;
outs<<padding;
}
outs<<" "<<sw.width<<" "<<sw.length;
return outs;
}
std::istream& operator >>(std::istream& ins, Swatch& sw){

ins>>hex>>sw.color>>dec>>sw.width>>sw.length;
sw.red = sw.color/sw.TWO_COLOR;
sw.blue = sw.color%sw.ONE_COLOR;
sw.green = (sw.color/sw.ONE_COLOR)%sw.ONE_COLOR;

return ins;
}
swatches.h
/**************************************************************************
The header file for a class called Swatches, which stores
the color and dimensions of a color swatch. The color is stored
as a single hexadecimal number which is actually a composite of
three hex numbers representing the intensity of Red, Green and
Blue respecitively. The dimensions are intergers for width and
height which can be interpreted into whatever unit is relevant
for the application.
A set of accessor and modification functions are provided for
for the private variables, and the color is available as either
a number a string.
************************************************************************/
#include <iostream>
#include <iomanip>
#include <string>
#ifndef SWATCH_H
#define SWATCH_H
class Swatch{
public:
static const unsigned long ONE_COLOR = 256;
static const unsigned long TWO_COLOR = 256*256;
// CONSTRUCTORS
Swatch();
Swatch(unsigned long n_color, int n_width, int n_height);
// ACCESSOR FUNCTIONS
unsigned long get_color();
std::string color_string();
unsigned long get_red();
unsigned long get_green();
unsigned long get_blue();
int get_width();
int get_length();
// MODIFICATION FUNCTIONS
void set_color(unsigned long n_color);
void set_color(std::string n_color);
void set_width(int n_width);
void set_length(int n_length);
// FRIENDS
friend std::ostream& operator <<(std::ostream& outs, const Swatch& sw);
friend std::istream& operator >>(std::istream& ins, Swatch& sw);
private:
unsigned long color;
unsigned long red, green, blue;
int width;
int length;
};
#endif
not going to bother to replicate your file structure, upload your project to github or similar or provide a .zip

also, provide the error messages verbatim
After rearranging the code to get everything in the right order in one file, I got it to compile with the following changes:
1
2
3
4
5
6
7
// iterator.h
#ifndef ITERATOR_H
#define ITERATOR_H
// #include "dnode.h"
#include <iterator>
template<class Item>
class dlist;


1
2
3
4
5
6
7
// dlist.template
#include <iostream>
template <class Item>
dlist<Item>::dlist(){
    head = nullptr;
    tail = nullptr;
}


1
2
3
4
5
6
7
8
9
10
11
12
template <class Item>
void dlist<Item>::front_remove() {
    if(head == nullptr) {
        return;
    }
    if(head == tail) {
        return;
    }
    head = head -> next();
    head -> set_previous(nullptr);
    return;
}


1
2
3
std::string Swatch::color_string(){
    char a_c_string[10];
    sprintf(a_c_string,"%lx",color);


1
2
3
std::ostream& operator <<(std::ostream& outs,const Swatch& sw){
    char a_c_string[10];
    sprintf(a_c_string,"%lx",sw.color);


rbegin() and rend() need to return a reverse iterator. The reverse iterator's ++ operator goes to the previous node and operator-- goes to the next.

I'm not certain, but I think you can derive const_iterator from iterator.

If you add a private clear() method to dlist then you can simplify some code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    ~dlist() { clear(); }
...
template<class Item>
dlist<Item>::dlist(const dlist& source){
    head = nullptr;
    tail = nullptr;
    *this = source;
}

template<class Item>
dlist<Item>::clear(){
    dnode<Item>* cursor = head;
    dnode<Item>* remove_ptr;
    while(cursor != nullptr){
        remove_ptr = cursor;
        cursor = cursor -> next();
        delete remove_ptr;
    }
}

template<class Item>
void dlist<Item>::operator =(const dlist& source){
    if(this == &source){
        return;
    }
    clear();
    dnode<Item>* sourceCursor = source.head;
    while(sourceCursor -> next() != nullptr){
        rear_insert(sourceCursor -> data());
        sourceCursor = sourceCursor -> next();
    }
}


front_remove() and rear_remove() don't do the right thing when the list has one item. Then need to set head and tail to nullptr. Also, you need to delete the removed node to avoid leaking memory.
Topic archived. No new replies allowed.