Pages

Exceptions

PL/SQL supports an error handling management based on a throw/catch exception system similar to the one commonly used by modern programming languages.

Here is how it looks an anonymous block that throws and then catch a system exception:

begin
raise value_error;
exception
when value_error then
dbms_output.put_line('A system exception has been raised');
end;

PL/SQL has a lot of predefined exceptions, as VALUE_ERROR that it is used above. You should expect it to be raised by a function when trying to use a value of the wrong type in a specific context.

As users, we could create our exceptions, and then raise and catch them, exactely as the system ones:

declare
my_ex exception;
begin
raise my_ex;
exception
when my_ex then
dbms_output.put_line('my_ex exception has been raised');
end;

In these two examples we have seen how to catch exception matching a specific type, but we can also use the catch-all clause WHEN OTHERS:

declare
my_ex exception;
begin
raise my_ex;
exception
when others then
dbms_output.put_line('An exception has been raised');
end;

Usually exception are raised by low level functions, and in everyday code is more common to catch exception that raise them:

declare
l_value integer;
begin
l_value := 3 / 0;
dbms_output.put_line('Hello');
exception
when zero_divide then
dbms_output.put_line('Divide by zero');
end;

In this example we try do divide by zero, this leads to a ZERO_DIVIDE system exception, so the current block execution is interrupted (the 'Hello' message is not printed) and the control is passed to the catch block (marked EXCEPTION). All the WHEN clauses are checked sequentially till a matching one is found, and the relative code is executed. If no WHEN OTHERS is specified, and the exception is not intercepted before the end of the block, it is propagated to the caller of the current block.

Here is another example of system exception catching:

declare
l_int integer;
l_str varchar2(20) := 'hello';
begin
l_int := l_str;
dbms_output.put_line('Hello');
exception
when value_error then
dbms_output.put_line('Value error');
end;

We could raise an exception also using a numeric code, that should be in the interval [-20000, -20999] using the function raise_application_error():

declare
my_exc_code integer := -20000;
begin
raise_application_error(my_exc_code, 'Something bad happened');
exception
when others then
dbms_output.put_line(sqlcode);
dbms_output.put_line(sqlerrm);
dbms_output.put_line(dbms_utility.format_error_backtrace);
dbms_output.put_line(dbms_utility.format_call_stack);
end;

In tis catch clause we could see a bunch of useful values to check for getting more information on the current exception.
SQLCODE gives us the code associated - in this case -20000;
SQLERRM contains the first 512 bytes of the associated error message;
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE includes information on where the exception has been raised;
DBMS_UTILITY.FORMAT_CALL_STACK gives us details on the exception stack trace.

More on PL/SQL exception handling in chapter 6 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

Cursor FOR loop

Besides the "classic" FOR loop, PL/SQL makes available also a "cursor" FOR loop. The syntax very similar:

FOR record IN (...)
LOOP
(...)
END LOOP;

But here, record is implicitely declared by PL/SQL to match the required type, and after the IN clause, a cursor_name or a SELECT statement is expected.

It makes sense using an explicit SELECT only when the code is simple, otherwise a cursor is the preferred option.

Printing the european countries to the output buffer could be done easily with a cursor FOR-SELECT loop:

begin
for my_rec in (select * from countries where region_id = 1)
loop
dbms_output.put_line(my_rec.country_id || ' ' || my_rec.country_name);
end loop;
end;

But, as we said, it is cleaner doing the same through a FOR-CURSOR loop:

declare
cursor eu_cur is
select * from countries where region_id = 1;
begin
for my_rec in eu_cur
loop
dbms_output.put_line(my_rec.country_id || ': ' || my_rec.country_name);
end loop;
end;

Actually, we could write FOR-CURSOR/SELECT equivalent code explicitely creating and managing a recordset and cursor in this way:

declare
cursor eu_cur is
select * from countries where region_id = 1;

my_rec eu_cur%ROWTYPE;
begin
open eu_cur;
loop
fetch eu_cur into my_rec;
exit when eu_cur%notfound;

dbms_output.put_line(my_rec.country_id || ': ' || my_rec.country_name);
end loop;
close eu_cur;
end;

Your choice ...

Chapter 5 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein is about loops.

Go to the full post

Numeric FOR loop

In PL/SQL there is a "classic" for loop, where an integer is used to delimit the range in which the loop has to be executed:

FOR index IN [REVERSE] n .. m
LOOP
(...)
END LOOP;

Where n and m represent the interval limits. Notice that n should be less or equal to m, even in case we specify the REVERSE option. In case n equals m, the loop would be executed just once. If n is greater than m, the control goes after the end of the loop.

Here is a FOR loop that prints the number 1, 2 and 3, each on its own line:

for my_value in 1 .. 3
loop
dbms_output.put_line(my_value);
end loop;

And here is a countdown:

for my_value in reverse 1 .. 3
loop
dbms_output.put_line(my_value);
end loop;


The fifth chapter of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein is about loops.

Go to the full post

WHILE loop

If we don't actually want to loop indefinitely, the PL/SQL simple LOOP statement risks to be unclear to the code reader.

If we know which codition rules the execution of the loop, we'd better use a WHILE loop instead:

WHILE (...)
LOOP
(...)
END LOOP;

The condition should evaluate to a boolean value. Only if such value is true the loop is carried on. In case of false (or NULL) the point of execution jumps to the next instruction after the end of the loop.

Here is the same loop showed in the previous post rewritten as a WHILE loop:

while l_value != 0
loop
dbms_output.put_line(l_value);
l_value := l_value - 1;
end loop;

There is no automatic conversion from integer to boolean here, so we have to write explicitly the check against zero.

More on loops in chapter 5 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein.

Go to the full post

Simple LOOP

The simplest way of iterating the execution of a statement in PL/SQL is achieved through the LOOP statement. And the simplest form of LOOP is this:

loop
(...)
end loop;

We normally want to stop a loop execution, and there are two polite ways of terminating a simple loop: through the EXIT and the EXIT WHEN statements.

Here is an example of a LOOP in an anonymous block terminated by EXIT:

declare
l_value integer := 3;
begin
loop
dbms_output.put_line(l_value);
if l_value = 0 then
exit;
else
l_value := l_value - 1;
end if;
end loop;
end;

We could easily rewrite the loop using EXIT WHEN, making it more readable:

loop
dbms_output.put_line(l_value);
exit when l_value = 0;

l_value := l_value - 1;
end loop;

As you can see, EXIT WHEN is merely a rewriting of an IF (condition) THEN EXIT statement.

Chapter 5 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein is about loops.

Go to the full post

CASE expression

We have seen how to use simple and searched CASE expression in PL/SQL, but this is not the complete story. We can even use a CASE (both simple and searched) in expression context. The CASE expression returns the value accordingly to the selected branch. If no branch is actually selected it returns NULL.

As en example, we see the usage of a local function in an anonymous PL/SQL block that converts the boolean it gets in input in a varchar2 that represents it. A function like that makes sense since the put_line() function in the DBMS_OUTPUT packages does not know how to manage boolean values:

declare
function boolean_to_varchar2(flag in boolean) return varchar2 is
begin
return case flag
when true then 'true'
when false then 'false'
else 'NULL' -- 1.
end;
end;
begin
dbms_output.put_line(boolean_to_varchar2(true));
dbms_output.put_line(boolean_to_varchar2(false));
dbms_output.put_line(boolean_to_varchar2(NULL));
end;

1. if you comment this line, when the input boolean to this function is not true nor false, it won't throw an exception, but it will return NULL, and so the put_line() would just print an empty line.

More information on CASE in the chapter 4 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein, that is about conditional and sequential control.

Go to the full post

Searched CASE statement

The simple CASE statement makes more readable our PL/SQL code when we want to compare the result from an expression evaluation with a bunch of alternatives.

If we have more complex decision to take, it could come in handy a different form of CASE, the so called "searched" one:

CASE
WHEN expression THEN (...)
...
ELSE (...)
END CASE;

The structure is close to the "simple" form, but we have multiple expressions, one for each WHEN, all of them are sequentially executed, until we find one that evaluates to true. If none is found, we execute the code in the ELSE clause. If no ELSE clause is provided, the statement throw a case_not_found exception, just like the "simple" CASE.

Here is an example of searched case, based on the oracle hr test schema. We read a salary of a employee than we print a message accordingly to its value. We have a few cases. A salary is considered "top" if it is greater that 20000; high if in (10000, 20000]; average if in (6000, 10000]; low if in [3000, 6000]; and minimal otherwise, that means less than 3000:

declare
l_id number(6,0) := 100;
l_salary number(8,2);
begin
select salary
into l_salary
from employees
where employee_id = l_id;

case
when l_salary > 20000 then
dbms_output.put_line('Top salary');
when l_salary > 10000 then
dbms_output.put_line('High salary');
when l_salary > 6000 then
dbms_output.put_line('Average salary');
when l_salary >= 3000 then
dbms_output.put_line('Low salary');
else
dbms_output.put_line('Minimal salary');
end case;
exception
when no_data_found then
dbms_output.put_line('No ' || l_id || ' among the employees.');
when others then
dbms_output.put_line('unexpected');
end;

The chapter 4 of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein is about conditional and sequential control. There you would find a lot more info on CASE statements, searched or simple.

Go to the full post

Simple CASE statement

When in your PL/SQL code the IF statement is not enough, here comes the CASE to help.

In its simple form it looks like this:

