A WPF/MVVM Countdown Timer on GitHub

I have started working on a simple countdown timer that is written in C#, XAML, and uses the ‘MVVM’ pattern. The v0.1 code is checked into GitHub, where you can download it, fork it, and play around (yes, I’m using semantic versioning). The purpose of this is to refresh my memory about XAML, and C#, and also to play around with CodeRush and Refactor! that make writing C# much easier.

The version 0.1 features are:

  • Countdown fixed and starts at 25 minutes.
  • Plays a start/stop sound using the SystemSounds.
  • Settings not implemented.
  • The window stays top-most.
  • The Windows 7 taskbar icon shows the countdown progress.

This will go up onto CodeProject, I expect, once I’ve finished it off. The icon, if you are interested, was created using Icon Workshop which, at the time of writing, has money off.

C++ 11 Part 1: New keywords and lambdas

I’ve start looking at the new C++11 standard and the best way to do it is to try an example and then use the new language features.

Starting with the simplest example, let’s just use a vector and a for loop:

using namespace std;

vector<int> v;
//  can't do this yet, in the dev preview:
//  vector<int> v = { 1, 2, 3 };

v.push_back(1);
v.push_back(2);

for(std::vector<int>::const_iterator it = v.begin(), e = v.end() ; it != e ; ++it)
{
	wcout << L"value = " << *it << endl;
}

The first thing to note here is that the iterator variable ‘it’ is, obviously, non-const: in other words we can manipulate the value of ‘it’ inside the for-loop scope.

Whilst still in the C++99, we know in this case that we’re not interested in changing the value of ‘it’, so we could use the ‘std::for_each’ construct. Unfortunately, in ‘old-style’ C++, writing the loop body for ‘std::for_each’ isn’t exactly concise or easy on the eye. This brings us nicely to the first new C++11 language feature, lambda functions.

Diving straight in, and being explicit in the syntax, we can re-write the loop above as:

using namespace std;

//  Old + new styles
for_each(v.begin(), v.end(), [=](int i) -> void {
	wcout << L"value = " << i << endl;
});

What is going on here? The syntax of lambda functions is a little strange the first time you see it, but is quite simple, Microsoft’s web page has a detailed description (http://msdn.microsoft.com/en-us/library/dd293603.aspx), but it is essentially as follows.

The ‘[]‘ is lambda introducer or capture clause, and can take one of the following values: [=], [&], [], [list_of_vars]. With a little bit of thought, and thinking back to existing C++ syntax the capture clause describes how the lambda function can access any variables that are within the scope in which it was declared (see the MS page for the *exact* description). The [=] means that any variable in the parent scope are accessible in the lambda scope by value. The [&] therefore means that parent scope variables are accessible by value, i.e. you can modify the variable in the parent scope from within the lambda. The ‘[]‘ defaults to the safe option, pass by value.

The last option for the capture-clause is to pass a list of parent scope variables prefixed with the preferred capture type, so that you can mix pass by value and pass by reference.

The second part of the lambda expression is simply the lambda parameter declaration list, in our case, the loop variable.

The last part of the lambda expression ‘-> void’ is the return type. Quoting directly from the MS page:

You can omit the return type part of a lambda expression if the lambda body contains a single return statement or the lambda expression does not return a value. If the lambda body consists of a single return statement, the compiler deduces the return type from the type of the return expression. Otherwise the compiler deduces the return type to be void.

So using lambda functions, we can move the loop body into a lambda function and succicntly write our for-loop as:

for_each(v.begin(), v.end(), [=](int i) -> void {
	wcout << L"value = " << i << endl;
});

What is the advantage in this? For one thing, the loop variable is now removed and the iterated value is now passed as its own type, by value. So we have what is essentially a ‘read-only’ loop, which is what std::for_each is for. If you want to modify things, use std::transform. This syntax can be optimised by a compiler, and in fact in tests (http://channel9.msdn.com/Events/BUILD/BUILD2011/TOOL-835T) std::for_each can be compiled into faster code than the raw for-loop.

However we can do better still. The std::for_each loop takes a starting iterator and an end iterator, and requires that the iterator can be moved using the prefix operator++(). The lessons learnt in C++ over the last decade or so is that non-member functions improve encapsulation, e.g. Myers(2000) http://drdobbs.com/184401197, Sutter(2004) http://www.gotw.ca/gotw/084.htm

It would therefore be really useful if we could pass the container type into a non-member function that returns the begin and end iterators, and which we can leverage with our own containers. In the C++99 standard, there was not an easy way of writing this. In C++11 with the new language extensions, it becomes trivial:

//  Use std::begin and std::end!
for_each(begin(v), end(v), [=](int i) -> void {
	wcout << L"value = " << i << endl;
});

The definition of begin and end are as follows:

template<class TCONTAINER>
auto inline begin(TCONTAINER& container) -> decltype(container.begin())
{
	return (container.begin());
}

template<class TCONTAINER>
auto inline begin(TCONTAINER const & container) -> decltype(container.begin())
{
	return (container.begin());
}

template<class TCONTAINER>
auto inline end(TCONTAINER& container) -> decltype(container.end())
{
	return (container.end());
}

template<class TCONTAINER>
auto inline end(TCONTAINER const & container) -> decltype(container.end())
{
	return (container.end());
}

We now see two new keywords. The first of which is possibly the most useful addition to C++11, the ‘auto’ keyword. If the compiler knows from the right-hand side what the return type is, why do you need to write it by hand? And worse, if you make a typo, the compiler tells you, as an error, what you should have typed!

Returning to the definitions of begin and end, we can see from the code above, that we obviously need two declarations for each: the first for non-const containers (if we use std::transform, for instance), and the second for const containers.

Firstly, we return an ‘auto’, where this is either the const_iterator, or non-const iterator as appropriate. We tell the compiler that we would *like* to inline this, and lastly we see a new keyword in the C++11 standard: ‘decltype’.

Quoting directly from http://en.wikipedia.org/wiki/Decltype

In the C++ programming language, decltype is an operator for querying the type of an expression. It was introduced in the current version of the C++ standard, C++11. Its primary intended use is in generic programming, where it is often difficult, or even impossible, to express types that depend on template parameters.

If you omit the ‘->decltype’ declaration, you see exactly what the problem is, and how the wikipedia quote is uncannily accurate: the compiler cannot deduce the return type from the function body.

In fact, you will see this compiler error on Windows: http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(C3551);k(vs.output)&rd=true.

So you can see how just taking a simple for loop can be improved significantly, with no loss of readability, and with potential performance improvements based on the new C++11 standard.

I will confidently predict that a new ‘Essential STL/C++’ will have two items: ‘prefer using keyword auto’, and ‘prefer non-member functions std::begin() and std::end() to the member function equivalents’.

Using the new C++11 standard will make for significantly less error prone code, either by typing errors (using auto!), or resource leakage (use std::shared_ptr, or std::unique_ptr). Just by delving into a simple example and following through the new standard library headers you can see how a lot of the new language features are already being used, and how you can apply them yourself.