I am pleased to announce that my book on modern C++ programming has been published by PacktPub. The book is called Modern C++ Programming Cookbook and can be ordered at packtpub.com and Amazon. ISBN of the book is 9781786465184. The complete table of contents is available below.

The front cover

The book is organized in recipes, much like a cookbook (therefore the name). These recipes are organized in sections that introduce you to the topic, list any necessary pre-requisites and then explain how to do something and how that works. Throughout 112 recipes, the book covers both language and library features from C++11, C++14 and C++17, including the libraries for strings, containers, algorithms, iterators, input/output, regular expressions, threads, filesystem, atomic operations, and utilities. Besides that, there is a chapter for patterns and idioms and one dedicated for testing frameworks, that covers everything you need to know to get started with Boost.Test, Google Test and Catch.

This book is intended for all C++ developers, regardless of their experience. The beginner and intermediate developers will benefit the most from the book in their attempt to become prolific with C++. Experienced C++ developers, on the other hand, will find a good reference for many C++11, C++14, and C++17 language and library features that may come in handy from time to time. However, the book requires prior basic knowledge of C++, such as functions, classes, templates, namespaces, macros, and others. If you are not familiar with C++ at all, you should first read an introductory book to familiarize yourself with the core aspects.

Although C++17 has not yet been ratified as an ISO standard, the final version that is up for the ballot is well defined. In my book I discuss most of the important language and library features that made it into C++17. The C++17 features discussed in the book are:

  • structured bindings
  • fold expressions
  • constexpr if
  • new attributes ([[fallthrough]], [[nodiscard]], [[maybe_unused]])
  • new type deduction rules for list initialization
  • range based for loops improvements
  • general form of lambda expressions
  • std::invoke() and std::apply()
  • static_assert changes
  • non-member container access functions std::data(), std::size(), and std::empty()
  • std::search() searchers (Boyer-Moore and Boyer-Moore-Horspool)
  • chrono changes (floor(), round(), ceil(), and abs())
  • std::any
  • std::optional
  • std::variant (2 recipes)
  • std::string_view
  • std::scoped_lock
  • filesystem library (5 recipes)
  • shared_ptr and unique_ptr changes

All the samples in the book have been tested with VC++ 2017 (where possible), GCC 7 and Clang 5. All the language and library features discussed in the book are available with these versions of the mentioned compilers, except for a few exceptions for VC++. At this time, the following features are still not supported in VC++:

  • structured bindings
  • fold expressions
  • constexpr if
  • searchers for std::search()

If you do not have the latest versions of these compilers, you can try all the samples in the book with an online compiler. gcc and Clang are available at wandbox.org and VC++ is available at webcompiler.cloudapp.net.

