C++ sorting with the STL

Since I’m doing a lot of C++ these days and working a lot with the STL, I want to jot down some things I’ve had to painfully recall about sorting:

  1. The std::sort function really only works with vector
  2. If you want to sort a set of pointers, you’ll need to create a comparator function or object and use it as a type parameter (uglier than hell)
  3. If you want to sort a list, you MUST call the sort method on the list

#2 looks like this and really sucks to look at:

set<string*,StringPointerComparator> myset;

And if you want to pass that thing around, you have to either pass it like that (nasty) or typedef it. Since I hate all typedefs, macrodefs, etc, I generally pass that nasty full type around.

Android review and iPhone comparison

Here’s a quick run-down and comparison between the G1 vs. iPhone and Andriod vs. OS X mobile. This is based on side-by-side evaluation with both phones.

The phones

Keyboard

The winner: G1

The G1’s keyboard is awesome. I like it so much better than the iPhones mainly because I can see the whole screen while typing, but also because it has numbers and I don’t have to hit something to switch between numbers and letters. I’m a keyboard freak, so hands down the G1 wins.

Screen

The winner: iPhone

I think this is close to a tie, but the iPhone screen is bigger. The resolution is the same for both phones, which means that the G1 can display as much information as the iPhone, but it is smaller.

Battery

The winner: iPhone

The iPhone’s battery is 2-3 times better than the G1’s. I’ve heard word of T-Mobile shipping out batteries that add 30% more life, but even still, I play around with my G1 very little and it still needs to be charged daily. My iPhone needs charging every 2-3 days with the same use.

Form factor/Design

The winner: iPhone

This isn’t much of a battle. The iPhone is sleek, light and really nice to look at. The G1 is thicker, heavier and an eye-sore comparatively. However, I can understand the extra size given the full keyboard. One thing the G1 does nicely is it figured out the exact size required for anyone to hold it in one hand and use any feature of the phone. This is the only thing nice about the G1’s size and shape.

Buttons

The winner: G1

I like the buttons and track ball with the G1. The iPhone is sometimes a bit cumbersome to use given that everything is on the screen. Sometimes it is nice to just hit a button.

Accelerometer

The winner: iPhone

The iPhone has a really good accelerometer that seems to be level and responsive. The G1’s is a little rough around the edges and you can’t calibrate it or tweak it at all.

The operating systems and software

Structure

The winner: Android

Android has a lot of advanced features that are pretty nice overall. Each application has a menu, which is great for adding loads of functionality. There are keyboard shortcuts in applications which makes using features fast. Android has intents which are nice. It also allows applications to leverage other applications and common libraries. By far, Android wins when it comes to a modern platform.

At the same time though, Android has many bugs and issues that also make it difficult to actually use.

Homepage/Application Chooser

The winner: Tie

The iPhone home page doesn’t have the cool backgrounds or the lame analog clock or the drag and drop application display, but it is simple, orderable (you can move apps around), and looks really nice. Androids has a cool homepage that allows ordering and an alphabetized app chooser. So, they are different, but equally as usable and cool.

Androids icons definitely have that Linux look, which I grew tired of a decade ago while iPhone’s icons are sleek and nice and I haven’t gotten tired of yet (only 1 year as a Mac user). It seems like Apple is more in tune with style and each OS release keeps things fresh. We’ll see how 10.6 goes. Linux on the other hand just plain sucks the life out of you.

Voicemail

The winner: OS X

T-Mobile and Android’s voicemail integration is horrible. It is exactly the same as every other phone for T-Mobile because you have to dial into voicemail and manage it via T-Mobile’s phone system. There is an 3rd party application that adds visual voicemail to Android phones, but it is in beta and it is a hack that appears to actually dial up your voicemail and record the voicemails to an MP3. I’m not positive on that, but this is what it seems like. Regardless of how this application works, it is a 3rd party application and T-Mobile and Android should really be offering a tightly integrated feature of the phone.

The iPhone completely integrates with AT&T’s voicemail such that you can view all your voicemails on the phone, listen to them on the phone, and even setup and switch your voicemail greeting on the phone.

Calendar

The winner: Android

