Wednesday, September 12, 2012

Singly linked list in C++

These days I needed a clean implementation of a singly linked list in C++. I found some ones around, but none of them was functional and clean and the same time. So I wrote my own, using nothing but pure C++ with templates, and here I’m publishing the full implementation.

First, the header. I chose to put the node class nested into the linked list class, because this approach allows me to have another node class which can belong to another kind of structure, if I need to. There are a couple of methods beyond the basics, I needed them to have a functional data structure that worked for me.
template<typename T> class LinkedList {
public:
	class Node {
	public:
		      Node()                     : _next(NULL) { }
		      Node(const T& data)        : _data(data), _next(NULL) { }
		Node* insertAfter();
		Node* insertAfter(const T& data) { return &(*this->insertAfter() = data); }
		Node* removeAfter();
		T&    data()                     { return _data; }
		Node& operator=(const T& data)   { this->_data = data; return *this; }
		Node* next(int howMany=1);
		int   countAfter() const;
	private:
		T     _data;
		Node *_next;
	friend class LinkedList;
	};

public:
	      LinkedList()          : _first(NULL) { }
	     ~LinkedList();
	int   count() const         { return !this->_first ? 0 : this->_first->countAfter() + 1; }
	Node* operator[](int index) { return !this->_first ? NULL : this->_first->next(index); }
	Node* append();
	Node* append(const T& data) { return &(*this->append() = data); }
	void  removeFirst();
	Node* insertFirst();
	Node* insertFirst(const T& data) { return &(*this->insertFirst() = data); }
private:
	Node *_first;
};
The node class implementation:
template<typename T> typename LinkedList<T>::Node* LinkedList<T>::Node::insertAfter() {
	Node *tmp = new Node;
	tmp->_next = this->_next; // move our next ahead
	this->_next = tmp; // new is our next now
	return this->_next; // return newly inserted node
}

template<typename T> typename LinkedList<T>::Node* LinkedList<T>::Node::removeAfter() {
	if(this->_next) {
		Node *nodebye = this->_next;
		if(this->_next->_next) this->_next = this->_next->_next;
		delete nodebye;
	}
	return this; // return itself
}

template<typename T> typename LinkedList<T>::Node* LinkedList<T>::Node::next(int howMany) {
	Node *ret = this;
	for(int i = 0; i < howMany; ++i) {
		ret = ret->_next;
		if(!ret) break;
	}
	return ret; // howMany=0 returns itself
}

template<typename T> int LinkedList<T>::Node::countAfter() const {
	int ret = NULL;
	Node *no = this->_next;
	while(no) { no = no->_next; ++ret; }
	return ret; // how many nodes exist after us
}
And the linked list implementation:
template<typename T> LinkedList<T>::~LinkedList() {
	Node *node = this->_first;
	while(node) {
		Node *tmpNode = node->next();
		delete node;
		node = tmpNode;
	}
}

template<typename T> typename LinkedList<T>::Node* LinkedList<T>::append() {
	if(!this->_first)
		return ( this->_first = new Node ); // return first and only
	Node *node = this->_first;
	while(node->next()) node = node->next();
	return node->insertAfter(); // return newly inserted node
}

template<typename T> void LinkedList<T>::removeFirst() {
	Node *nodebye = this->_first;
	if(this->_first->next()) this->_first = this->_first->next();
	delete nodebye;
}

template<typename T> typename LinkedList<T>::Node* LinkedList<T>::insertFirst() {
	Node *newly = new Node;
	if(this->_first) newly->_next = this->_first; // only case of FRIEND use
	return this->_first = newly; // return newly inserted node
}
The machinery is pretty straightforward to use, I believe. You just need to declare one instance of the LinkedList class, and all the node manipulation will be done through it and the node pointers returned by the methods, which allows operations on the nodes themselves. You’ll never have to alloc/dealloc any node. Here’s an example, with some operations and then printing all elements:
#include <stdio.h>
int main() {
	LinkedList<int> list;
	list.append(33)->insertAfter(80);
	list.insertFirst(4)->removeAfter();

	LinkedList<int>::Node *node = list[0];
	while(node) {
		printf("%d\n", node->data()); // print each value
		node = node->next();
	}
	return 0;
}