Table of contents

  1. Learning Modern Core Language Features
    • Using auto whenever possible
    • Creating type aliases and alias templates
    • Understanding uniform initialization
    • Understanding the various forms of non-static member initialization
    • Controlling and querying object alignment
    • Using scoped enumerations
    • Using override and final for virtual methods
    • Using range-based for loops to iterate on a range
    • Enabling range-based for loops for custom types
    • Using explicit constructors and conversion operators to avoid implicit conversion
    • Using unnamed namespaces instead of static globals
    • Using inline namespaces for symbol versioning
    • Using structured bindings to handle multi-return values
  2. Working with Numbers and Strings
    • Converting between numeric and string types
    • Limits and other properties of numeric types
    • Generating pseudo-random numbers
    • Initializing all bits of internal state of a pseudo-random number generator
    • Using raw string literals to avoid escaping characters
    • Creating cooked user-defined literals
    • Creating raw user-defined literals
    • Creating a library of string helpers
    • Verifying the format of a string using regular expressions
    • Parsing the content of a string using regular expressions
    • Replacing the content of a string using regular expressions
    • Using string_view instead of constant string references
  3. Exploring Functions
    • Defaulted and deleted functions
    • Using lambdas with standard algorithms
    • Using generic lambdas
    • Writing a recursive lambda
    • Writing a function template with a variable number of arguments
    • Using fold expressions to simplify variadic function templates
    • Implementing higher-order functions map and fold
    • Composing functions into a higher-order function
    • Uniformly invoking anything callable
  4. Preprocessor and Compilation
    • Conditionally compiling your source code
    • Using the indirection pattern for preprocessor stringification and concatenation
    • Performing compile-time assertion checks with static_assert
    • Conditionally compiling classes and functions with enable_if
    • Selecting branches at compile time with constexpr if
    • Providing metadata to the compiler with attributes
  5. Standard Library Containers, Algorithms, and Iterators
    • Using vector as a default container
    • Using bitset for fixed-size sequences of bits
    • Using vector for variable-size sequences of bits
    • Finding elements in a range
    • Sorting a range
    • Initializing a range
    • Using set operations on a range
    • Using iterators to insert new elements in a container
    • Writing your own random access iterator
    • Container access with non-member functions
  6. General Purpose Utilities
    • Expressing time intervals with chrono::duration
    • Measuring function execution time with a standard clock
    • Generating hash values for custom types
    • Using std::any to store any value
    • Using std::optional to store optional values
    • Using std::variant as a type-safe union
    • Visiting a std::variant
    • Registering a function to be called when a program exits normally
    • Using type traits to query properties of types
    • Writing your own type traits
    • Using std::conditional to choose between types
  7. Working with Files and Streams
    • Reading and writing raw data from/to binary files
    • Reading and writing objects from/to binary files
    • Using localized settings for streams
    • Using I/O manipulators to control the output of a stream
    • Using monetary I/O manipulators
    • Using time I/O manipulators
    • Working with filesystem paths
    • Creating, copying, and deleting files and directories
    • Removing content from a file
    • Checking the properties of an existing file or directory
    • Enumerating the content of a directory
    • Finding a file
  8. Leveraging Threading and Concurrency
    • Working with threads
    • Handling exceptions from thread functions
    • Synchronizing access to shared data with mutexes and locks
    • Avoiding using recursive mutexes
    • Sending notifications between threads
    • Using promises and futures to return values from threads
    • Executing functions asynchronously
    • Using atomic types
    • Implementing parallel map and fold with threads
    • Implementing parallel map and fold with tasks
  9. Robustness and Performance
    • Using exceptions for error handling
    • Using noexcept for functions that do not throw
    • Ensuring constant correctness for a program
    • Creating compile-time constant expressions
    • Performing correct type casts
    • Using unique_ptr to uniquely own a memory resource
    • Using shared_ptr to share a memory resource
    • Implementing move semantics
  10. Implementing Patterns and Idioms
    • Avoiding repetitive if…else statements in factory patterns
    • Implementing the pimpl idiom
    • Implementing the named parameter idiom
    • Separating interfaces from implementations with the non-virtual interface idiom
    • Handling friendship with the attorney-client idiom
    • Static polymorphism with the curiously recurring template pattern
    • Implementing a thread-safe singleton
  11. Exploring Testing Frameworks
    • Getting started with Boost.Test
    • Writing and invoking tests with Boost.Test
    • Asserting with Boost.Test
    • Using test fixtures with Boost.Test
    • Controlling output with Boost.Test
    • Getting started with Google Test
    • Writing and invoking tests with Google Test
    • Asserting with Google Test
    • Using test fixtures with Google Test
    • Controlling output with Google Test
    • Getting started with Catch
    • Writing and invoking tests with Catch
    • Asserting with Catch
    • Controlling output with Catch

Credits

It took about eight months to complete this book and I got a lot of help from several people that I would like to thank to. First of all, is the team at PacktPub; although there were more people involve that I actually am aware of, I would like to thank Anurag Ghogre, Subhalaxmi Nadar and Nitin Dasan for all the help they provided throughout this time and the work they put in the project, as well as the other people that were involved with this book. I also want to thank David Corbin, whom I know for many years as “The CPU Wizard”, for reviewing the book and providing valuable feedback that made the book better. And last, but not least, I want to thank my wife for putting up with me through the many days and nights that I worked on this project.

, , , , , , , , Hits for this post: 6486 .