The Android Google calendar integration is great. However, it doesn’t support multiple calendars very well (you can only view calendars in the associated GMail account and not other GMail accounts or an Exchange calendar) and that’s a real pain point for most. Since I use a single calendar for everything, I don’t mind too much. On the other hand, if you have a Mac and only use Calendar.app, integration with the iPhone is great. This combined with Mobile Me would be ideal for real-time updates and syncing. For now though, Android wins in this department.

I’d imagine that Google will soon offer syncing with the iPhone as it does with the BlackBerry. If not, NuevaSync will work once it is finished and out of Beta.

Likewise, I would put money that Android will start supporting multiple calendars shortly.

Maps

The winner: OS X

Multi-touch, double-click and good integration/features wins this battle. Since you are already touching the screen to move around, multi-touch is nice. The G1’s map interface is nice and it does allow single handed use, but iPhone’s bigger screen and multi-touch prevail in this category.

Email

The winner: OS X

First, the GMail application really should be combined with the Email application. The fact that they are separate is really painful and annoying. Email should just be email like the iPhone does. Second, Android’s email application is one of the worst applications ever written. Here are a few of the pain points:

  • Can’t view first few lines of emails in the inbox view
  • The folder and email view are combined making for a very cluttered interface
  • Email fails regularly even when connected to a WiFi
  • Deleting emails does nothing for GMail accounts via IMAP.
  • Can’t setup what happens on delete for IMAP accounts. For example, with GMail IMAP it should move the message to [Gmail]/Trash

The worst thing is probably that the Email application doesn’t instantly work with GMail IMAP accounts. This should just work considering that the entire platform and stock applications are written by Google. I mean come on guys, take a cue from Apple and just make stuff work, especially with your own systems. Plus, Email constantly crashes and has so many issues that it is rendered useless in most situations.

The iPhone email isn’t perfect, but it handles all of these things much better and also makes setting up GMail accounts a snap.

Document Viewer

The winner: OS X

The iPhone has a built in PDF viewer that works really well. It also displays Word documents and other formats decently well. In gets a little bit freaked out by complex Word documents in the new DOCX format, but otherwise it is great. It also allows you to zoom in and out using multi-touch and double-click.

The G1 looks like it uses Google Docs online viewer or some type of hacky internal viewer. Not really sure about which one, but it does a very poor job of displaying documents and files, including PDF (I mean really? PDF? It should perfectly display all PDFs). Images are also displayed poorly and some don’t render correctly, such as JPGs. Plus, no zoom (ouch!).

Apps

The winner: OS X

This is based purely on the most fundamental of all applications, solitaire. There are a number of choices on both phones, but overall the solitaire on the iPhone is much nicely in terms of design, features, etc.

App stores

The winner: OS X

Apple’s store has a much cleaner interface and includes pictures, better details, better commenting system and more interactivity. The Android market looks pretty shabby comparatively.

Accelerometer/Orientation

The winner: OS X

The iPhone uses the accelerometer all over the place and it does it really well. Orientation of the phone is really helpful in most applications as it makes the phone easy to use.

Android’s support for orientation and the G1’s accelerometer is just garbage. Even the browser requires 3-4 clicks before you can change the orientation without opening the keyboard. I mean come on guys, just use the tools you have and make people’s lives simple. Plus, HTC seems like they added a pretty low end accelerometer and it isn’t calibrated very well. Plus, you can’t really calibrate it.

Development

The winner: Android

I’ve talked at length about how I think Objective-C is really keeping Apple back, but here’s another way to look at it. If you take the years that technologies were introduced and line them up so that you have language, RAM, and CPU (based on speed), here are the results:

iPhone: 1986 1989 2000
G1: 1995 1996 2000

I definitely like the G1 and Android numbers much better.

The Final Score

If we add all these up, it looks like this:

G1/Android: 5

iPhone/OS X: 11

The final winner? iPhone/OS X

Getting the current system time in milliseconds with C++

After doing quite a bit of C++ recently, I thought I would post my method for getting the current system time in milliseconds in C++ for both Mac OS X and Windows. The Mac version might translate to other Unix platforms, but you’ll have to check the docs or man pages.

Mac OS X

#include <sys/time.h>
timeval time;
gettimeofday(&time, NULL);
long millis = (time.tv_sec * 1000) + (time.tv_usec / 1000);

This actually returns a struct that has microsecond precision.

Windows

#include "windows.h"
SYSTEMTIME time;
GetSystemTime(&time);
WORD millis = (time.wSeconds * 1000) + time.wMilliseconds;

