Articles on software design and programming, C++ and language independent ideas.
I was asked recently a question about the template instance's parameters inspection possibilities in order to be able to stringify the types and integral constants used to create that instance. Namely, having a template with N parameters, and an instance (an object or just a type) of that template we would like to print the text representation of the parameters with which that instance was created. This article presents an example solution to that problem.
State is inevitable. Essential in practice, a side-effect, is a change applied to a shared global state. With the state up front, we make it easily trackable and visible in the data-flow diagrams. No more bad surprises after refactoring, at least in theory.
It is almost unbelievable how it is easy to commit a sin against simplicity. Consider a funcionality that converts some data type into an another one data type. All the information required to do a conversion is included in the original data type. How would you report errors if optional-way were banned?
Definition of actions is not a trivial task. The resulting abstraction that embeds the defined actions does not have to be a set of virtual member functions wrapped into a class from which implementations exposed to the user derive. General guideline promoted in this article is to expose non-virtual interfaces to the user while providing a customisation point in the form of a minimal set of actions that can be combined with each other.
Presentation of a generic approach to accessing and transforming nested data types using Profunctor Optics in C++17.
Embedding and recovering the type information by means of a value passed into a generic lambda expression.
(or Exercise in Monads) Building and executing a generic chain of functions that are not composable directly with the help of FunctionObject concept, C++17 abstractions, and functional programming idioms.
Presentation of a technique that enables transparent interception of the selected arguments passed to any function by means of a user-provided predicate metafunction. A proposal of an extension to C++17 std::invoke STL helper function — apply_if.
Synchronisation cost minimisation technique explained based on the classic producer-consumer problem. Keep the shared resource synchronised, but unblock the producer execution for the time of the buffer items' consumption to achieve significant gain in overall performance of the solution and its reliability.
Exploring execution of algorithms during explicit template instantiation. Example includes code that generates accessors that are able to mutate private members and call private member functions.
(or Automatic two-phase init) This article presents a solution that enables injection of a custom code to be executed once all the non-static members are initialised. Presented technique is particulary useful in case of constructor inheritance and use of "member initializer" feature.
Among all the various design patterns widely used by the C++ language community, probably only the visitor pattern takes advantage of the language type system in such a sophisticated way. Visitor pattern provides a solution to a recurring problem found in object-oriented designs (and in any other that use runtime-supported subtype polymorphism), namely the determination of the actual type of the object referenced by some interface type. This article will revisit the core idea behind that design pattern, mention couple of existing implementations, and describe a C++14 implementation of the visitor that aims to be flexible and type-safe as much as the template-based solution is, but remains in the domain of fixed (non-template) types favoured by the classic interfaces based on the virtual member functions.
Tweaking std::binary_search to return found item using custom comparator and ordering of intervals and points.
Enforcing stronger typing with couple of alternatives to bitmasks typically used by interfaces to select many properties at once.
Understanding concept requirements put on types by std::swap and taking benefit from std::refrence_wrapper class members.
How to encode assumptions into types and check them during compile time with no use of static_assert.
There examples of C++14 type inference failures and solutions to them.
Let's define an interface by using types and composition, where misuse is signalled by a compilation error.
A note on improving performance through wise usage of short circuiting, simple pattern matching engine with boolean operators and ternary operators.
Enabling iteration over a sequence of objects of given type without changing the type name itself. Plus, how to guarantee never-singular iterators and never-empty collections.
Well designed system is built up from multiple layers, where each layer may be complex piece of software. We will look into a single layer of the system to find out how to make it safe without sacrificing its performance.
Functions defines domain as a set of possible input values and co-domain as a set of possible output values. Let's find a way to assure we receive and reply with meaningful values. An example from production code.
Thoughts on designing software that is easy to test and benefits from dependency injection.
Plenty of software projects use source code generation to automate numerous tedious tasks. Let's have a look how to resolve code generation task in much cleaner way compared to what we find usually and make its results maintainable.