The new Visual C++ 2017, currently in release candidate phase, provides a series of updates and fixes to both the C++ compiler and the standard library. A comprehensive list of these improvements is available at What’s New for Visual C++ in Visual Studio 2017 RC.

In this article, I want to shortly look at the new standard library features from VC++ 2017.

  • std::any (available in header <any>) is a class that represents a type-safe container that can hold the value of any copy-constructible object. To read the value stored in an any variable you need to use the non-member function std::any_cast.

  • std::optional (available in header <optional>) is a class template that may or may not contain a value any moment in time. If it contains a value, it is allocated as part of the optional object, and therefore does not incur any memory overhead.

  • std::variant (available in header <variant>) is a class template that represents a type-safe union. A variant can hold any number of alternatives, but they cannot be of type reference, array or void. The first alternative must be default constructible, because variants are default constructible and a default-constructed variant object contains a value of its first alternative. If the first alternative is not default-constructible, std::monostate (an empty, default-constructible class) can be used for that purpose. If it contains a value, it is allocated as part of the variant object, and therefore does not incur any memory overhead.

  • std::basic_string_view (available in header <string_view>) is a class template that represents a view of a contigous sequence of characters (defined by a pointer to the start of the sequence and a count). Several type aliases are available:

    basic_string_view has an interface almost identical to basic_string so that switching from the later is as simple as possible. A typical useage of this class template is for function parameters as a replacement for constant references to basic_string.

Additional new supported C++17 standard library features are:

  • std::apply is a function template that invokes a specified callable object with a tuple of arguments.
  • std::make_from_tuple is a function template that creates an object by invocking its constructor with the members of a specified tuple.

To have all these available the /std::c++latest compiler switch must be used. This can be also set from the project properties, at C/C++ > Language > C++ Language Support.
vclangsettings

, , , , , , Hits for this post: 10030 .

In Visual Studio 2015 MFC comes with a new features (something that has rarely happen in recent years): support for dynamic dialog layout. That means library support for moving and resizing controls on a dialog. In this article I will show how this feature works.

Suppose we have the following dialog:
Dialog in original size

What we want is that the controls on the dialog move (the buttons) or resize (the group box, edit and the list) when the dialog is resized:

Resized dialog

Resized dialog

The resource editor provides support for this, but it can also be done programmatically. If you open the properties of a control there is a new category called Dynamic Layout that allows you to select a moving and a sizing type.
Dynamic Layout Settings
The options you have for both moving and resizing are: None, Horizontal Vertical, and Both. These options should be self explanatory. However, the important thing to notice is the value for the X and Y axes moving and resizing: these are ratios, not dialog units or pixels, having a value between 1 and 100 and defining how much a control is moved or resized when the host dialog changes size.

Now, to enable the layout shown in the the example above we need to do the following:

  • fully resize (100%) the group box and list box both horizontally and vertically
  • fully resize the edit control horizontally
  • completely (100%) move the OK button vertically
  • completely move the Add button horizontally
  • completely move the Clear and Cancel buttons both horizontally and vertically

Dynamic layout settings for the example dialog
It is pretty simple to put values into the dynamic layout settings for each control. When you build and run and resize the dialog box the controls move or resize accordingly.

These dynamic layout settings are put in the resource script (.rc file) of the application. For the example above it looks like this:

In this definition IDD_MFCDYNLAYOUTDEMO_DIALOG is the identifier of the dialog for which the settings are defined and the numbers in the BEGIN-END block represent:

  • the first line is a header containing the version number on the structure (0 in this version)
  • the consecutive lines are the dynamic layout settings (move and size ratios) for each control on the dialog, corresponding to the order the controls were defined for the dialog in the resource script file.

Dynamic layout settings in .rc file

These settings are loaded into a CMFCDynamicLayout object (see afxlayout.h/cpp). This is done in the OnInitDialog method of the CDialog class as shown below:

Note: for CPaneDialog, CDialogBar and CFormView on the other hand this is done in HandleInitDialog.