This code gives the milliseconds within the last minute. If you want milliseconds since epoch or some other fixed point in time it will require a bit more math on the SYSTEMTIME struct.

Writing a marker interface in C++

Just figured this out and it caused me about 3 hours of pain, so I figured I’d post it in case I need to do it again.

class Base {
public:
  virtual ~Base() {};
};

class Derived : public Base {
private:
  set someSet;
public:
  virtual ~Derived() {};
  set getSomeSet() { return someSet; };
};

You might find this necessary if you have some code like this:

class Base {
};

class Derived : public Base {
private:
  set someSet;
public:
  set getSomeSet() { return someSet; };
}

void main() {
  map objects;
  Base base;
  if (objects.find("foo") != objects.end()) {
    base = objects.find("foo")->second; // This is actually a Derived
  }
}

void useBase(Base& base) {
  Derived* derived = (Derived*) &base;
  set someSet = derived->getSomeSet();
  ...
}

This code will toss strange errors such as EXC_BAD_ACCESS and other kernel alarms. I’m not certain way this happens, but I think it is because Derived in the second example isn’t actually an instance of Base since the compiler doesn’t understand that Base is polymorphic. If you try to apply a dynamic_cast operator rather than the pointer cast (as used in example #2) the compiler will complain. What is probably happening is that at runtime the memory for the Derived is not correct because it was cast to a Base, and the kernel freaks out when you attempt to access something in Derived.

Another classic example of C++’s power causing major issues at runtime. These types of problems are not only tricky to figure out, but really only make sense to the kernel and compiler and aren’t obvious from a OO perspective.

Most modern OO languages would have absolutely no issues with the above code, and all dynamic OO languages wouldn’t even need the casts at all and would duck type the invocations via dynamic method invocation.

Visual Studio sucks, NetBeans is coming along, IJ is slipping

I’ve been working on a decent sized C++ project recently and since the application will be used on a Windows server, I wanted to stay close to that platform. I fired up the latest Visual Studio 2008 version hot off the presses with my MSDN subscription and boy is that thing a piece of junk. It is like working in the stone ages. I mean writing C++ is bad enough and then I have to battle with the worse IDE imaginable?

I think not.

So, I grabbed Eclipse and NetBeans and fired both up. Eclipse, is a beast and I wanted to avoid it at all costs if possible. I’ve never liked Eclipse, no matter the version, and they haven’t improved the issues enough for me to really use it for Java development. However, I found the Eclipse C++ integration decent, but still pretty rough. The Eclipse interface is so clunky that it makes it hard to be productive.

Next I grabbed the latest NetBeans (6.5) and fired it up. I have to say that it started pretty darn fast for a Java IDE. It also has a really decent layout and configuration system. The C++ support, although experimental for on the fly error highlighting, is impressive. After tweaking my colors and battling through keymappings I’m actually productive. NetBeans lacks a number of editor features that are required these days, including multiple clipboards, duplicate lines (has this but no keyboard shortcut), join lines, etc. Besides this problems, I like it.

On the flip side, IntelliJ is still great. 8.0 is just out and it adds a number of new great features and more language support. However, I think that IJ is probably getting close to needing a good chunk rewritten. The configuration system is becoming clunky, the projects difficult to manage, and most aspects of the IDE are beginning to fail.

The speed is horrible, the memory consumption off the charts and the productivity increases that we all used IntelliJ for are is slowly being integrated into the other IDEs. I think IJ is still the best, but their margin is slowing being reduced. If the folks over at JetBrains want to stay competitive they are gonna need more speed, more productivity, more simplicity and more power. These things are all hard to get at the same time, but I’m confident that they will find at way.

For now, I’m gonna give NetBeans the full shake-down, log a ton of bugs and wait for 7.0 to see how many they fix. I’d say my list is pretty short at this point and I could envision a full switch to NetBeans with 5-10 enhancements if IntelliJ continues its slow decline.

Only time will tell.

Setting up GoogleTest in VS 2008

I’m not a huge C++ developer nor a VS wizard, so I thought I would write down how I got GoogleTest setup in a C++ project I’m using VS 2008 for.

  1. Download it
  2. Add it as an existing project to your solution by right clicking on the “Solution ‘your-project'” part of the Solution Explorer
  3. Compile it (if you want)
  4. Right click your project and open the Properties
  5. Click on ‘Common Properties -> Frameworks and References’
  6. Add a Reference to the GoogleTest project
  7. Click on ‘Configuration Properties-> C++’
  8. Under the ‘Additional Include Directories’ add the a new directory that points to the include directory inside the GoogleTest distribution
  9. Click on ‘Configuration Properties -> C++ -> Code Generation’ and change all of the projects to ‘Multi-threaded Debug (/MTd)’

Another thing I realized is that it is probably best to create a separate project for the tests within your solution. I created a Win32 Console Application project in my solution and followed the above steps for that project. I also then needed to add a reference to the project I am testing within my test-project. (Slightly annoying, cumbersome and verbose).

git completion in zsh

Just figured out how to get git tab completion working in zsh on a Mac. Turns out that the completion scripts use a bunch of extra git commands such as git-ls-files. These commands need to be in your path for the completion to work. If you installed git using the OS X installer, you need to add this directory to your path:

/usr/local/git/libexec/git-core

Savant command-line tool and plugins are almost ready

Been working this week on Savant 2.0. My first thought when I started writing Savant 2.0 was to write a complete replacement for both Maven and Ant that used Groovy and allowed for both a plugin model as well as a simple build script approach. This was too much to bite off when you consider all of the other changes to the dependency management part of Savant we made for 2.0.

For JCatapult we created a set of Ant build scripts that could be plugged into any build file and reused. It looks like this:

<project name="foo">
  <import file="${jcatapult.home}/ant/plugins/java/1.0/compile.xml"/>
  ...
</project>

This model meant that the build.xml file had nothing but import statements in it. It made life much simpler when working with numerous projects that were virtually the same.

The part I didn’t like was that I loved this model. I liked it so much I started using them for everything including Java.net Commons, Savant and internal Inversoft projects. This meant that I had a dependency on JCatapult, which for all intents and purposes is a webapp platform. This seemed strange.

I started thinking about moving these files over to Savant. At first I just figured I would migrate the entire set of Ant plugins from JCatapult over and be done. However, once I moved them over it meant that I would need to start pulling in plugins for a variety of projects. Some would come from Savant and others might come from JCatapult or elsewhere. This was due to the fact that some of the JCatapult plugins were very specific to JCatapult projects. I could force developers to download each plugin they needed from various places, install them in a specific directory and then update their build files before they could build any projects. It all started to look very clunky.

Then I remembered (duh!) that Savant is a dependency management tool and it can find, version and download ANYTHING. Why not apply this pattern to Ant build files in the form of plugins?

So, I did just that!

It works great. The way it works is that I wrote a simple Java class that figures everything out and then generates an ant build file. The full process looks like this:

  1. New script called svnt invokes a Savant class
  2. This new class parses the project.xml file, which defines the plugins the project will be using
  3. It downloads any missing plugins to the Savant local cache
  4. Since the plugins are JAR files, it explodes the JAR file to ~/.savant/plugins under a specific directory just for that plugin
  5. This class then generates a temporary build.xml file that imports all of the plugins the project needs
  6. It outputs the location of this temporary build.xml file
  7. The svnt script executes Ant passing it the location of this build file (i.e. ant -f /tmp/tmpbuild.xml)

And that’s it. Nothing fancy, just a little sugar on top of Ant to provide downloading of plugins and build files automatically.

The last part of this exercise is to write a bunch of plugins. Since these are just Ant build scripts and we’ve all created hundreds of those so it should be a simple matter of tweaking them ever so slightly to work when imported.

My new projects don’t have a build.xml file (but if they do it is imported to add additional targets or override targets from the plugins) and just contain the Savant project.xml file. This file now defines plugins and it looks like this:

<project name="foo" group="inversoft.org" version="1.0">
  <plugin group="plugins.savant.inversoft.org" name="clean" version="1.0"/>
  <plugin group="plugins.savant.inversoft.org" name="java" version="1.0"/>
  <plugin group="plugins.savant.inversoft.org" name="junit" version="1.0"/>
  <plugin group="plugins.savant.inversoft.org" name="release-svn" version="1.0"/>
  ...
</project>

That’s it. If anyone is interested in trying it out, I should have a release available in the next few days along with some documentation for the 5-10 plugins I will have ready. If you want to try and build all this by hand right now, you’ll need to install JCatapult since Savant uses that until it can be self building.