Establishing the Baseline
This is a classic job application coding challenge I often revisit.
It's the perfect bite-sized project to refresh a language.
In this project, I'll be establishing my current C++ baseline, so I can identify where to begin the refresh.
Pleasantly Surprised by C++Builder 13.2
Update: I recently brought this C++23 project, originally developed in CLion, into C++Builder and was very impressed by its Modern 64-bit compiler—both its fast compilation speed and its support for modern C++.
It's not a large project, but nevertheless it uses std::variant, std::visit, variadic templates, lambdas, structured bindings and other modern C++ features. A full build takes around 4 seconds, and the application runs flawlessly.
The only adjustment required was a small Windows-specific helper to enable virtual terminal processing for the ANSI control sequences used by the console application:
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include <cstdio>
#include "ConsoleVT.h"
bool EnableVirtualTerminal()
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
if (handle == INVALID_HANDLE_VALUE || handle == nullptr)
return false;
DWORD mode = 0;
if (!GetConsoleMode(handle, &mode))
return false;
std::printf("Console mode: 0x%08lX\n", static_cast<unsigned long>(mode));
if ((mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0)
return true;
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
return SetConsoleMode(handle, mode) != FALSE;
}
Here's a screenshot of the project in RAD Studio 13.2. The original article continues below.
A Canvas with Pixels
Each time I perform this exercise, I try a different approach to the solution. This time, I had the idea of treating the Canvas as an operations producer rather than a view that owns a "pixels" data structure. Essentially, it receives a command and converts it into operations to be applied to a view.
The idea worked well until I realized that bucket fill requires inspecting what's already on the canvas, so PixelBuffer emerged as an entity. I'm not sure how I feel about this approach, to be honest.
Source Code
The project is available on GitHub.
It's a CLion C++23 project. After compiling the project, copy the two demo text files to the cmake-build-debug folder, and run cpppicasso from an ANSI-capable terminal - such as PowerShell 7 on Windows.
PS D:\Source\cpppicasso\cmake-build-debug> .\cpppicasso.exe
The project uses ANSI control sequences for positioning and colours. If you enter the command 2 the second demo should load, looking like this:
On Modern C++
Wow...what a huge change since C++11.
On the one hand, it was very familiar, yet on the other hand, it felt like a new language. Almost like returning home after a long absence and finding that things have moved along—but for the better. A bit like Singapore, which always astounds me with its improvements every time I return.
Standouts
I was really surprised by features like std::variant and std::visit, which facilitated a more explicit, type-safe style of modelling state and behaviour. Similarly, features such as std::optional and std::expected made intent around absence and failure both clearer and harder to ignore.
Improvements in CLion and clangd coupled well with constexpr and attributes such as [[nodiscard]]—the tooling leans you into best practices.
Structured bindings (for (auto& [command, steps] : …)) left me giddy with enthusiasm.
I'm generally impressed and really keen to jump into my next project.