This LoadDynamicLayoutResource is actually a member of CWnd which contains other methods for working with dynamic layouts:

  • EnableDynamicLayout: enables or disables layout manager for a window
  • IsDynamicLayoutEnabled: indicates if layout management is enabled for a window
  • GetDynamicLayout: retrieves a pointer to layout manager
  • ResizeDynamicLayout: readjust the position of the controls handled by the dynamic layout manager as a response to WM_SIZE
  • InitDynamicLayout: initializes dynamic layout manager as a response to the WM_CREATE message

These methods allow you to enable or disable the dynamic layout management on the fly.

  1. Initially the dynamic layout management is set so the controls move and resize when the dialog is resized.
    dynlayout6

    dynlayout7

  2. Disable the dynamic layout management and the child controls are no longer adjusted.
    dynlayout8
  3. Re-enable the dynamic layout management and it works again.
    dynlayout9

The catch here is that just calling CWnd::EnableDynamicLayout won’t work because this method only deletes and recreates the CMFCDynamicLayout instance.

Just like CDialog::OnInitDialog you’d have to call CWnd::LoadDynamicLayoutResource. Therefore, the correct code for enabling and disabling dynamic layout management should look like this:

As mentioned earlier, setting the move and size values for dynamic layout management can be done programmatically using the CMFCDynamicLayout class. This is important when the controls are created dynamically and not in the resource template. What you have to do is:

  • create the CMFCDynamicLayout object
  • store the host window (the dialog) in that object
  • add the child controls with their move and size settings

The following code provides the same dynamic layout functionality as shown earlier except that all is set from code. Note that you must call EnableDynamicLayoutHelper from OnInitDialog.

Actually the same code as above can be expressed differently with the help of several static methods from CMFCDynamicLayout that create instances of MoveSettings and SizeSettings.

One important thing to notice here is that this code does not call CWnd::LoadDynamicLayoutResource because there are no settings in the resource script file. All these settings are only provided programmatically in this case.

When controls have to move or resize completely (100%) across one or both axes, setting the right values for the layout is straight forward. It gets complicated though when controls are not positioned sideways or need to move or resize with more complicated rules. Let’s take an example where the OK and Cancel buttons are positioned at the bottom vertically and centered horizontally. When the dialog resizes they should retain the original size, but they should always remain at the center bottom.

dynlayout10 dynlayout11

In this case the Y ratio for move is again 100. But what is the move ratio on the X axis? To determine you need a paper and pen. Basically we need to find how much do the buttons move on X when the width increases by 100 units. That is the ratio we have to set.

Initially the dialog has 251 units, that means two halves of 125 and 126 units. We want to keep the buttons apart by 10 units. What means the OK button is left aligned at 70 units and the Cancel button is left alight at 130 units.
dynlayout12
Then we increase the size of the dialog by 100 units. It’s now 351 and the haves have 175 and 176. The buttons are still 10 units apart and their with is still 50 units each. That means the OK button is now left aligned at 120 units, and the Cancel button is left aligned at 180 units.
dynlayout13
The conclusion is their both left margin has moved 50 units, and that is the value we need to set for the X ratio of their move setting. (Remember, the value is a ratio, but 50 units out of 100 units is also 50%.)

What if the OK and Cancel buttons should both be aligned at the center of their each half on the X axis and always preserve the margins? In other words they should change like this:

dynlayout14 dynlayout15

In this example, initially, the dialog has 231 units and that means two halves of 115 and 116 units. The buttons have both 60 units width, so they are aligned at 27 or 28 units to the margins.
dynlayout16
When the width of the dialog increases by 100 units to 331 units, the two halves have 165 and 166 units. The buttons preserve their margins, so their new width is 110 units.
dynlayout17
(Notice that the image above is stretched and the margins may be misleading.)

The conclusion is that:

  • The OK button did not move horizontally, but it increased its width from 60 units to 110 units, that means 50%.
  • The Cancel button moved horizontally and is now left aligned at 193 units instead of the original 143 units. That means it moved by 50% horizontally. Its sized increased from 60 units to 110 units, that also means 50%.

With those values set the buttons are resized and positioned as intended.