CASE expression
WHEN result1 THEN (...)
...
ELSE (...)
END CASE;

Actually, we could use it in an even simpler form, with just a branch and no final else.
Here is a first example, where the we write something to the output buffer if the country is in region 1:

declare
l_id varchar2(2) := 'IT';
l_region integer;
begin
select region_id
into l_region
from countries
where country_id = l_id;

case l_region
when 1 then
dbms_output.put_line(l_id || ' is in Europe');
end case;
exception
when no_data_found then
dbms_output.put_line('No ' || l_id || ' among the country ids.');
when case_not_found then
dbms_output.put_line('case not found');
when others then
dbms_output.put_line('unexpected');
end;

We catch a case_not_found exeception here, that is what the CASE throw when it happens that no branch is actually selected. If you put 'EG' in l_id you'll what I mean. (I even add a catch-all clause, just to see it at work)

It's not a good idea throw-catching exceptions, if there is way to avoid it. In this case we can make good use of the ELSE clause in our CASE:

case l_region
when 1 then
dbms_output.put_line(l_id || ' is in Europe');
else
dbms_output.put_line('I don't know where ' || l_id || ' is');
end case;

This lead to the generic case for the simple case, with a number of WHEN clauses, and a final ELSE:

case l_region
when 1 then
dbms_output.put_line(l_id || ' is in Europe');
when 2 then
dbms_output.put_line(l_id || ' is in America');
when 3 then
dbms_output.put_line(l_id || ' is in East - Far East');
when 4 then
dbms_output.put_line(l_id || ' is in Middle East - Africa');
else
dbms_output.put_line('I don''t know where ' || l_id || ' is');
end case;

I'm writing this post while skimming through the fourth chapter (about conditional and sequential control) of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein. It's a good text on PL/SQL, if you are looking for a sort of reference book.

Go to the full post

IF statement

The PL/SQL IF statements comes in three flavours:

IF THEN (...) END IF;
IF THEN (...) ELSE (...) END IF;
IF THEN (...) ELSIF (...) ELSE (...) END IF;

From Oracle 9 onwards, there's no much use for the third form, since the CASE statement is available and preferred.

As an example of the first form, we write an anonymous PL/SQL block that performs a select on the country_name table putting the found country_name in the local variable l_country. Then we use the IF statement to check if the found country is the expected one. If so, a message is sent to the output buffer:

declare
l_country varchar2(40);
l_id varchar2(2) := 'IT';
begin
select country_name
into l_country
from countries
where country_id = l_id;

if(l_country = 'Italy')
then
dbms_output.put_line(l_id || ' stands for Italy');
end if;
exception
when no_data_found
then
dbms_output.put_line('No ' || l_id || ' among the country ids.');
when value_error
then
dbms_output.put_line('Check your local variables...');
end;

What if the country_id specified does not exist in the table? Well, an exception is raised (no_data_found). Another exception could be raised if case we have a mismatch between our local variable types and the actual data we put in them. So, for instance, if we put 'ITA' in l_id we should have a value_error exception.

As example for the second form, consider a variation on the previous example. Now we want to output something also in the case we don't find the expected match. We change just the IF block, that now is:

if(l_country = 'Italy')
then
dbms_output.put_line(l_id || ' stands for Italy');
else
dbms_output.put_line(l_id || ' does not stand for Italy');
end if;

No example for the third form, let's use a CASE instead.

I'm writing this post while skimming through the fourth chapter (about conditional and sequential control) of Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein. It's a good text on PL/SQL, if you are looking for a sort of reference book.

Go to the full post

Starting up with SQL*Plus

Even though you have access to Oracle SQL Developer, it makes sense knowing how to get around with SQL*Plus, a quite user-unfriendly tool that has the advantage of being available almost everywhere.

You should find it in the server/bin folder of your Oracle installation, and you run it calling sqlplus from the console.

You can save some time providing username and password at command line (usually regarded as a bad idea, for security considerations):
sqlplus hr/password
In this case I'm trying to connect to Oracle through the account of the hr user, assuming its password is the infamous self-descriptive word.

If you don't want to be pushed by sqlplus to provide you username/password at startup, you can call it passing the option /NOLOG - in this case you should call the sqlplus command CONNECT to actually connect to Oracle.

In a real working environment, providing username and password it is usually not enough to estabilish a connection: you should also say which database you actually want to connect to. That means you should also specify, after an '@', the requested service name. If you look for a file named tnsnames.ora (usually in the oracle server/network/admin folder) you should find a list of the available service names; and you will se how the name you pass is usually resolved to a machine name with a specific port on which estabilish the connection.

Once we are connected to our Oracle database, we can run a sql query simply writing it (remember the semicolon at the end):
SQL> select * from countries where region_id = 1;
If you are connected to the Oracle test hr user you should get this output:

CO COUNTRY_NAME REGION_ID
-- ---------------------------------------- ----------
BE Belgium 1
CH Switzerland 1
DE Germany 1
DK Denmark 1
FR France 1
IT Italy 1
NL Netherlands 1
UK United Kingdom 1

Running PL/SQL is not more difficult. We just write the code we want to execute, we just have to enter a slash ('/') on a new line at the end, to ask SQL*Plus to run the code:

SQL> begin
2 dbms_output.put_line('Hello');
3 end;
4 /

Actually, we should remember to ask to SQL*Plus to let us see to output buffer used by the DBMS_OUTPUT package:
SET SERVEROUTPUT ON
Otherwise we won't read the hello message, but just a confirmation message from SQL*Plus:
PL/SQL procedure successfully completed.
A short PL/SQL could be execute by the SQL*Plus EXECUTE (or EXEC) command:
EXEC dbms_output.put_line('Hello')

I'm writing this post while reading Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein. I suggest you to get a copy of it, if you want to read more on this stuff.

Go to the full post

What PL/SQL is about

It should be enough to read out its complete name to understand what PL/SQL is about: Procedural Language extensions to the Structured Query Language.

So, through PL/SQL we should be able to to some "real" programming, integrating the underlying SQL functionality. Something like using JDBC for Java, but here we are in the database - so we have its full power in our hands. On the other side, we are strictly bound to it. So strictly that we can forget about other non-Oracle databases.

Here is an example, based on the well known hr sample database that is provided by Oracle itself, of PL/SQL code:

-- this is a PL/SQL script

declare
name_count integer;
begin
select count(*)
into name_count
from employees
where first_name = 'Steven';

dbms_output.put_line('found ' || name_count || ' contacts.');
END;

As you see, it is a curious mixing up of a procedural language of the seventies and SQL as we know it.

First line is a comment, that it is formatted just like a SQL one.
The code is structured in a DECLARE section for the local variables, and a BEGIN-END block where the algorithm lies.
The SELECT statement is very close to the one we already know, but it outputs it result INTO our local variable.
And finally we use the put_line() function from the DBMS_OUTPUT utility package to write something (included our local variable) to the associated output buffer.

I'm writing this post while reading Oracle PL/SQL Programming, fifth edition, by Steven Feuerstein. I suggest you to get a copy of it, if you want to learn more on this stuff.

Go to the full post

Hello PL/SQL by DBMS_OUTPUT

I'm using Oracle SQL Developer (OSD), connected to Oracle 11, and I would like just to say hello.

Actually, being OSD a graphical version of SQL*Plus, we can use the its PROMPT command
PROMPT hello
But we want to say hello in a PL/SQL fashion, so we use the DBMS_OUTPUT package.

It is all quite simple, we just have to remember that the DBMS_OUTPUT package to issue the command SET SERVEROUTPUT ON to actually see the output.

OSD makes available a window just for DBMS_OUTPUT, called DBMS Output Pane. If you use it, you should click on the green plus on the left to set server output on for your connection.

When we are ready, we can finally say hello in a PL/SQL block:

begin
dbms_output.put_line('hello');
end;

Go to the full post

boost::thread on member function

We have already seen how to create threads running on free functions and on functors. Now we are about to see how to run threads on member functions.

Have a look at this class:

class Multi
{
private:
boost::mutex mx_;
int value_;
public:
Multi(int value) : value_(value) { }

int getValue() { return value_; }

void increase()
{
for(int i = 0; i < 3; ++i)
{
{
boost::lock_guard<boost::mutex> lock(mx_);
std::cout << "Thread " << boost::this_thread::get_id()
<< ": " << ++value_ << std::endl;
}
boost::this_thread::sleep(boost::posix_time::millisec(50));
}
}

void divide(int div)
{
for(int i = 0; i < 3; ++i)
{
{
boost::lock_guard<boost::mutex> lock(mx_);
std::cout << "Thread " << boost::this_thread::get_id()
<< ": " << (value_ /= div) << std::endl;
}
boost::this_thread::sleep(boost::posix_time::millisec(50));
}
}
};

We have a couple of methods, increase() and divide(), competing on a resource, value_, whose access is ruled by the mutex mx_. Actually, mx_ is used to protect the access to both value_ and std::cout - in this case there was no need of a dedicate mutex for each resource. As usual, the mutex is acquired and released by a lock.

And here a simple function using that class:

void mt05()
{
Multi m(42);
std::cout << "Main thread " << m.getValue() << std::endl;

boost::thread t1(&Multi::increase, &m); // 1.
boost::thread t2(&Multi::divide, &m, 2); // 2.
t1.join();
t2.join();
std::cout << "Main thread: " << m.getValue() << std::endl;
}

1. Here the thread constructor is expecting a callable as first parameter, and this is no news, so we pass it the address of a member function. But now we have to say to the thread to which actual object it should refer, so we pass it the "this" pointer of that object.
2. Same as the previous line, but here we need to pass a value to be used as input parameter to divide().

Go to the full post

By reference to boost::thread

The boost::thread constructor expects a callable object as parameter, and it expects it to be passed by value. Actually it makes sense. Since we have to work with that object in a different thread it is safer to having an independent copy of it.

But if the caller accept to take the responsibility of guaranteeing that object is going to be valid during all the existence of the newly created thread, there should be a way to pass that object by reference. And actually there is, and it requires us wrapping the object by calling std::ref (or boost::ref, if this new C++0x standard wrapper is not available yet for your compiler).

I have already done some testing on std::ref and boost::thread for Windows/VC++, here I replied the test - with a few variations - for Linux/g++.

This time I can't proudly say that the original code worked with no change whatsoever on the new platform, and this is due to the fact that std::ref is in the std::tr1 namespace, in the current GNU implementation. So, for the time being, it would probably be better using boost::ref() instead.

In any case, here is the include section I used for this version:

#include <iostream>
#include <tr1/functional>
#include <boost/thread.hpp>

Then I created a functor that performs a countdown:

namespace
{
class Callable
{
private:
static boost::mutex mio_;
int value_;
public:
explicit Callable(int value) : value_(value) {}

int getValue() { return value_; }

void operator()()
{
while(value_ > 0)
{
boost::this_thread::sleep(boost::posix_time::seconds(1));

{
boost::lock_guard<boost::mutex> lock(mio_);
std::cout << value_-- << ' ';
std::cout.flush();
}
}
}
};

boost::mutex Callable::mio_;
}

Finally I wrote a function that uses two objects of this class:

void mt04()
{
Callable c1(5);
Callable c2(5);

boost::thread t1(c1); // 1.
boost::thread t2(std::tr1::ref(c2)); // 2.

t1.join();
t2.join();

std::cout << std::endl << "c1: " << c1.getValue()
<< ", c2: " << c2.getValue() << std::endl;
}

1. The thread t1 creates a copy of c1, and performs the countdown on its local copy. The original object c1 won't be changed.
2. The thread t1 is getting a reference to c2, so the countdown is actually changing the original object.

Go to the full post

Most vexing parse

The combined usage of boost::thread and functor could lead to the infamous "most vexing parse" issue. It a sort of misunderstanding from the coder and the compiler, caused by an ambiguity in C++ syntax.

You would find its full description in Item 6 of Effective STL by Scott Meyers. But, in few words, in this mixup the coder thinks he is calling a default constructor to create an object to be used as parameter for a function call, while the compiler gets that he wants to declare a function.

The solution requires the coder to be polite and to explain more clearly what he really wants.

In our case the issue could raise with a minimal change in the code. Say that we decided to give a default to the Count constructor:
Count(const int multi = 1) : multi_(multi) {}
Our idea was that in this way we'd save some typing, since 1 was the most popular choice for creating a Count.

This leads us to create a thread writing (wrongly):
boost::thread t1(Count());
From our point of view the code is clearly the request of creating a thread object named t1, passing to it a Count instance initialized with the default value (one).

Unfortunatly, for the compiler we declared nothing less than a function named t1, returning a boost::thread object and accepting in input as parameter an unnamed pointer to function with no parameter and returning a Count object.

Why should we ever want to declare such a thing? Well, there is no use in discussing with a compiler. Better to clarify what we mean, adding an extra pair of round brackets:
boost::thread t1((Count()));

Go to the full post

Functor and boost::thread

We have just seen how to create a boost::thread object associated to a free function, so to run it in a different thread.

I have already written a post on using functor instead. In that case I was working on Windows and VC++, but the code didn't need to be changed at all to run on Linux and g++.

Actually, after testing that no change was required, I did change it a bit, to comply with a slightly different code-style and, to introduce some thrill, adding a short sleep after any write.

Here is the new version:

#include <iostream>
#include <boost/thread.hpp>

namespace
{
class Count
{
static boost::mutex mio_;
const int multi_;
public:
Count(const int multi) : multi_(multi) { }

void operator()()
{
for(int i = 0; i < 10; ++i)
{
{
boost::lock_guard<boost::mutex> lock(mio_);
std::cout << "Thread " << boost::this_thread::get_id()
<< " is looping: " << i*multi_ << std::endl;
}
boost::this_thread::sleep(boost::posix_time::millisec(50));
}
}
};

boost::mutex Count::mio_;
}

void mt02()
{
std::cout << "Main thread " << boost::this_thread::get_id() << std::endl;
boost::thread t1(Count(1));
boost::thread t2(Count(-1));
t1.join();
t2.join();
std::cout << "Back to the main thread " << std::endl;
}

As already said in the original post, there is no real need for a functor for such a limited functionality, when a function could do fine. The only nuisance was on the parameter binding, but since a call to bind is done in the boost::thread constructor when required, there is no reason to prefer a functor in such a simple case.

Here is the new version of the code - also in this case the slight changes were not due to the change of the development platform:

#include <iostream>
#include <boost/thread.hpp>

using namespace std;

namespace
{
boost::mutex mio;

void counter(const int multi)
{
for(int i = 0; i < 10; ++i)
{
boost::this_thread::sleep(boost::posix_time::millisec(20)); // 1.
{
boost::lock_guard<boost::mutex> lock(mio);
cout << boost::this_thread::get_id() << ": " << multi * i << endl;
}
}
}
}

void mt03()
{
// boost::thread t1(boost::bind(&myCount, 1));
// boost::thread t2(boost::bind(&myCount, -1)); // 2.
boost::thread t1(&counter, 1);
boost::thread t2(&counter, -1);

t1.join();
t2.join();
}

1. Just to change things a bit, here the sleep is before writing.
2. We could have written the binding explicitly, but it is not required.

Go to the full post

Hello boost::thread

I have just written a Makefile (for Linux-RedHat) and now I'm using it for a tiny program testing multithreading with Boost. The fact is that the standard C++ thread support in g++ is still marked as experimental, and I need something more stable - so I'm using boost::thread.

The idea is having a simple environment where writing a few functions using the boost::thread features. I'm not using a real test environment, at least for the moment, because we are still to take a few decisions on it. In any case it would be easy to move the job done in this way to actual test cases.

Here is the main, it just prints a message and calls the functions (currently just one):

#include
#include "hello.h"

int main(int argc, char* argv[])
{
std::cout << "Testing Boost " << std::endl;

mt01();

// std::cout << "Press Enter to terminate" << std::endl;
// std::cin.ignore();
}

I currently don't need the parameter list in main, but it could be useful for future tests, and it gives no harm.
Initially I thought it was a good idea to "pause" the execution at the end. But since I'm running my application directly from the terminal, I don't actually need to let it hang until I press enter, so I commented the last two lines.

The hello.h is currently just an include guard and a function declaration:

#ifndef THISTHREAD_HELLO_H
#define THISTHREAD_HELLO_H

extern void mt01();

#endif // THISTHREAD_HELLO_H

And here finally is the first test on boost::thread:

#include <boost/thread/thread.hpp>
#include <iostream>

namespace
{
void hello() // 1.
{
std::cout << "Hello from thread "
<< boost::this_thread::get_id() << std::endl;
}
}

void mt01()
{
std::cout << "This is thread "
<< boost::this_thread::get_id() << std::endl; // 2.

boost::thread t(&hello); // 3.
t.join(); // 4.

std::cout << "Back to "
<< boost::this_thread::get_id() << std::endl;
}

1. Just a simple local function.
2. To show that actually we are in a different thread, I get the id of the current thread through the free function get_id() defined in the boost::this_thread namespace.
3. An object boost::thread is created passing to it the address of a function (1), that would be executed in a different thread.
4. The current thread hangs waiting the termination of the other one.

Actually, I have already written a very similar post almost an year ago. At that time I was testing boost::thread on Windows, for a different project. In this case, the striking similarity is a feature, since we can see that with boost::thread (and in a near future with the standard C++0x thread) we can achieve multithreading with the same code compiled on different environments.

Go to the full post

Makefile for Boost

I'm setting up a testing environment for boost::thread on g++ in my Red Hat Linux box. Assuming that the compiler and the Boost libraries are already available, as it is in my case, what it is left to do before programming is creating a Makefile.

The cool thing about make is that you can let it auto-detect almost everithing. In my case I specify just the project name (actually, the name I want to get for the executable), the custom library I'm about to use (boost_thread-mt), and the debugging options (-Wall -g).

As a source names I can say "all the files with .cpp extension", as objects "all the source files, changing their extension to .o", and this is it.

I don't even have to specify the compiler I'm actually using. Make is smart enough to get it by its own.

Here is my Makefile:
# 
# Makefile for some Boost testing
#

MY_NAME := hello
MY_SRCS := $(wildcard *.cpp)
MY_OBJS := ${MY_SRCS:.cpp=.o}
MY_INCLUDE_DIRS :=
MY_LIBRARY_DIRS :=
MY_LIBRARIES := boost_thread-mt

CXXFLAGS += $(foreach includedir,$(MY_INCLUDE_DIRS),-I$(includedir))
CXXFLAGS += -Wall -g
LDFLAGS += $(foreach librarydir,$(MY_LIBRARY_DIRS),-L$(librarydir))
LDLIBS += $(foreach library,$(MY_LIBRARIES),-l$(library))

.PHONY: all clean

all: ${MY_NAME}

$(MY_NAME): $(MY_OBJS)
    $(LINK.cc) $(MY_OBJS) -o $(MY_NAME) $(LDLIBS)

clean:
    @- rm -rf $(MY_OBJS) $(MY_NAME)

OK, there are still a few nuisances. The Makefile syntax is not beautiful, most remarkably the mandatory TAB character in the task lists is a real pain. But, all in all, we can't complain.

Go to the full post

Standard algorithms are cool

Using standard algorithms our code gets easier to read, write, and modify. And even better if we throw in lambda functions. Here we are seeing an example showing how std::transform() looks better than a for loop.

We have to write a piece of code that gets in input an array of doubles and puts them, increased by 42 and keeping their order, at the beginning of a deque.

Let's say this is the array of doubles:

const int DIM = 10;
double data[DIM] = { 0.23, 1.54, 2.44, 3.45, 4.98, 5.93, 6.34, 7.28, 8.58, 9.41 };
dump(data, data+DIM);

And this is the deque:

std::deque<double> d;
d.push_back(999); // this should stay at the end

We can't use push_back(), because the element(s) already in the deque should be kept at the end of it. We can't use push_front() because we would get the unrequired special effect of reversing the data order. We should use insert().

Here is a "classical" solution to our problem, by for loop:

std::deque<double>::iterator pos = d.begin();
for(int i = 0; i < DIM; ++i)
pos = d.insert(pos, data[i] + 42) + 1;

We need to refresh our current position (pos iterator) after the call to insert(), since it invalidates its old value, and we increase it to avoid falling back in the push_front() behaviour.

Once one is accustomed to the standard transform() algorithm, this version of the same code looks clearer:

std::transform(data, data + DIM, inserter(d, d.begin()),
std::bind2nd(std::plus<double>(), 42));

Actually, there are a few features that could look surprising, at first. Maybe you need to get acquainted to inserters, to the binders, or to the standard functor. But after a while all of this would look natural to you.

Moreover, we could avoid using a binder and the plus functor here, if we use a lambda function instead - that makes the code even more clear:

std::transform(data, data + DIM, inserter(d, d.begin()),
[] (double v) { return v + 42; } );

Item 43 of Effective STL, one of the Effective C++ book series by Scott Meyers, is about standard algorithm as a way of writing better C++ code.

Go to the full post

Using std::for_each() instead of for loop

The standard algorithm for_each() is usually more efficent and less error prone than a classical for loop. And after a while it gets more natural to use.

The major nuisance in using for_each(), at least from my point of view, is that we have often to adapt the function we call in it by mem_fun() or mem_fun_ref(). Luckly, lambda function makes it easier for us.

For this example we are about to use this pretty nonsensical class:

class I43
{
private:
const int value_;
public:
I43(int value) : value_(value) {}

int getValue() const { return value_; }

void doSomething() const
{
std::cout << "Doing something on " << value_ << std::endl;
}
};
std::ostream& operator<<(std::ostream& os, const I43& i)
{
return os << i.getValue();
}

The "put to" overload on ostream makes our new class ready to be used for our simple printing utility function.

As usual, let's create some data to work with:

std::vector<I43> vi;
vi.reserve(10);
for(int i = 0; i < 10; ++i)
vi.push_back(i);
dump(vi);

Notice that we push an integer in the vector but, since the underlying vector type is I43, and the I43 ctor having int ad argument is not explicit, our friendly compiler automatically creates an I43 object for us, and put it in the vector.

If we didn't like having an automatic conversion from int to I43 we would have written the constructor in this way:
explicit I43(int value) : value_(value) {}
But we didn't, so our code works fine.

Now we want to call the doSomething() method for each element in the vector. A common approach to this task results in a for using an iterator as loop variable:

typedef std::vector<I43>::iterator IT;
for(IT it = vi.begin(); it != vi.end(); ++it)
it->doSomething();

Using the standard algorithm for_each() is usually considered a better approach:
std::for_each(vi.begin(), vi.end(), std::mem_fun_ref(&I43::doSomething));
Problem is that we have to use a notation that is a bit clumsy. We specify the address of the member function we want to call, then we adapt it to for_each() using std::mem_fun_ref().

A lambda function makes the code a bit more concise and readable:
std::for_each(vi.begin(), vi.end(), [] (I43 i) { i.doSomething(); });

Item 43 of Effective STL, one of the Effective C++ book series by Scott Meyers, says a lot more about why for_each() is better than a for loop

Go to the full post

std::accumulate()

If you need to summarize values in a sequence, the standard function accumulate() is what are you looking for. It is a simple and useful function that just requires some attention. Firstly, its prototype is not in the algorithm include file, as one could expect, but in the less popular numeric. Secondly, we should remeber that the type of the resulting "accumulated" value is deducted by the function from the value we pass it as initial value.

So, if this is the container we are working with:

std::vector<double> vd;
vd.reserve(10);
for(int i = 0; i < 10; ++i)
vd.push_back(1.34 + i * 0.11);
dump(vd);

We'll write something like:

double sum = std::accumulate(vd.begin(), vd.end(), 0.0);
std::cout << "Sum is: " << sum << std::endl;

Where the stress is on the fact that the third parameter of accumulate() is 0.0, a double, and not 0, a simple int.

If we want to get the product of all the elements in the sequence, we use the overload of accumulate() that requires a predicate as last parameter, and we pass it an instance of the standard functor multiplies - in this case specifying double as underlying type:

double prod = std::accumulate(vd.begin(), vd.end(), 1.0, std::multiplies<double>());
std::cout << "Product is: " << prod << std::endl;

More info on std::accumulate(), and its (here not even mentioned) relation with for_each(), in Item 37 of Effective STL, one of the Effective C++ book series by Scott Meyers.

Go to the full post

std::is_partitioned() and std::partition_point()

The C++0x standard has made easier working with partitioning. Now we have a standard function, is_partitioned(), to check if an interval in a container is partitioned against a predicate, and another one, partition_point() that returns an iterator to the first element out of the first group

As we can expect, partition_point() assumes the elements have been already partitioned by the passed predicate.

We are going to test these features on this container:

std::vector<int> vi;
vi.reserve(10);
for(int i = 0; i < 10; ++i)
vi.push_back(i);
dump(vi);

We need a predicate for partitioning the container, say, in even and odd elements. Best choice is a lambda fuction, being the test so easy, but we need to store the function in a local variable, since we have to reuse it a couple of times. The explicit way of doing that is using a function object (declared in the standard functional include file):
std::function<bool (int)> isEven = [] (int i) -> bool { return i%2 == 0; };
But if we want to save some typing we could use the autodetecting type deducing, by the auto keyword, and not specify the lambda return type - letting the compiler deducing it from the code, too:
auto isEven = [] (int i) { return i%2 == 0; };
We are paying our lazyness (and the concision/readability of the produced code) with less control on what we are writing - it is a choice that you have to take.

In any case, now we can test if our sequence is partitioned in even/odd elements:

if(std::is_partitioned(vi.begin(), vi.end(), isEven))
std::cout << "I don't expect this" << std::endl;

After typedeffing the iterator on our vector:
typedef std::vector<int>::iterator IT;
we partition the sequence, and test it again, this time for getting a positive result. Notice the paranoid check on the partitioning result. In this case is just overkilling, but I put it there as I would do in production code:

IT pivot = std::partition(vi.begin(), vi.end(), isEven);
if(std::is_partitioned(vi.begin(), vi.end(), isEven))
{
std::cout << "Now the container is partitioned: ";
dump(vi);
if(pivot != vi.end())
std::cout << "Second group starts at: " << *pivot << std::endl;
}

Now that the sequence is partitioned, we can get its partition point. Actually, here this is not useful at all, since that is the iterator we get back from partition(). But OK, this is just an example:

IT ppoint = std::partition_point(vi.begin(), vi.end(), isEven);
if(ppoint != vi.end())
std::cout << "Partition point is: " << *ppoint << std::endl;

Go to the full post

std::copy_if

With C++0x std::copy_if() is finally here, hurray! But, what if your compiler does not support yet the new standard? You have to write it yourself.

Good news is that the code is quite simple:

template<typename InputIterator, typename OutputIterator, typename Predicate>
OutputIterator my_copy_if(InputIterator begin, InputIterator end, OutputIterator to, Predicate p)
{
while(begin != end)
{
if(p(*begin))
*to++ = *begin;
++begin;
}
return to;
}

Let's see it at work, because it is a good reason to see copy_if, a back_inserter and a lambda function in the same line.

As usual, first step is about setting up the input data:

std::vector<int> vi;
vi.reserve(10);
for(int i = 0; i < 10; ++i)
vi.push_back(i);
dump(vi);

An then let's copy only the even elements:

std::vector<int> vo;
std::copy_if(vi.begin(), vi.end(), std::back_inserter(vo),
[] (int i) -> bool { return i %2 == 0; });
dump(vo);

Here I used the standard copy_if() - using our version won't change the test code.

Why copy_if() has to be written how we see it, and more info on the matter in Item 36 of Effective STL, one of the Effective C++ book series by Scott Meyers.

Go to the full post

Pointer in container and erase-remove idiom

We know that using raw pointers in a standard container is a pain in the neck. But we now we can use instead smart pointers, as the shared_ptr originally provided by Boost, and now available as part of the C++0x standard.

With smart pointers there is no special issue, we barely use the erase-remove idiom as we already know it.

But there is some interest in this post, because we are about to use a lambda function and improve again our simple dump function, to let it deal with pointers.

Firstly, we write a class that we are about to use dinamically:

class Simple
{
private:
const int value_;
bool valid_;
public:
Simple(int value) : value_(value), valid_(true) {}

bool isValid() const { return valid_; }
void setValid(bool valid) { valid_ = valid; } const

int getValue() const { return value_; }
};

Then we write a variation on our function for dumping elements in a container, specific for pointers management:

template <typename T, typename InputIterator>
void dumpPtr(InputIterator begin, InputIterator end,
std::ostream& os = std::cout, const char* const delimiter = " ")
{
std::for_each(begin, end, [&] (T t) { os << *t << delimiter; } );
os << std::endl;
}

It doesn't change much, actually, from the previous version. We just acknowledge that we have to do with a pointer, and dereference it on usage.

We should remember to write an overload for the "put to" operator, so that we can output Simple objects:

std::ostream& operator<<(std::ostream& os, const Simple& s)
{
return os << s.getValue() << " (" << s.isValid() << ')';
}

We are going to work with shared pointers to Simple objects. A typedef is going to be useful:
typedef std::shared_ptr<Simple> SPS;
Given all this, we create a vector of smart pointers to Simple, put some data in it, and mark as not valid a few items:

std::vector<SPS> vss;
vss.reserve(10);
for(int i = 0; i < 10; ++i)
vss.push_back(SPS(new Simple(i)));

vss[2]->setValid(false);
vss[5]->setValid(false);
vss[8]->setValid(false);

dumpPtr<SPS>(vss.begin(), vss.end());

And now the fun stuff:

vss.erase(std::remove_if(vss.begin(), vss.end(),
[] (SPS s) -> bool { return s->isValid() == false; }), vss.end());

It is just a line of code, but it is quite dense.

We use the remove_if() standard algorithm using as a predicate a lambda function (notice the "arrow" notation to specify its return type) that works on each smart pointer in the passed range. The returned iterator from remove_if() is used as beginning of the sequence that has to be erased from the vector.

More info on this issue in Item 33 of Effective STL, one of the Effective C++ book series by Scott Meyers.

Go to the full post

Standard partial sorting

Sometimes using std::sort(), or its stable and hence more costly version std::stable_sort(), is unnecessary expensive. We could use instead other standard functions like partial_sort(), nth_element(), or partition().

First step, let's create a shuffled vector of ints:

std::vector<int> vi;
vi.reserve(100);
for(int i = 0; i < 100; ++i)
vi.push_back(i);
std::random_shuffle(vi.begin(), vi.end());
dump(vi);

If we need just the top 20 elements, we could do just a partial sort, that puts in the correct order only the range specified by the first two iterators:

std::partial_sort(vi.begin(), vi.begin() + 20, vi.end());
dump(vi.begin(), vi.begin() + 20);

If we are not iterested in the order, but only in the top elements, we could call instead nth_element():

std::nth_element(vi.begin(), vi.begin() + 20, vi.end());
dump(vi.begin(), vi.begin() + 20);

The nth_element() function() is written in such a way that it makes it useful for getting a specific nth element in a collection (as its name shows) limiting the ordering effort on the collection. So we could use it, for instance, to get the median element in a collection:

std::vector<int>::iterator target = vi.begin() + vi.size() / 2;
std::nth_element(vi.begin(), target, vi.end());
std::cout << "Median is: " << *target << std::endl;

A less costly function is partition(), that applies a predicate to a collection to partition it in two groups, returning the iterator to the last element of the group respecting the passed condition. Given this function:
bool even(int value) { return value%2 == 0; }
we can use it to partition our vector:

std::vector<int>::iterator lastEven = std::partition(vi.begin(), vi.end(), even);
dump(vi.begin(), lastEven);

For more details on partitioning and partial sorting, have a look at Item 31 of Effective STL, in the Effective C++ book series by Scott Meyers.

Go to the full post

Using inserters

When calling standard functions on containers, we should pay attention on memory issues. When we need the standard function to allocate memory we should explicitely require this using back_inserter, front_insert, or inserter (specifying where).

For example, consider this function:

int square(int value)
{
return value * value;
}

An this vector that represents our input data:

std::vector<int> vi;
vi.reserve(5);

for(int i = 0; i < 10; ++i)
vi.push_back(i);
dump(vi);

We are about to create a modified copy of the input data in a second array, using the standard function transform(). To represent the position where to put the data in the ouput vector we use the back_inserter():

std::vector<int> vr;
vr.reserve(vi.size());
std::transform(vi.begin(), vi.end(), std::back_inserter(vr), square);
dump(vr);

If the output is a list, we could decide to push the data at its beginning, causing an inversion in the sequence:

std::list<int> lr;
std::transform(vi.begin(), vi.end(), std::front_inserter(lr), square);
dump(lr);

Considering again a vector, this time not an empty one, like:

std::vector<int> vr2;
vr2.reserve(vi.size() + 2);
for(int i = 0; i < 2; ++i)
vr2.push_back(999);
dump(vr2);

We could want to put the data in the middle:

std::vector<int>::iterator it = vr2.begin() + vr2.size() / 2;
std::transform(vi.begin(), vi.end(), std::inserter(vr2, it), square);
dump(vr2);

For more details on the inserters, have a look at Item 30 in Effective STL, one of the Effective C++ book series by Scott Meyers.

Go to the full post

Base for reverse_iterator

We have a vector, a huge one, and we expect that an element we are looking for it is closer to its end than its beginning. So we perform a find() on the reversed vector, delimited by the reversed begin-end iterators, and we get back a reverse iterator pointing to the found element (or to the vector reverse end).

To use the reverse iterator we have to convert it to a straight one, by its base() member function. But you should pay attention to the context in which you are using it.

Here we have a vector and we perform a reverse find() looking for an element:

std::vector<int> vi;
vi.reserve(5);

for(int i = 0; i < 5; ++i)
vi.push_back(i);
dump(vi);

std::vector<int>::reverse_iterator rit = find(vi.rbegin(), vi.rend(), 3);

To insert a new element in the vector after the found, we pass the converted resulting reverse iterator to the insert() vector member function:
vi.insert(rit.base(), 99);
But if we want to erase the element we found we actually need to decrement the converted iterator before removing:

if(rit != vi.rend())
vi.erase(--rit.base());

If we forget to do that the unexpected result will be to remove the next element instead (in this case _4_ instead of _3_).

More on this topic in Effective STL Item 28. Have fun with the Effective C++ book series by Scott Meyers.

Go to the full post

C++ Hash table

Hash tables were not part of the Standard C++ Library before C++0x, but there are a number of different implementations providing them, under the names of hash_set, hash_multiset, hash_map, and hash_multimap.

Since these names have been already taken, the C++0x hash containers have a bit less intuitive names: unordered_set, unordered_multiset, unordered_map, and unordered_multimap.

If your compiler does not support yet this C++0x feature, you can use the boost implementation, that is already available, almost surely, for it too.

Effective STL is one of the Effective C++ book series by Scott Meyers. Its Item 26 is about the pre-C++0x non-standard hash containers

Go to the full post

Sorted vector instead of map

A map/multimap is a perfect container if you plan to perform on it a random mix of insertions, lookups, erasures.

If there is a pattern in its usage (a setup where data are inserted, a lookup where data are retrieved, a reorganization when the data is changed, ...) it could be worthy using a less fancy but more efficient sorted vector.

The idea is setting the data, sorting the vector, and then looking up using the standard searching functions for sorted containers. Then maybe change the data, sort again, and go on again with searching phase.

As we are about to see, the main difference to the sorted vector for set usage is in the way to compare values to the elements in the vector, that requires some caution.

After defining a synonim to the pair that we are going to use, we write a functor that we are going to use for comparisons. We actually have to write three overloads for operator(), since we have to manage comparisons among pairs, and pair against key both as first or second argument:

typedef std::pair<std::string, int> Data;

class DataCompare
{
private:
bool keyLess(const Data::first_type& k1, const Data::first_type& k2) const
{
return k1 < k2;
}

public:
bool operator()(const Data& lhs, const Data& rhs)
{
return keyLess(lhs.first, rhs.first);
}

bool operator()(const Data& lhs, const Data::first_type& k) const
{
return keyLess(lhs.first, k);
}

bool operator()(const Data::first_type& k, const Data& rhs) const
{
return keyLess(k, rhs.first);
}
};

Now we define an overload for the "put to" operator on ostream - this is for enabling us to use the utility dump() function previously described:

std::ostream& operator<<(std::ostream& s, const Data& p)
{
return s << '(' << p.first << ", " << p.second << ')';
}

So, we are ready to work with our vector that is about to emulate a map. We put some data in it, converting an int to a std::string, and we shuffle the data to simulate a random data creation:

std::stringstream ss;

std::vector<Data> vd;
vd.reserve(10);
for(int i = 0; i < 10; ++i)
{
ss << i;
Data d(ss.str(), i * i);
ss.str("");

vd.push_back(d);
}

std::random_shuffle(vd.begin(), vd.end());
dump(vd);

Before working on this vector, we have to sort it:

std::sort(vd.begin(), vd.end());
dump(vd);

And now we are ready to search data on it:

std::string target = "5";
if(std::binary_search(vd.begin(), vd.end(), target, DataCompare()))
std::cout << "binary_search found " << target << std::endl;

Let's use now our vector as a multimap emulation, adding some duplicated data. Before using it we should remember to sort again the vector:

vd.reserve(20);
for(int i = 0; i < 10; ++i)
{
ss << i;
Data d(ss.str(), i * i);
ss.str("");

vd.push_back(d);
}

std::sort(vd.begin(), vd.end());
dump(vd);

We are ready to search. First thing we typedef the constant iterator on the vector, to save some typing and keep the code readable, than we search through lower_bound(), paying attention to the comparison clause, and equal_range(), using a pair of iterators on the vector to check the result:

typedef std::vector<Data>::const_iterator CIT;
CIT it = std::lower_bound(vd.begin(), vd.end(), target, DataCompare());
if(it != vd.end() && !(it->first < target))
std::cout << "lower_bound found: " << *it << std::endl;

std::pair<CIT, CIT> range = std::equal_range(vd.begin(), vd.end(), target, DataCompare());
if(range.first != range.second)
std::cout << "equal_range found: " << *(range.first) << std::endl;

Many more details on sorted vectors in Item 23 of Effective STL, part of the Effective C++ book series by Scott Meyers.

Go to the full post

From int to std::string

The sprintf() function is the standard approach for converting an integer to a c-string - being the well known itoa() function not part of any C standard.

For C++ std::string it is usually preferred going through a std::stringstream and then costructing our string out if it.

In this example we see how to create a few strings from ints, and printing them using the dump() function described previously:

std::vector<std::string> vs;
vs.reserve(10);

std::stringstream ss;
for(int i = 0; i < 10; ++i)
{
ss << i; // 1.
std::string s(ss.str()); // 2.
vs.push_back(s);
ss.str(""); // 3.
}
dump(vs);

1. Inside the loop we put an integer in the string stream;
2. then we extract the string from the stream, use it to create a new string by copy, and finally push the newly created string in the vector;
3. we reset the stream, to be ready for a new string creation.

Go to the full post

Printing map not using ostream_iterator

My simple dumping function for containers has a few limitations, the worst of them probably is that it doesn't work for maps.

The fact is maps are based on std::pair, no "put to" operator on ostream is defined for it in the std namespace, but ostream_iterator really needs it there to do its job.

So I have taken a different approach. Instead of using the standard copy() algorithm coupled with ostream_iterator, I'm using here for_each() and I'll add a local "put to" operarator definition for my pair.

Here is my new version of the function:

template <typename InputIterator>
inline void dump(std::ostream& os, InputIterator begin, InputIterator end,
const char* const delimiter = " ")
{
typedef std::iterator_traits<InputIterator>::value_type T;
std::for_each(begin, end, [&] (T t) { os << t << delimiter; } );
}

I have used a lambda function to keep the code sleek and compact. If you compiler does not allow lambda yet, you can use the boost implementation.

The overload for "normal usage" on standard output has not changed:

template <typename InputIterator>
inline void dump(InputIterator begin, InputIterator end)
{
dump(std::cout, begin, end);
std::cout << std::endl;
}

As also the overload for dumping all the items in the container stays the same:

template <typename Container>
inline void dump(const Container& c) { dump(c.begin(), c.end()); }

Given this new version of dump(), I define a map and a operator "put to" working for its undelying pair:

typedef std::map<int, int> MII;
typedef MII::value_type MII_VT;
std::ostream& operator<<(std::ostream& s, const MII_VT& p)
{
return s << '(' << p.first << ", " << p.second << ')';
}

And here is a sample code for testing:

MII mii;
for(int i = 0; i < 10; ++i)
mii[i] = i * i;

dump(mii);

Go to the full post

Sorted vectors instead of set

A set is a perfect data structure if you plan to perform on it a mix of different operations (insertions, lookups, erasures) with no control on what is going on next.

If you can see a definite pattern in its usage (a setup where data are inserted, a lookup where data are retrieved, a reorganization when the data is changed, ...) it could be worthy using a less fancy but more efficient sorted vector.

The idea is setting the data, sorting the vector, and then looking up using the standard searching functions for sorted containers.

Here is an usage example.

First thing we put some data in our vector:

std::vector<int> vi;
vi.reserve(10);
for(int i = 0; i < 10; ++i)
vi.push_back(i);

std::random_shuffle(vi.begin(), vi.end());
dump(vi);

Once we have the data ready (I shuffled the vector to emulate a random initialization), we can sort it:

std::sort(vi.begin(), vi.end());
dump(vi);

Time to perform some data search. We can use the standard alogorithm binary_search():

int target = 5;
if(std::binary_search(vi.begin(), vi.end(), target))
std::cout << "binary_search found " << target << std::endl;

Let's add some more data, duplicating the values, so to make the test a bit more interesting:

vi.reserve(20);
for(int i = 0; i < 10; ++i)
vi.push_back(i);
std::sort(vi.begin(), vi.end());
dump(vi);

We can use lower_bound() to get the first element with the given value, but we should pay attention writing the condition that ensures we have a good value:

typedef std::vector<int>::const_iterator CIT;
CIT it = std::lower_bound(vi.begin(), vi.end(), target);
if(it != vi.end() && !(*it < target))
std::cout << "lower_bound found: " << *it << std::endl;

In this simple case we could have checked just for equality but, generally speaking, the negation of less is the correct way of approaching the problem.

Otherwise we could use equal_range() that does not suffer that issue:

std::pair<CIT, CIT> range = std::equal_range(vi.begin(), vi.end(), target);
if(range.first != range.second)
std::cout << "equal_range found: " << *range.first << std::endl;

Many more details on sorted vectors in Item 23 of Effective STL, part of the Effective C++ book series by Scott Meyers.

Go to the full post

Associative containers, pointers, comparison

When we put strings in an associative container like set, we expect them to be stored by default by ascending alphabetical order. And that is exactely what happens, if we are working with a set of string.

The issue is if our set is of pointer to strings, since the default comparison keeps the elements ordered by address, and not by the string content.

If we want it being meaningful, we have to override the default with a more sensible choice.

Actually, it is not a good idea to put pointers in a container - if we do that, we have to remember to delete the pointers "manually" when their are not in use anymore - it is better to use smart pointers instead. Not the auto_ptr, obviously, since they are not designed to be used in standard containers, but a copy-supporting one, like shared_ptr, that are going to be available in C++0x. If your compiler does not provide it, you can use the boost implementation.

First thing, let's reduce the typing introducing a typdef for the shared pointer to string:
typedef std::shared_ptr<std::string> SS;
Now, we write a functor that we are going to use for comparing correctly the strings in our container:

struct SmartStringLess : public std::binary_function<const SS&, const SS&, bool>
{
bool operator()(const SS& ps1, const SS& ps2)
{
return *ps1 < *ps2;
}
};

We'll need also a function that prints the string in the passed smart pointer:

void printSS(const SS& ss)
{
std::cout << *ss << std::endl;
}

And, again to reduce typing, another couple of typedefs for the set of smart pointers and for the iterator on the set:

typedef std::set<SS, SmartStringLess> SSS;
typedef SSS::const_iterator SIT;

Notice that the definition for the set refers to the functor we created above.

After all this setup, we are ready to creating our set and putting some data in it:

SSS sss;
sss.insert(new std::string("Alpha"));
sss.insert(new std::string("Delta"));
sss.insert(new std::string("Tango"));
sss.insert(new std::string("Foxtrot"));

Given that we specified the SmartStringLess functor, the strings are stored alphabetically oredered. But we still have an issue, we can't use the standard copy algorithm to the ostream_iterator for printing the content of the container:
std::copy(sss.begin(), sss.end(), std::ostream_iterator<SS>(std::cout, " ")); // !!!
The result of this call is printing, again, the pointers and not the strings.

We should fall back to a classic for loop with a double-dereferenced iteratator (quite ugly, actually):

for(SIT it = sss.begin(); it != sss.end(); ++it)
{
std::string s = **it;
std::cout << s << std::endl;
}

Or we can use instead the standard for_each algorithm, using the printSS() function that we written above:
std::for_each(sss.begin(), sss.end(), printSS);

Many more details on this argument in Item 20 of Effective STL, one of the Effective C++ books by Scott Meyers.

Go to the full post

Erasing elements from a container

The erase-remove idiom is the preferred way to drop elements from vector, deque and string; for list we should call the member function remove(), that implements the erase-remove pattern.

For associative containers we have to pursue a different approach since the remove() algorithm does not work properly here and no remove() member function is available. So, the erase() member function should be used instead.

Here are going to remove all the even numbers from a vector, a list, and a set. First of all we need a function that could be used as predicate for remove_if(), and here it is:

bool even(int value)
{
return value%2 == 0;
}

We initialize a vector in this way:

std::vector<int> v;
v.reserve(10);
for(int i = 0; i < 10; ++i)
v.push_back(i);
dump(v);

And then we eliminate the even elements using the erase-remove (actually, remove_if) idiom:

v.erase(remove_if(v.begin(), v.end(), even), v.end());
dump(v);

Now a list. The job is done by the member remove_if() function:

std::list<int> l;
for(int i = 0; i < 10; ++i)
l.push_back(i);
dump(l);

l.remove_if(even);
dump(l);

Finally the set. The use the member erase(), but we should pay attention not to invalidate the iterator on which we are working. This lead to a piece of code that is a sort of delicate:

std::set<int> s;
for(int i = 0; i < 10; ++i)
s.insert(i);
dump(s);

for(std::set<int>::iterator it = s.begin(); it != s.end(); /* ! */)
{
if(even(*it))
s.erase(it++); // 1.
else
++it; // 2.
}
dump(s);

1. We eliminate an element, so we post-increment the iterator, in this way the invalidated iterator is just a copy used by erase(), we could safely go on looping on it.
2. Nothing to do, we use the more efficent pre-increment operator.

Many more details on this argument in Item 9 of Effective STL, one of the Effective C++ books by Scott Meyers.

Go to the full post

Erase-remove idiom

The remove() standard algorithm doesn't actually remove anything. It just doesn't know how to do it. It works on iterators and it has no access to the underlying container, so what it does it is just manipulating the container and returning an iterator to the new "end" iterator for the container. The elements from "new end" to "old end" are trash, and should be erased for good, using the container specific erase() method.

See what happens if I incorrectly use remove() assuming it works in a "natural" way, and not the actual one (the dump() function is described in a previous post):
std::vector<int> v;
v.reserve(10);
for(int i = 0; i < 10; ++i)
   v.push_back(i);

v[3] = v[5] = v[9] = 99;
dump(v);

remove(v.begin(), v.end(), 99); // !! this is not enough !!
dump(v);
In my environment this is the (unexpected but correct) output:
0 1 2 99 4 99 6 7 8 99
0 1 2 4 6 7 8 7 8 99
As you see, remove() did its job, but we still have to get rid of the trash at the end of the container. And to do that, the best way is calling erase() on the result of remove(), that is an iterator to the "new end", and the iterator to the "current end":
// remove(v.begin(), v.end(), 99); // !! this is not enough !!
v.erase(remove(v.begin(), v.end(), 99), v.end());
It should be clear now why this is called "erase-remove" idiom.

So, the standard remove() algorithm and specialized container method do not actually remove anything. With an exception: the list::remove() method that does actually eliminates the element.
So, in this specific case, we use it in this way:
std::list<int> l;
for(int i = 0; i < 10; ++i)
   l.push_back(i);
dump(l);

l.remove(7); // !! this works correctly !!
dump(l);
I often re-read the Effective C++ books by Scott Meyers. This post has been written while pondering on Item 32 of Effective STL.

Go to the full post

std::istream_iterator

If we are expecting just one type of data from an input stream, we can easily put them in a container using std::istream_iterator. We have a file filled with integers, as an example we can think to a file created in this way:
const char* const filename = "someStuff.dat";

std::ofstream ofs(filename);
for(int i = 0; i < 10; ++i)
    ofs << i << ' ';
ofs.close();
To read it, we can think to loop on a ifstream open on that file, getting one single integer at time and pushing it in our container:
std::ifstream ifs(filename);

std::list<int> data;
while(!ifs.eof())
{
    int value;
    ifs >> value;

    data.push_back(value);
}
dump(data);

ifs.close();
We know that is better to use range member methods, so we rewrite our solution using istream_iterator:
std::ifstream ifs(filename);

std::istream_iterator<int> dataBegin(ifs);
std::istream_iterator<int> dataEnd;
std::list<int> data(dataBegin, dataEnd);
dump(data);

ifs.close();
Notice that we create the "begin" istream_iterator specifying the type we are expecting in the file, and an ifstream to the file itself. The "end" istream_iterator requires just the data type. Do we really need to give names to the iterators? Actually not. They are used only in the list ctor, so we could create them there on the fly. The issue in doing this, is that we have to pay attention in writing it right:
std::ifstream ifs(filename);

std::list<int> data((std::istream_iterator<int>(ifs)), std::istream_iterator<int>());
dump(data);

ifs.close();
The parentheses around the first iterator in the list ctor are mandatory. If you don't put them, for the compiler we are declaring a function, and not defining a list object. I love the Effective C++ books by Scott Meyers. Currently, I'm reading the STL installment. This post is written in connection to its Item 6.

Go to the full post

Partial copy from a std::vector

We have a vector with n elements (let's assume n is even, that is not an issue in any case), we want a second vector containing a copy of just the second half of the first one. How should be do that?

The question is posed in a way that should suggest the usage of the assign() function, member of all the standard sequence container. The alternative solutions are usually less attractive being both less immediate and efficient.

Let's create a couple of vectors with some data in it, and dump their content to standard output (the dump() function is showed in a previous post):

const size_t DATA_SIZE = 6;
int data[DATA_SIZE] = { 41, 35, 75, 71, 19, 11};

std::vector<int> v1(data, data + DATA_SIZE);
dump(v1);

std::vector<int> v2(v1.rbegin(), v1.rend());
dump(v2);

To do the required job we could take it literally. We clear the output vector, then loop on the input vector, starting from its middle element to the end, adding at the end of the output vector a new element copy of the current input one:

v2.clear();
for(std::vector<int>::iterator it = v1.begin() + v1.size() / 2;
it != v1.end(); ++it)
{
v2.push_back(*it);
}
dump(v2);

We can easily rewrite it using the standard copy() algorithm, that hides the loop in its belly and uses back_inserter() to allocate memory at the end of the output vector:

v2.clear();
std::copy(v1.begin() + v1.size() / 2, v1.end(), std::back_inserter(v2));

A marginally better solution would require us to use the inserter() member function that makes clearer that we are inserting new elements in the vector, and not just copying:

v2.clear();
v2.insert(v2.end(), v1.begin() + v1.size() / 2, v1.end());

But the preferred one uses the assign() member function:

v2.assign(v1.begin() + v1.size() / 2, v1.end());

No clear() call is required, since it is done internally by assign() and, most importantly, the complete memory allocation is done by assign() in just one chunck (and for other considerations that you could read in Meyer's book).

I love the Effective C++ books by Scott Meyers. Currently, I'm reading the STL instalment, and this post is based on its Item 5.

Go to the full post

Printing a container

It is such a common task to dump a container to the standard output console that I have written a template function to do this job. (Actually, this solution does not work for maps - in another post I have changed a bit the code to overcome this issue - but this post is still useful as an example for ostream_iterator usage).

There are a few interesting features in a handful of lines: it is a template function getting in input a couple of InputIterators, and uses the std::copy algorithm and the std::ostream_iterator to get its result.

But let's start from the beginning. We have a container, with some data in it:
std::list<int> list1;

list1.push_back(12);
list1.push_back(43);
list1.push_back(44);
list1.push_back(21);
We want to dump it to the console. A trivial way to do that is using a function tailored on the current container we are using:
void dump(std::list<int>& l)
{
  std::list<int>::iterator it;
  for(it = l.begin(); it != l.end(); ++it)
    std::cout << *it << ' ';
  std::cout << std::endl;
}

This works, but it is far from being an optimal solution.
Any time we use a different container, and even if just the typename changes, we have to write another function. Besides, we would like to remove the for loop and using instead a standard algorithm. Moreover, it would be nice if we could print our container on other streams than the output console, and let the user choose for the delimiter between the elements. And, why dumping always all the container, wouldn't be better letting the caller specify the interval to print?

Lots of requirements, as you can see, but it is easy to achieve a solution:
template <typename T, typename InputIterator>
void dump(std::ostream& os, InputIterator begin, InputIterator end,
const char* const delimiter = " ")
{
  std::copy(begin, end, std::ostream_iterator<T>(os, delimiter));
}
One thing is still missing. In the original function the print was completed with an end of line, that here doesn't make much sense. And, the normal usage - at least in my case - of this function is actually for dumping the container to the output console. So I thought it was a good idea to provide this overload:
template <typename T, typename InputIterator>
inline void dump(InputIterator begin, InputIterator end)
{
  dump<T>(std::cout, begin, end);
  std::cout << std::endl;
}
Now we can dump our list to the standard output in this way:
dump<int>(list1.begin(), list1.end());
Nice result, still, do we really have to specify the value type we are about to dump? Actually not, since this information is already stored in the iterator itself.

Our task now is calling the dump function in this way:
dump(vi.begin(), vi.end());
To do that, we remove the typename T reference in the utility dump overload:
template <typename InputIterator>
inline void dump(InputIterator begin, InputIterator end)
{
  dump(std::cout, begin, end);
  std::cout << std::endl;
}
And rewrite the actual dump function like this:
template <typename InputIterator>
inline void dump(std::ostream& os, InputIterator begin, InputIterator end,
const char* const delimiter = " ")
{
  typedef std::iterator_traits::value_type T;
  std::copy(begin, end, std::ostream_iterator(os, delimiter));
}
To extract the information on the data type underneath the iterator, we use the iterator_traits template, that makes it available as a typedef (named value_type).

Right, but we often want to dump the entire container, so it would be friendly to offer another overload, that expects as input parameter just the container itself. By the way, providing it, we keep our new dump functionality compatible with the original dump showed at the beginning of this post:
template <typename Container>
inline void dump(const Container& c) { dump(c.begin(), c.end()); }

Go to the full post

Hello Perl

As default, usually there's no Perl on Windows. But it is easy to get it, install it, and use it. I have just put Strawberry Perl on my Windows 7 machine and I'm fooling a bit around with it.

In this post I'm going to write a short Perl script, checking if I remember how to do it.

They are just a few lines, just to have an idea of a few features available. What this script does is getting a user input, expected to be a list of at least two comma separated values, and outputting the first and the last one of them. It reads from standard input in an infinite loop, that the user could terminate closing the stream (control-Z on Windows) or sending an interrupt to the program:

#!/usr/bin/perl # 1.
use strict; # 2.
use warnings; # 3.

print "Input a CSV line: ";
while(<>) { # 4.
my @fields = split /,/; # 5.
if(@fields > 1) { # 6.
print "First is $fields[0], last is $fields[$#fields]\n"; # 7.
}
else {
print "Please, insert at least two comma separated values\n";
}

print "New input or interrupt: ";
}

1. This first line is not actually required on Windows, let's think to it as a comment saying that this is a perl script.
2. We ask to the perl interpreter to perform more checks than usual, to help us avoiding silly mistakes.
3. Even more perl checking added.
4. In the angular brakets we access a file as input stream and return a string from it. Here we don't specify which file, so perl assumes we are interested in standard input; and we don't specify where to put the result, so perl puts it in the default ("$_").
5. We declare ("my") an array ("@") and we initialize it with the result of a function ("split") that gets in input a string (not specified, so the default one "$_") and the pattern we want to apply to the string for splitting it.
6. Using an array name in a scalar context gives us the array size.
7. The "$#" notation applied to an array name gives back the index of its last element.

As you can see perl helps us to write code that is very compact but, if you are not in the loop, it is a bit hard to be understood, too.

Go to the full post

Developing by testing

We have been asked to write a C++ function that checks if the passed integer is prime. Let's develop it using Google Test as testing environment.

Step 1

The function should have this prototype:
extern bool isPrime(int value);
Let's write a first implementation, any value we pass in, the function says it is not a prime:

bool isPrime(int value)
{
return false;
}

We know it is not working properly, but at least it works.

Step 2

We setup the Google Test environment, so we are going to call RUN_ALL_TEST on a few tests we are about to write.

Negative numbers are not prime, so here is a first lot of tests:

TEST(IsPrimeTest, Negative) {
EXPECT_FALSE(isPrime(-1));
EXPECT_FALSE(isPrime(-2));
EXPECT_FALSE(isPrime(INT_MIN));
}

Let's consider the first positive numbers:

TEST(IsPrimeTest, Trivial) {
EXPECT_FALSE(isPrime(0));
EXPECT_FALSE(isPrime(1));
EXPECT_TRUE(isPrime(2));
EXPECT_TRUE(isPrime(3));
}

And then do some testing on other positive numbers:

TEST(IsPrimeTest, Positive) {
EXPECT_FALSE(isPrime(4));
EXPECT_TRUE(isPrime(5));
EXPECT_FALSE(isPrime(6));
EXPECT_TRUE(isPrime(23));
}

Step 3

We compile and run our application. If we correctly setup Google Test, we are going to find out that the first lot of testing succeed (hurray!) but we have a few errors in the other two ones:

IsPrimeTest.Trivial:
(...)\test.cpp(94): error: Value of: isPrime(2)
Actual: false
Expected: true
(...)\test.cpp(95): error: Value of: isPrime(3)
Actual: false
Expected: true

IsPrimeTest.Trivial:
(...)\test.cpp(101): error: Value of: isPrime(5)
Actual: false
Expected: true
(...)\test.cpp(103): error: Value of: isPrime(23)
Actual: false
Expected: true

Looks like the algorithm we applied in our function is not perfect.

Step 4

We change of function in this way:

bool isPrime(int value)
{
if(value < 2)
return false;
// 2 is prime, all other even numbers not
if((value != 2) && (value % 2 == 0))
return false;
return true;
}


Wow - no errors detected. But have we done enough testing?

Step 4

Let's add some more tests:

TEST(IsPrimeTest, LessThan100) {
EXPECT_FALSE(isPrime(87));
EXPECT_TRUE(isPrime(89));
EXPECT_FALSE(isPrime(95));
EXPECT_TRUE(isPrime(97));
}

Looks like we still have problems:

(...)\test.cpp(107): error: Value of: isPrime(87)
Actual: true
Expected: false
(...)\test.cpp(109): error: Value of: isPrime(95)
Actual: true
Expected: false

And so on ...

Go to the full post

Test Fixtures

Google Test makes us available fixtures, that make our life easier when we would like to use the same data configuration for a number of tests.

A fixture requires us to create a class derived from ::testing::Test that defines all the variables we plan to use in our tests. The declarations of such variables should not be in private section and could be initialized in the class constructor or in the SetUp() method. Then we could do any cleanup job in the destructor (if no exceptions are involved) or in the TearDown() method.

As an example consider the class Squirrel:

#include <string>

class Squirrel
{
private:
std::string name_;
int nuts_;

public:
Squirrel(const char* const name, int nuts =0) : name_(name), nuts_(nuts) {}

void setNuts(int nuts) { nuts_ += nuts; }
int getNuts() { return nuts_; }
std::string getName() { return name_; }
};

Since we plan to do many different tests on a couple of squirrels, we create a class derived from ::testing::Test, ChipNDaleTest, in this way:

class ChipNDaleTest : public ::testing::Test {
protected:
Squirrel chip_;
Squirrel dale_;

ChipNDaleTest() : chip_("Chip"), dale_("Dale") {}
};

Now we can write as many text fixture we need, based on that test class:

TEST_F(ChipNDaleTest, Empty) {
EXPECT_EQ(0, chip_.getNuts());
EXPECT_EQ(0, dale_.getNuts());
}

TEST_F(ChipNDaleTest, Names) {
EXPECT_EQ("Chip", chip_.getName()); // 1.
EXPECT_STREQ("Dale", dale_.getName().c_str()); // 2.
}

1. The name is tested as a std::string, so we can use operator == and then the EXPECT_EQ test macro.
2. Testing the name as a c-string require the usage of a c-string comparison test macro.

Go to the full post

C-string comparison

For checking C++ strings while using Google Test we can use the normal binary comparison ASSERT / EXPECT macros. We can do that because std::string properly redefines the comparison operators.

But if we talk about c-string we can't rely on those macros. As we well know, checking s == t, when s and t are two bare pointers to character, performs a check on the pointers and not to the actual strings of characters.

To check two c-strings for content equality we can use ASSERT_STREQ and EXPECT_STREQ; to enforce their difference we have ASSERT_STRNE and EXPECT_STRNE. Then we have the "ignore case" versions: ASSERT_STRCASEEQ / EXPECT_STRCASEEQ and ASSERT_STRCASENE / EXPECT_STRCASENE.

An example to clarify the matter:

TEST(TestCString, CString) {
const char* const expected = "A string";
const char* const actual = "Another string";
const char* const actual2 = "A string";
const char* const actual3 = "a string";

EXPECT_STREQ(expected, actual);
EXPECT_STRNE(expected, actual2);
EXPECT_STRCASEEQ(expected, actual3); // 1.
EXPECT_STRCASENE(expected, actual3);
}

1. this is the only test that actually succeed, since the two strings differ only in the case of the first letter. The other three test fail, as reported by Guitar:

(...)\test.cpp(56): error: Value of: actual
Actual: "Another string"
Expected: expected
Which is: "A string"
(...)\test.cpp(57): error: Expected: (expected) != (actual2),
actual: "A string" vs "A string"
(...)\test.cpp(59): error: Expected: (expected) != (actual3) (ignoring case),
actual: "A string" vs "a string"

Go to the full post

Binary comparisons

We could just use ASSERT_TRUE and EXPECT_TRUE, and their *_FALSE counterparts, to do all our testing job with Google Test.

But there is a bunch of other assertions and expectations that make our testing more readable. Binary comparisons support comparison between the expected and the actual result of a test using the comparison operators == (ASSERT_EQ, EXPECT_EQ), != (ASSERT_NE, EXPECT_NE), < (ASSERT_LT, EXPECT_LT), <= (ASSERT_LE, EXPECT_LE), > (ASSERT_GT, EXPECT_GT), >= (ASSERT_GE, EXPECT_GE).

Let's see them in action:

TEST(BinaryComparison, Equal) {
int expected = 40;

EXPECT_TRUE(expected == increase(41)); // 1.
EXPECT_EQ(expected, increase(41)); // 2.
EXPECT_EQ(40, increase(41));
EXPECT_NE(42, increase(41));
}

I've used only EXPECT tests, but the ASSERT ones work just the same.
1. We could use EXPECT_TRUE, but the generated message is a bit less readable.
2. We could put a variable or a literal as expected value. In case of a variable, the error message would report its name and value.

Here is the messages as showed by Guitar (the application runner for Google Test):

(..)\test.cpp(18): error: Value of: expected == increase(41)
Actual: false
Expected: true
(..)\test.cpp(19): error: Value of: increase(41)
Actual: 42
Expected: expected
Which is: 40
(..)\test.cpp(20): error: Value of: increase(41)
Actual: 42
Expected: 40
(..)\test.cpp(21): error: Expected: (42) != (increase(41)), actual: 42 vs 42

Let's check now the Less / LessEqual tests:

TEST(BinaryComparison, Less) {
int expected = 40;

EXPECT_LT(expected, increase(39));
EXPECT_LE(expected, increase(38));
}

Here is the feedback from Guitar:

(..)\test.cpp(27): error: Expected: (expected) < (increase(39)), actual: 40 vs 40
(..)\test.cpp(28): error: Expected: (expected) <= (increase(38)), actual: 40 vs 39

And, finally, Greater / GreaterEqual:

TEST(TestIncrease, Greater) {
int expected = 40;

EXPECT_GT(expected, increase(39));
EXPECT_GE(expected, increase(40));
}

with the relative output on Guitar:

(..)\test.cpp(34): error: Expected: (expected) > (increase(39)), actual: 40 vs 40
(..)\test.cpp(35): error: Expected: (expected) >= (increase(40)), actual: 40 vs 41

Go to the full post