Blog Posts

Page 2

How to typed command line arguments in python

How to typed command line arguments in python

Creating tools with python is a common practice due to its ease of use and productivity. Now python already has good built-in support for parsing command-line arguments, but we can take it one step further.

Let’s take the following example where we would like to create a platform independent build script that should be able to accept the build type and an option to rebuild.

published on Mon, 22 Apr 2024

How to call a function of a file in python

How to call a function of a file in python

Take the following use case, where I have a script that I use in my Continues Integration (CI) pipeline and I would like to call a function in that file from the command-line with parameters.

The inspect module provides several useful functions to help get information about live objects such as modules, classes, methods, functions, tracebacks, frame objects, and code objects. For example, it can help you examine the contents of a class, retrieve the source code of a method, extract and format the argument list for a function, or get all the information you need to display a detailed traceback.

published on Fri, 17 Nov 2023

Practical cppstd 17 highlights by example

Practical cppstd 17 highlights by example

Language Features

Nested namespace definitions

namespace A::B::C {
   // ...
}

// Rather than:
namespace A {
    namespace B {
        namespace C {
            // ...
        }
    }
}

Structured bindings

#include <map>
#include <string>
#include <iostream>

struct Vector3
{
    float X;
    float Y;
    float Z;
};
using MappingPair = std::pair<int, std::string>;

int main()
{
    const auto [x, y, z] = Vector3{1.0f, 1.0f, 1.0f};
    std::map<int, std::string> mapping
    {
        {1, "one"},
        {2, "two"}
    };
    const auto [it, isInserted] = mapping.insert(MappingPair{3, "three"});
    std::cout << it->first << " " << it->second << "\n\n";

    for (const auto& [key, value] : mapping)
    {
        std::cout << key << " " << value << std::endl;
    }
}

Selection statements with initializer

{
  std::lock_guard<std::mutex> lk(mx);
  if (v.empty()) v.push_back(val);
}
// vs.
if (std::lock_guard<std::mutex> lk(mx); v.empty()) {
  v.push_back(val);
}

constexpr if

template <typename T>
constexpr bool isIntegral() {
  if constexpr (std::is_integral<T>::value) {
    return true;
  } else {
    return false;
  }
}
static_assert(isIntegral<int>() == true);
static_assert(isIntegral<char>() == true);
static_assert(isIntegral<double>() == false);
struct S {};
static_assert(isIntegral<S>() == false);

Class template argument deduction

auto pair = std::pair{1.0, "foo"}; // Deduces to std::pair<double, std::string>;

[[fallthrough]], [[nodiscard]], [[maybe_unused]] attributes

switch (n) {
  case 1: 
    // ...
    [[fallthrough]];
  case 2:
    // ...
    break;
  case 3:
    // ...
    [[fallthrough]];
  default:
    // ...
}
[[nodiscard]] bool do_something() {
  return is_success; // true for success, false for failure
}

do_something(); // warning: ignoring return value of 'bool do_something()',
                // declared with attribute 'nodiscard'
// Only issues a warning when `error_info` is returned by value.
struct [[nodiscard]] error_info {
  // ...
};

error_info do_something() {
  error_info ei;
  // ...
  return ei;
}

do_something(); // warning: ignoring returned value of type 'error_info',
                // declared with attribute 'nodiscard'
void my_callback(std::string msg, [[maybe_unused]] bool error) {
  // Don't care if `msg` is an error message, just log it.
  log(msg);
}

Library Features

std::variant

#include <variant>
#include <string>
#include <iostream>
#include <type_traits>

using SettingVarT = std::variant<int, std::string>;


class SettingVisitorWithClosure
{
public:
    SettingVisitorWithClosure(const std::string& str)
        : _str(str)
    {
    } 

    void operator()(int args)
    {
        std::cout << _str << " integer " << args << std::endl;
    }

    void operator()(std::string args)
    {
        std::cout << _str << " string " << args << std::endl;
    }

private:
    std::string _str = "Hello";
};

int main ()
{ 
    SettingVarT setting = 0;

    ////////////////////////////////////////////////////////////////////////////////
    // Lambda std::variant visitor without closure
    std::visit([](auto&& args)
    {
        using T = std::decay_t<decltype(args)>;

        if constexpr (std::is_same_v<T, int>)
        {
            std::cout << "integer " << args << std::endl;
        }
        if constexpr (std::is_same_v<T, std::string>)
        {
            std::cout << "string" << args << std::endl;
        }
    }, setting);

    ////////////////////////////////////////////////////////////////////////////////
    // Variant visitor with closure
    SettingVisitorWithClosure closure("Hello");
    std::visit(std::move(closure), setting);
}

std::optional

characteristics: value-type common use case: return value of a function that may fail.

published on Mon, 06 Mar 2023

Create an array of all possible variants alternatives of std::variant type

The standard library std::variant is a usefull feature, introduced since c++17, to define a type that can hold multiple alternative types.

For example a cell of a CSV file could represent multiple data types such as a string or int. Declaring a new type std::variant<std::string, int> allows to store one of the alternative types at the time. The std::variant internally allocates space for the largest alternative type.

But what if you need to extract what the possible alternatives of the std::variant ?

published on Thu, 02 Mar 2023

How to build Macos Universal Binaries with Conan and CMake

*** update (May 2025) ***

How to build Macos Universal Binaries with Conan and CMake

Universal Binaries contain native instructions for multiple target architectures like x86_64 and arm64 to run your app both on Intel Mac and Apple silicon machines. When using Conan there are a few common build systems, or native build tool generators, when creating packages from the Conan Center Index(CCI) like: CMake, Autotools, Pkgconfig, b2 (Boost Build) and Make. Some of these build tools have build-in support when it comes to building Universal Binaries.

published on Fri, 25 Nov 2022