diff --git a/code/bash/aliases.sh b/code/bash/aliases.sh
new file mode 100644
index 0000000000000000000000000000000000000000..8f43bb2af89cf68980fe21add1f1d3af7a2c94df
--- /dev/null
+++ b/code/bash/aliases.sh
@@ -0,0 +1,8 @@
+alias cf="clang-format --style=WebKit -i"
+alias C="clang++ -std=c++20 -stdlib=libc++ -Ofast"
+alias Cm="clang++ -std=c++20 -stdlib=libc++ -Ofast -fmodules -fimplicit-module-maps -fprebuilt-module-path=."
+alias Cixx="clang++ -std=c++20 -stdlib=libc++ -Ofast -fmodules -fimplicit-module-maps --precompile -xc++-module -fprebuilt-module-path=."
+alias G="g++ -std=c++20 -pedantic -Wall -O3"
+alias Gm="g++ -std=c++20 -fmodules-ts -pedantic -Wall -O3"
+alias Gh="g++ -std=c++20 -fmodules-ts -xc++-system-header -O3"
+
diff --git a/code/bash/pathutils.sh b/code/bash/pathutils.sh
new file mode 100644
index 0000000000000000000000000000000000000000..4922204faa3a8ee4bc7d6bbde943474f37cab622
--- /dev/null
+++ b/code/bash/pathutils.sh
@@ -0,0 +1,83 @@
+#!/bin/bash
+
+# ***********************************************
+#  Programming in C++
+#  08 -- 12 May 2023
+#  Jülich Supercomputing Centre
+# ***********************************************
+
+rmspecial() {
+    sed -e 's/[]\/()$*.^|[]/\\&/g' <<< "$1"
+}
+
+# Usage:
+# prepend_path NAME_OF_PATH_ENV_VAR LOCATION_TO_PREPEND
+prepend_path() {
+    local pathtochange prevpath
+    pathtochange=$1
+    prevpath=${!pathtochange}
+    if [ -d "$2" ]; then
+        [[ ":${prevpath}:" != *":$2:"* ]] && prevpath="$2:${prevpath}"
+    fi
+    eval "export ${pathtochange}=${prevpath}"
+}
+
+# Usage:
+# remove_path_element NAME_OF_PATH_ENV_VAR LOCATION_TO_REMOVE_FROM_IT
+remove_path_element() {
+    local pathtochange prevpath toremove
+    pathtochange=$1
+    prevpath=${!pathtochange}
+    toremove=$(rmspecial $2)
+    prevpath=$(eval "echo ${prevpath} | sed -e 's#$toremove:##'")
+    prevpath=$(eval "echo ${prevpath} | sed -e 's#:$toremove##'")
+    eval "export ${pathtochange}=${prevpath}"
+}
+
+# Usage:
+# pathadd /a/b/c/bin
+pathadd() {
+    prepend_path PATH $1
+}
+# Usage:
+# pathrm /a/b/c/bin
+pathrm() {
+    remove_path_element PATH $1
+}
+libpathadd() {
+    prepend_path LD_LIBRARY_PATH $1
+    prepend_path LD_RUN_PATH $1
+    prepend_path LIBRARY_PATH $1
+}
+libpathrm() {
+    remove_path_element LD_LIBRARY_PATH $1
+    remove_path_element LD_RUN_PATH $1
+    remove_path_element LIBRARY_PATH $1
+}
+
+incpathadd() {
+    prepend_path CPATH $1
+}
+incpathrm() {
+    remove_path_element CPATH $1
+}
+manpathadd() {
+    prepend_path MANPATH $1
+}
+manpathrm() {
+    remove_path_element MANPATH $1
+}
+cmpathadd() {
+    prepend_path CMAKE_PREFIX_PATH $1
+}
+cmpathrm() {
+    remove_path_element CMAKE_PREFIX_PATH $1
+}
+pypathadd() {
+    prepend_path PYTHONPATH $1
+}
+pycmpathrm() {
+    remove_path_element PYTHONPATH $1
+}
+
+
diff --git a/code/include/CountingIterator.hh b/code/include/CountingIterator.hh
new file mode 100644
index 0000000000000000000000000000000000000000..ab63f41b38f7bf846198805eb436a332f7dc9191
--- /dev/null
+++ b/code/include/CountingIterator.hh
@@ -0,0 +1,55 @@
+#pragma once
+#include <iterator>
+#include <type_traits>
+#include <concepts>
+
+template <std::integral T>
+struct CountingIterator {
+    using difference_type = std::make_signed_t<T>;
+    using value_type = T;
+    using pointer = T*;
+    using reference = T&;
+    using iterator_category = std::random_access_iterator_tag;
+
+    constexpr auto operator++() noexcept -> CountingIterator { return { ++val }; }
+    constexpr auto operator++(int) noexcept -> CountingIterator { return { val++ }; }
+    constexpr auto operator--() noexcept -> CountingIterator { return { --val }; }
+    constexpr auto operator--(int) noexcept -> CountingIterator { return { val-- }; }
+    constexpr auto operator+=(difference_type d)
+    {
+        val += d;
+        return *this;
+    }
+    constexpr auto operator-=(difference_type d)
+    {
+        val -= d;
+        return *this;
+    }
+    constexpr auto operator<(CountingIterator other) const noexcept -> bool { return val < other.val; }
+    constexpr auto operator==(CountingIterator other) const noexcept -> bool { return val == other.val; }
+    constexpr auto operator!=(CountingIterator other) const noexcept -> bool { return val != other.val; }
+    constexpr auto operator>(CountingIterator other) const noexcept -> bool { return val > other.val; }
+    constexpr auto operator<=(CountingIterator other) const noexcept -> bool { return val <= other.val; }
+    constexpr auto operator>=(CountingIterator other) const noexcept -> bool { return val >= other.val; }
+    constexpr auto operator*() const noexcept { return val; }
+    constexpr auto operator*() noexcept -> auto& { return val; }
+    constexpr auto operator->() noexcept -> auto* { return &val; }
+    constexpr auto operator-(CountingIterator other) const noexcept -> difference_type { return val - other.val; }
+    constexpr auto operator+(difference_type d) const noexcept -> CountingIterator { return { val + d }; }
+    constexpr auto operator[](size_t d) const noexcept { return val + d; }
+    T val {};
+};
+template <std::integral T>
+struct Sequence {
+    constexpr auto begin() const noexcept { return beg; }
+    constexpr auto end() const noexcept { return nde; }
+    using iterator = CountingIterator<T>;
+    iterator beg{};
+    iterator nde{std::numeric_limits<T>::max()};
+    Sequence(T b, T e) noexcept : beg{b}, nde{e} {}
+    explicit Sequence(T b) noexcept : beg{b} {}
+};
+
+template <std::integral T>
+constexpr auto algo_counter(T t) noexcept -> CountingIterator<T> { return {t}; }
+
diff --git a/code/include/FileAsLines.hh b/code/include/FileAsLines.hh
new file mode 100644
index 0000000000000000000000000000000000000000..73d5bb1e1d9584fbabd8a3731942cc133ab45e13
--- /dev/null
+++ b/code/include/FileAsLines.hh
@@ -0,0 +1,41 @@
+#pragma once
+#include <filesystem>
+#include <fstream>
+#include <string>
+#include <vector>
+
+class FileAsLines {
+public:
+    using iterator = std::vector<std::string>::iterator;
+    void read(std::filesystem::path nm)
+    {
+        std::ifstream fin { nm };
+        std::string line;
+        while (getline(fin, line))
+            mylines.push_back(line);
+    }
+    FileAsLines(std::filesystem::path nm) { read(nm); }
+    FileAsLines() = default;
+    FileAsLines(const FileAsLines&) = default;
+    FileAsLines(FileAsLines&&) = default;
+    FileAsLines& operator=(const FileAsLines&) = default;
+    FileAsLines& operator=(FileAsLines&&) = default;
+    ~FileAsLines() = default;
+    inline size_t size() const { return mylines.size(); }
+    inline bool empty() const { return mylines.empty(); }
+    inline const std::string& operator[](size_t i) const { return mylines[i]; }
+    inline std::string& operator[](size_t i) { return mylines[i]; }
+    inline const std::string& front() const { return mylines.front(); }
+    inline std::string& front() { return mylines.front(); }
+    inline const std::string& back() const { return mylines.back(); }
+    inline std::string& back() { return mylines.back(); }
+    inline decltype(auto) begin() { return mylines.begin(); }
+    inline decltype(auto) end() { return mylines.end(); }
+    inline decltype(auto) begin() const { return mylines.cbegin(); }
+    inline decltype(auto) end() const { return mylines.cend(); }
+
+private:
+    std::vector<std::string> mylines;
+};
+std::ostream& operator<<(std::ostream& os, const FileAsLines& lines);
+
diff --git a/code/include/Vbose.hh b/code/include/Vbose.hh
new file mode 100644
index 0000000000000000000000000000000000000000..d55244b79a3f69c423907f521e65453b80773324
--- /dev/null
+++ b/code/include/Vbose.hh
@@ -0,0 +1,76 @@
+#pragma once
+
+#include <iomanip>
+#include <iostream>
+#include <string>
+
+class Vbose {
+public:
+    Vbose()
+    {
+        std::cout << "Default constructor of object at " << ((size_t)this) << "\n";
+    }
+    inline auto getval() const { return nm; }
+    inline void setval(const std::string& nw) { nm = nw; }
+
+    Vbose(const Vbose& v)
+        : nm(v.nm)
+    {
+        std::cout << "Copy constructor of object at " << ((size_t)this) << ". ";
+        std::cout << "Source for copy is at " << ((size_t)&v) << "\n";
+    }
+    Vbose(Vbose&& v) noexcept
+        : nm(std::move(v.nm))
+    {
+        std::cout << "Move constructor of object at " << ((size_t)this) << ". ";
+        std::cout << "Source for move is at " << ((size_t)&v) << "\n";
+    }
+
+    Vbose(std::string gs) noexcept
+        : nm(gs)
+    {
+        std::cout << "Constructor of object at " << ((size_t)this) << ",";
+        std::cout << " using string " << std::quoted(gs) << "\n";
+    }
+
+    auto operator=(const Vbose& v) -> Vbose&
+    {
+        std::cout << "Assignment operator: LHS @ " << ((size_t)this) << "(" << nm << "), ";
+        std::cout << "RHS @ " << ((size_t)&v) << "(" << std::quoted(v.nm) << ")\n";
+        if (this != &v) {
+            nm = v.nm;
+        }
+        return *this;
+    }
+
+    auto operator=(Vbose&& v) -> Vbose&
+    {
+        std::cout << "Move assignment operator: LHS @ " << ((size_t)this) << "(" << std::quoted(nm) << "), ";
+        std::cout << "RHS @ " << ((size_t)&v) << "(" << std::quoted(v.nm) << ")\n";
+        std::swap(nm, v.nm);
+        return *this;
+    }
+
+    ~Vbose()
+    {
+        std::cout << "Destructor of object at " << ((size_t)this) << " with data " << std::quoted(nm) << "\n";
+    }
+
+    auto operator+(const Vbose& v) -> Vbose
+    {
+        std::cout << "Inside operator + ()\n";
+        return {nm + "+" + v.nm};
+    }
+    auto value() const noexcept -> std::string
+    {
+	return nm;
+    }
+    void value(const std::string& vl)
+    {
+	std::cout << "Changing internal value of object at " << ((size_t)this) << " from " << nm << " to " << vl << "\n";
+	nm = vl;
+    }
+
+private:
+    std::string nm { "Uninitialized" };
+};
diff --git a/code/include/binform17.hh b/code/include/binform17.hh
new file mode 100644
index 0000000000000000000000000000000000000000..d52ff9f5c779014322002c6b7eb1cba409469a76
--- /dev/null
+++ b/code/include/binform17.hh
@@ -0,0 +1,49 @@
+#include <iostream>
+#include <bitset>
+#include <cstddef>
+#include <iomanip>
+
+namespace cxx2022 {
+using byte = unsigned char;
+ 
+template <class T>
+auto bits(T var)
+{
+    std::remove_cv_t<std::remove_reference_t<T>> loc{var};
+    unsigned long bytes{0UL};
+    byte* in = reinterpret_cast<byte *>(&loc);
+    byte* out = reinterpret_cast<byte *>(&bytes);
+    std::copy(in, in + sizeof(loc), out);
+    return std::bitset<8*sizeof(decltype(loc))>(bytes) ;
+}
+
+void showbits(double var)
+{
+    std::cout << "bits for double value " << var << "\n";
+    auto b = bits(var).to_string();
+    std::cout << "raw = " << b << "\n";
+    std::cout << "sign  exponent          mantissa\n" 
+              << std::setw(6) << std::left << b[0]
+              << std::setw(16) << std::left << b.substr(1UL, 11) 
+              << "  " << b.substr(12) << "\n\n";
+}
+
+void showbits(float var)
+{
+    std::cout << "bits for float value " << var << "\n";
+    auto b = bits(var).to_string();
+    std::cout << "raw = " << b << "\n";
+    std::cout << "sign  exponent          mantissa\n" 
+              << std::setw(6) << std::left << b[0]
+              << std::setw(16) << std::left << b.substr(1UL, 8) 
+              << "  " << b.substr(9) << "\n\n";
+}
+
+template <class T>
+void showbits(T var)
+{
+    std::cout << "bits for " << var << " with non-floating point type : " << bits(var) << "\n";
+}
+
+}
+
diff --git a/code/include/cxx20format b/code/include/cxx20format
new file mode 100644
index 0000000000000000000000000000000000000000..029ba91ad96ca7e8fe11eba5d4545f3185f8f57d
--- /dev/null
+++ b/code/include/cxx20format
@@ -0,0 +1,12 @@
+#include <version>
+#ifdef __cpp_lib_format
+  #include<format>
+  using std::format;
+#elif __has_include (<fmt/format.h>)
+  #define FMT_HEADER_ONLY
+  #include<fmt/core.h>
+  #include<fmt/format.h>
+  using fmt::format;
+  #warning Using external format.h header from the fmt library.
+#endif
+
diff --git a/code/include/cxx20ranges b/code/include/cxx20ranges
new file mode 100644
index 0000000000000000000000000000000000000000..989fe0678f4f85bb3e84064d75710094316f92fc
--- /dev/null
+++ b/code/include/cxx20ranges
@@ -0,0 +1,14 @@
+#include <version>
+#ifdef __cpp_lib_ranges
+  #include<ranges>
+  namespace sr = std::ranges;
+  namespace sv = std::views;
+#elif __has_include (<range/v3/all.hpp>)
+  #include<range/v3/all.hpp>
+  namespace sr = ranges;
+  namespace sv = ranges::views;
+  #warning Using rangesv3 3rd party library
+#else
+#error No suitable header for C++20 ranges was found!
+#endif
+
diff --git a/code/include/print_tuple.hh b/code/include/print_tuple.hh
new file mode 100644
index 0000000000000000000000000000000000000000..7ea143f130ef4df6ff44b98a06b99cf54eb0130b
--- /dev/null
+++ b/code/include/print_tuple.hh
@@ -0,0 +1,26 @@
+#pragma once
+#include <tuple>
+#include <iostream>
+#include <iomanip>
+
+template <class ... Args>
+std::ostream & operator<<(std::ostream & strm, const std::tuple<Args...> & t)
+{
+    using namespace std;
+    auto print_one = [&strm](const auto & onearg) -> ostream & {
+        using bare_type = remove_cv_t<remove_reference_t<decltype(onearg)>>;
+        if constexpr (is_same_v<bare_type, string>)
+            strm << quoted(onearg);
+        else
+            strm << onearg;
+        return strm;
+    };
+    auto print_components = [&](const auto & ... args){
+       ((print_one(args) << ", "), ...);
+    };
+    strm << "[";
+    apply(print_components, t);
+    return strm <<"]";
+}
+
+
diff --git a/code/include/range_output.hh b/code/include/range_output.hh
new file mode 100644
index 0000000000000000000000000000000000000000..65508ea662b844944d0a06891f8e2b3a1832359c
--- /dev/null
+++ b/code/include/range_output.hh
@@ -0,0 +1,113 @@
+#pragma once
+#include <algorithm>
+#include <iomanip>
+#include <iosfwd>
+#include <cxx20ranges>
+#include <string>
+
+namespace output {
+template <class C>
+concept RawArray = std::is_array_v<C>;
+template <class C>
+concept ArrayClass = requires(C c)
+{
+    { c[1ul] };
+    { c.size() };
+};
+
+template <class C>
+concept StringLike = std::convertible_to<C, std::string_view>;
+
+namespace {
+    //auto size(const Container auto& C) { return C.size(); }
+    auto size(const RawArray auto& C) { return std::extent_v<std::remove_cvref_t<decltype(C)>>; }
+}
+
+template <class C>
+concept ArrayLike = (not StringLike<C>)and(ArrayClass<C> or RawArray<C>);
+
+template <class T>
+void write_possibly_quoted(std::ostream& os, T&& t)
+{
+    if constexpr (StringLike<T>) {
+        os << std::quoted(t);
+    } else {
+        os << t;
+    }
+}
+
+std::ostream& operator<<(std::ostream& os, const ArrayLike auto& c)
+{
+    os << "[";
+    auto sz = size(c);
+    for (size_t i {}; i != sz; ++i) {
+        write_possibly_quoted(os, c[i]);
+        if (i + 1 < sz)
+            os << ", ";
+    }
+    return os << "]";
+}
+
+template <class T>
+requires(not StringLike<T> and sr::range<T>)
+    std::ostream&
+    operator<<(std::ostream& os, T&& r)
+{
+    os << "[";
+    for (auto el : r) {
+        write_possibly_quoted(os, el);
+        os << ", ";
+    }
+    return os << "]";
+}
+template <class SepType>
+class rprinter {
+    std::ostream* strmptr = nullptr;
+    SepType sep;
+
+public:
+    rprinter(SepType s)
+        : sep { s }
+    {
+    }
+    rprinter(const rprinter&) noexcept = default;
+    std::ostream& stream() { return *strmptr; }
+    void stream(std::ostream& os) { strmptr = &os; }
+    const auto& separator() const noexcept { return sep; }
+};
+template <>
+class rprinter<void> {
+    std::ostream* strmptr = nullptr;
+
+public:
+    std::ostream& stream() { return *strmptr; }
+    void stream(std::ostream& os) { strmptr = &os; }
+};
+
+template <class T>
+rprinter<T> operator<<(std::ostream& os, rprinter<T> r)
+{
+    r.stream(os);
+    return { r };
+}
+template <class T>
+std::ostream& operator<<(rprinter<T> vp, sr::range auto&& t)
+{
+    if constexpr (std::is_same_v<T, void>) {
+        for (auto&& el : t)
+            vp.stream() << el;
+    } else {
+        if (not sr::empty(t)) {
+            vp.stream() << *sr::begin(t);
+            sr::for_each(t | sv::drop(1), [&vp](auto&& el) {
+                vp.stream() << vp.separator() << el;
+            });
+        }
+    }
+    return vp.stream();
+}
+
+inline rprinter<void> unseparated;
+inline rprinter<const char*> comma_separated { ", " };
+
+}
diff --git a/code/include/timeit.hh b/code/include/timeit.hh
new file mode 100644
index 0000000000000000000000000000000000000000..6201609dcac252bd91782db45d7cff7335630754
--- /dev/null
+++ b/code/include/timeit.hh
@@ -0,0 +1,65 @@
+#pragma once
+
+#include <chrono>
+#include <cmath>
+#include <iostream>
+#include <string_view>
+
+template <typename Callable, typename... Args>
+void timeit(std::string_view testname, unsigned reps, Callable&& f, Args&&... args)
+{
+    using namespace std::chrono;
+    double tmin {}, tmax {}, ttot {}, t2tot {};
+    for (auto i = 0u; i < reps; ++i) {
+        auto start = high_resolution_clock::now();
+        std::forward<Callable>(f)(std::forward<Args>(args)...);
+        auto end = high_resolution_clock::now();
+        auto intv = duration<double>(end - start).count();
+        if (i == 0u) {
+            tmin = tmax = intv;
+        } else {
+            tmax = std::max(tmax, intv);
+            tmin = std::min(tmin, intv);
+        }
+        ttot += intv;
+        t2tot += (intv * intv);
+    }
+    enum class TUnit { sec,
+        msec,
+        usec,
+        nsec };
+    TUnit u = TUnit::sec;
+    if (tmin < 1.0)
+        u = TUnit::msec;
+    if (tmin < 1.e-3)
+        u = TUnit::usec;
+    if (tmin < 1.e-6)
+        u = TUnit::nsec;
+    double tmean = ttot / reps;
+    double t2mean = t2tot / reps;
+    double tstdv = sqrt(t2mean - tmean * tmean);
+    std::string unitstring { " seconds" };
+    double conv { 1.0 };
+    switch (u) {
+    case TUnit::msec:
+        unitstring = " milliseconds";
+        conv = 1000.0;
+        break;
+    case TUnit::usec:
+        unitstring = " microseconds";
+        conv = 1000000.0;
+        break;
+    case TUnit::nsec:
+        unitstring = " nanoseconds";
+        conv = 1000000000.0;
+        break;
+    case TUnit::sec:
+    default:
+        break;
+    };
+    std::cout << "Timing results for " << testname << " from " << reps << " repeatitions...\n";
+    std::cout << "Mean = " << tmean * conv << unitstring << "\n";
+    std::cout << "Std. dev = " << tstdv * conv << unitstring << "\n";
+    std::cout << "Minimum = " << tmin * conv << unitstring << "\n";
+    std::cout << "Maximum = " << tmax * conv << unitstring << "\n";
+}