For more information see MFC Dynamic Dialog Layout.

Demo source code:
MFC Dynamic Layout Management - demo 1 (1191)
MFC Dynamic Layout Management - demo 2 (1036)
MFC Dynamic Layout Management - demo 3 (879)

, , , Hits for this post: 21363 .

guidgen.exe is a small utility that comes with Visual Studio and generates GUIDs in a variety of formats. The problem with the tool is that it does not format GUIDs in plain text, which I happen to need many times (in source code, database tables, etc.) and I suppose is a feature needed by many developers. There are a couple of variants of the tool on Codeproject (GUIDGen Developer Studio AddIn and GUIDGen AddIn for Visual Studio.NET) but they lack some of the new formats supported by guidgen.

GUIDGEN.exe from Visual Studio

GUIDGEN.exe from Visual Studio does not have plain text formatting or case options.

Modified GUIDGEN has plain text formatting and case option but does not support all formats from Visual Studio’s GUIDGEN (i.e. C# and VB.NET Guid attribute format)

I have decided to create another modified version of GUIDGEN in order to support additional formats, including plain text, and also case options.

guidgen used to be available as an MFC sample, but that doesn’t seem to be the case any more. However, the sample from Visual Studio 2005 is still available on MSDN and I used that as a starting point. The result is a tool very similar to guidgen.exe from Visual Studio (2013 or 2015) but with additional features:

  • two more formats: __declspec(uuid("xxxxxxxx-xxxx...xxxx")) and plain text
  • case option: upper case (default) or lower case
guidgen2 guidgen3

The existing guidgen executable is available in the Common7\Tools folder of Visual Studio (i.e. c:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\ for Visual Studio 2013). You can replace that version with this build or put it somewhere else and keep it side by side by adding a new command from Tools > External tools. This might be more practical if you have several versions of Visual Studio installed.

guidgen-externaltools

Here are the downloads:
Guidgen-src (863) – Source code as Visual Studio 2013 solution
Guidgen-binaries (781) – Executables built with MFC as a shared library
Guidgen-mfcstaticlib-binary (851) – Executables built with MFC an a static library

, , , , , Hits for this post: 21383 .

If you’re a football fan you must have heard about the octopus called Paul that has predicted the outcome of all Germany’s matches at the World Cup 2010. She lives in the Sea Life Aquarium in the western city of Oberhausen. Before each match she was given two jars with a mussel and a national flag inside. And every time she picked the mussel from the jar with the flag of the correct winner. Yesterday she picked Spain over Germany.

Now, I want to make a prediction about her current and next predictions: she got the result of tonight’s match wrong, Germany will win. And then, she’ll have to chose between Netherlands and Germany and will pick the Netherlands. Now, the prediction is not that much about who wins (it doesn’t matter actually who wins), it’s about how Paul makes the picks.

How did I do this prediction? Well, I see patterns. 😉 And here is Paul’s prediction pattern. She is giving two jars, arranged by the teams order:
Germany – Australia
Germany – Serbia
Ghana – Germany
Germany – England
Argentina – Germany
Germany – Spain

She’s picking left, right, right, left, right, right. The next match will be between Netherlands and Germany and she will pick left, thus Netherlands.

Let’s see how good I am with predictions.

UPDATE: OK, psychic Paul was right once again. 😉 But I still predict that it will pick left, thus, Uruguay for Germany’s next match.

SECOND UPDATE: so Paul has picked Germany over Uruguay, and Spain over Netherlands. That completely ruins my prediction. 🙁

Hits for this post: 13691 .

The w3counter.com site published several statistics based on 33 milion unique visits to 5664 sites. The statistics refer to the operating system, web browser, country and screen resolution of the visitor. The king of kings of operating systems is Windows XP with 83,48%, followed by Windows 2000, Max OS X and Windows Vista. Linux and Windows 98 have both 1.34% percent. In terms of web broswers, the leader is IE 6 with 47.01%, followed IE7 with 19.19% and Firefox 2.0 with 17.51%.

You can see the whole charts here: http://www.w3counter.com/globalstats.php.

Hits for this post: 13716 .