Friday, July 27, 2012

Bringing back the favicon on Firefox 14

On its way to chromify Firefox, Mozilla removed the favicon from the URL bar on Firefox 14. I agree with their reason, saying that one could use the favicon to emulate the secure connection padlock, but in my opinion it should be disabled by default, being optional to bring it back. Not all Firefox users are newbies or morons.

Fortunately, a guy called jooliaan published an addon to bring the favicon back to the URL bar, and it works just like it should. The addon is called Favicon Restorer, and I highly recommend it.

The way it goes, Mozilla is killing Firefox version after version. We love Firefox for what it is; if we wanted something that looks like Chrome, we would just use Chrome. Wake up, Mozilla.

Thursday, July 5, 2012

A trick to auto hide Chrome download bar

If you make a quick search, you’ll find how many people are annoyed by Chrome’s download bar, which doesn’t hide itself automatically, and requires you to manually hit the “X” button. There is no way to automate this through the extensions API, nor the browser gives you any option.

However, I found a simple trick to close the download bar, and it’s so simple that it’s hard to imagine how no one had this idea before – I didn’t see it anywhere, by the way. Not exactly automatic, but it’s better than click that “X” button.

Here’s how: you’ll have to use two shortcut keystrokes. The first one is Ctrl+J, which opens the download tab. The silver bullet is that this download tab displays the download progress, thus automatically closing the download bar. Then, once you have the download tab opened, just hit Ctrl+W, which closes the current tab, and it’s done.

So, by hitting Ctrl+J and Ctrl+W in succession, you’ll be free from clicking the “X” button on the download bar.

Sunday, June 17, 2012

Linus Torvalds is my hero

I’m a big fan of Linus Torvalds, not only for what he did with Linux, but also for his figure, particularly his lack of tenderness. His thoughts about C++ are legendary already, and that impressed me to the point that today I’m writing mostly ANSI C code.

Now, during a talk at Aalto University in Finland, he voiced about the lack of support Nvidia has given Linux, and his zero-diplomacy balls have striked loudly again. For my personal delight, I must admit, since I had a problem with a Nvidia video card driver on my Ubuntu just a couple months ago, to which I simply shrugged after days of pain.

Listen to the man:


And Nvidia, fuck you!

Saturday, June 2, 2012

Nu Sans programming font

I’ve just discovered out the Nu Sans monospace font on a Reddit discussion regarding the Mensch font – which is also a good font. However, Nu Sans caught my attention when I tested it on Visual Studio 2008 because it has that Lucida Console feel: a large font within small line height. And this is good for programming, because you can fit more lines on the screen. The TTF of the link above is a demo without accents, but it’s pretty usable.

So I just found a new font for my programming font collection.

Sunday, May 13, 2012

FLAC and LAME frontend

I use the FLAC and LAME command line tools, and I’ve tried many FLAC and LAME frontends. And I disliked all them. One day I decided to write my own, with a parallel multithreaded handling of the files, so all the files are converted at once, taking advantage of multicore CPUs.

Today I’ve just published it as open source on GitHub. It’s pure C and Win32. I hope it can be useful to someone – not only the program itself, but also my C programming techniques. It can be found at rodrigocfd/flac-lame-gui.

Saturday, May 12, 2012

My first program on GitHub

That’s a simple C Win32 program to shrink down padding bytes from ID3v2 tags on MP3 files. Maybe the most important thing, I think it showcases my style of C programming, and I’m glad to share it with the world. I hope it can be useful to someone someday.

It can be browsed at rodrigocfd/id3-padding-remover.