{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "aa9d4f33-5bd8-42f2-918a-e654d4363577",
      "metadata": {},
      "source": [
        "<center>\n",
        "    <h1>C++ kernel based on xeus</h1>\n",
        "</center>\n",
        "\n",
        "A Jupyter kernel for C++ based on the `CppInterOp`, a clang based C++ Interoperability Library and the `xeus` native implementation of the Jupyter protocol, xeus.\n",
        "\n",
        "- GitHub repository: https://github.com/compiler-research/xeus-cpp\n",
        "- Documentation: https://xeus-cpp.readthedocs.io/en/latest/"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9af8aa44-7786-47b6-b94b-8579470acb3a",
      "metadata": {
        "jp-MarkdownHeadingCollapsed": true
      },
      "source": [
        "## Usage\n",
        "\n",
        "<div style=\"background: #efffed;\n",
        "            border: 1px solid grey;\n",
        "            margin: 8px 0 8px 0;\n",
        "            text-align: center;\n",
        "            padding: 8px; \">\n",
        "    <i class=\"fa-play fa\" \n",
        "       style=\"font-size: 40px;\n",
        "              line-height: 40px;\n",
        "              margin: 8px;\n",
        "              color: #444;\">\n",
        "    </i>\n",
        "    <div>\n",
        "    To run the selected code cell, hit <pre style=\"background: #efffed\">Shift + Enter</pre>\n",
        "    </div>\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "be1c8c6c-3fbe-4f53-9deb-8496c43d26ad",
      "metadata": {},
      "source": [
        "## Output and error streams\n",
        "\n",
        "`std::cout` and `std::cerr` are redirected to the notebook frontend."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "9bd7f767-6c22-4a1b-a1e2-cd4184fd0367",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "some output\n"
          ]
        }
      ],
      "source": [
        "#include <iostream>\n",
        "\n",
        "std::cout << \"some output\" << std::endl;"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "9622f20f-5925-4544-a97b-aada3a14209a",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "name": "stderr",
          "output_type": "stream",
          "text": [
            "some error\n"
          ]
        }
      ],
      "source": [
        "std::cerr << \"some error\" << std::endl;"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "c7dcdb89-6e0c-44a2-a968-d9fb9907deda",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Caught an exception: Unknown exception\n"
          ]
        }
      ],
      "source": [
        "#include <stdexcept>\n",
        "\n",
        "try {\n",
        "    throw std::runtime_error(\"Unknown exception\");\n",
        "}\n",
        "catch (const std::exception& e) {\n",
        "    std::cout << \"Caught an exception: \" << e.what() << std::endl;\n",
        "}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "7af0c962-17dc-47d4-9772-b8a06e2bda3a",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "5\n"
          ]
        }
      ],
      "source": [
        "int j = 5;\n",
        "std::cout << j << std::endl;"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a39c7021-ee9f-442e-8ea3-63ca23aa5d46",
      "metadata": {},
      "source": [
        "# Interpreting the C++ programming language\n",
        "# You can define functions, classes, templates, etc ..."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "e5b116ce-ced1-4aa4-b14e-ef7d2606202e",
      "metadata": {},
      "source": [
        "## Functions"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "86b08f22-e16c-4eac-917d-ae6eeb7ec7cb",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "double sqr(double a)\n",
        "{\n",
        "    return a * a;\n",
        "}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "5aff6711-54bf-4280-a496-c9f7c683eee5",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "6.25\n"
          ]
        }
      ],
      "source": [
        "double a = 2.5;\n",
        "double asqr = sqr(a);\n",
        "std::cout << asqr << std::endl;"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "5b3959b0-9dc7-41a4-bba1-e20abd0765f7",
      "metadata": {},
      "source": [
        "## Classes"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "d981a53b-8185-49c5-8a30-02453cc1b9e9",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "class Foo\n",
        "{\n",
        "public:\n",
        "\n",
        "    virtual ~Foo() {}\n",
        "\n",
        "    virtual void print(double value) const\n",
        "    {\n",
        "        std::cout << \"Foo value = \" << value << std::endl;\n",
        "    }\n",
        "};"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "id": "195d513f-d5cb-4e3d-a6cb-ae99dfcd9aab",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Foo value = 1.2\n"
          ]
        }
      ],
      "source": [
        "Foo bar;\n",
        "bar.print(1.2);"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "9ecc1588-cb6e-4676-bb16-b9938e980b06",
      "metadata": {},
      "source": [
        "## Polymorphism"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "id": "4df90bea-5c9e-462e-bd20-d80fd169b7b6",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "class Bar : public Foo\n",
        "{\n",
        "public:\n",
        "\n",
        "    virtual ~Bar() {}\n",
        "\n",
        "    virtual void print(double value) const\n",
        "    {\n",
        "        std::cout << \"Bar value = \" << 2 * value << std::endl;\n",
        "    }\n",
        "};"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "id": "f7dbbcc2-0f00-48eb-8bb9-94e871afa2a7",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Bar value = 2.4\n"
          ]
        }
      ],
      "source": [
        "Foo* bar2 = new Bar;\n",
        "bar2->print(1.2);\n",
        "delete bar2;"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "094f4ca7-0aa5-4121-bfff-bf5db1d42c5d",
      "metadata": {},
      "source": [
        "## Templates"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "id": "0df4f3a5-25a1-4548-ba63-54887c770dad",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "#include <typeinfo>\n",
        "\n",
        "template <class T>\n",
        "class FooT\n",
        "{\n",
        "public:\n",
        "\n",
        "    explicit FooT(const T& t) : m_t(t) {}\n",
        "\n",
        "    void print() const\n",
        "    {\n",
        "        std::cout << typeid(T).name() << \" m_t = \" << m_t << std::endl;\n",
        "    }\n",
        "\n",
        "private:\n",
        "\n",
        "    T m_t;\n",
        "};"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "id": "67181378-69d0-4adb-8a69-9abd20d3bc85",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "d m_t = 1.2\n"
          ]
        }
      ],
      "source": [
        "FooT<double> foot(1.2);\n",
        "foot.print();"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6ce20171-18cb-4373-874b-89e6a2d2e425",
      "metadata": {},
      "source": [
        "## Documentation\n",
        "\n",
        " - Documentation for types of the standard library is retrieved on cppreference.com."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "id": "c723686c-a70b-4e68-a175-b2224f0616aa",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<style>\n",
              "            #pager-container {\n",
              "                padding: 0;\n",
              "                margin: 0;\n",
              "                width: 100%;\n",
              "                height: 100%;\n",
              "            }\n",
              "            .xcpp-iframe-pager {\n",
              "                padding: 0;\n",
              "                margin: 0;\n",
              "                width: 100%;\n",
              "                height: 100%;\n",
              "                border: none;\n",
              "            }\n",
              "            </style>\n",
              "            <iframe class=\"xcpp-iframe-pager\" src=\"https://en.cppreference.com/w/cpp/container/vector?action=purge\"></iframe>"
            ],
            "text/plain": [
              "https://en.cppreference.com/w/cpp/container/vector"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "?std::vector"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "afee187b-2e6a-47db-acb1-8dab5a975565",
      "metadata": {},
      "source": [
        "## Using the display_data mechanism"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "55181b46-06b1-44ef-8a13-502b81bb3372",
      "metadata": {},
      "source": [
        "For a user-defined type `T`, the rich rendering in the notebook and JupyterLab can be enabled by by implementing the function `nl::json mime_bundle_repr(const T& im)`, which returns the JSON mime bundle for that type."
      ]
    },
    {
      "cell_type": "markdown",
      "id": "a887da0e-9635-40c2-88ed-84997f9658ca",
      "metadata": {},
      "source": [
        "### Image example"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "id": "362cc371-9fb7-4f2c-8824-f566498ae99b",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "#include <string>\n",
        "#include <fstream>\n",
        "#include <sstream>\n",
        "\n",
        "#include \"nlohmann/json.hpp\"\n",
        "\n",
        "#include \"xeus/xbase64.hpp\"\n",
        "\n",
        "namespace nl = nlohmann;\n",
        "\n",
        "namespace im\n",
        "{\n",
        "    struct image\n",
        "    {\n",
        "        inline image(const std::string& filename)\n",
        "        {\n",
        "            std::ifstream fin(filename, std::ios::binary);\n",
        "            m_buffer << fin.rdbuf();\n",
        "        }\n",
        "\n",
        "        std::stringstream m_buffer;\n",
        "    };\n",
        "\n",
        "    nl::json mime_bundle_repr(const image& i)\n",
        "    {\n",
        "        auto bundle = nl::json::object();\n",
        "        bundle[\"image/png\"] = xeus::base64encode(i.m_buffer.str());\n",
        "        return bundle;\n",
        "    }\n",
        "}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "id": "b326166f-1652-4cd5-bc8e-e4fa93f848a6",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "im::image marie(\"../data/marie.png\");"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "id": "c32f5494-00e8-4427-bf6a-ce20c31ab44e",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "#include \"xcpp/xdisplay.hpp\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "id": "fc494113-8283-4d27-93b1-055ce5ee8240",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "data": {
            "image/png": "[encoded data, 145252 characters]"
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "xcpp::display(marie);"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "b1c0a821-e794-4f31-a791-85536d997069",
      "metadata": {},
      "source": [
        "### Audio example"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "id": "c1fe251d-2155-47ea-abaa-0e0b9da9d70d",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "namespace nl = nlohmann;\n",
        "\n",
        "namespace au\n",
        "{\n",
        "    struct audio\n",
        "    {\n",
        "        inline audio(const std::string& filename)\n",
        "        {\n",
        "            std::ifstream fin(filename, std::ios::binary);\n",
        "            m_buffer << fin.rdbuf();\n",
        "        }\n",
        "\n",
        "        std::stringstream m_buffer;\n",
        "    };\n",
        "\n",
        "    nl::json mime_bundle_repr(const audio& a)\n",
        "    {\n",
        "        auto bundle = nl::json::object();\n",
        "        bundle[\"text/html\"] =\n",
        "           std::string(\"<audio controls=\\\"controls\\\"><source src=\\\"data:audio/wav;base64,\")\n",
        "           + xeus::base64encode(a.m_buffer.str()) +\n",
        "            \"\\\" type=\\\"audio/wav\\\" /></audio>\";\n",
        "        return bundle;\n",
        "    }\n",
        "}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "id": "0cc2ee8f-955e-459a-847f-1729ea961710",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "au::audio drums(\"../data/audio.wav\");"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "id": "e4de8992-2ffa-4493-8d86-f3738b1f8e97",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "<audio controls=\"controls\"><source src=\"data:audio/wav;base64,[encoded data, 684328 characters]\" type=\"audio/wav\" /></audio>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "xcpp::display(drums);"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f287b246-e1e2-4e5c-9167-89cd2b6b0de0",
      "metadata": {},
      "source": [
        "### Update-display"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 21,
      "id": "68f1b7e1-c357-4526-8ede-8edd9acad087",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "namespace nl = nlohmann;\n",
        "\n",
        "namespace ht\n",
        "{\n",
        "    struct html\n",
        "    {\n",
        "        inline html(const std::string& content)\n",
        "        {\n",
        "            m_content = content;\n",
        "        }\n",
        "        std::string m_content;\n",
        "    };\n",
        "\n",
        "    nl::json mime_bundle_repr(const html& a)\n",
        "    {\n",
        "        auto bundle = nl::json::object();\n",
        "        bundle[\"text/html\"] = a.m_content;\n",
        "        return bundle;\n",
        "    }\n",
        "}\n",
        "\n",
        "// A blue rectangle\n",
        "ht::html rect(R\"(\n",
        "<div style='\n",
        "    width: 90px;\n",
        "    height: 50px;\n",
        "    line-height: 50px;\n",
        "    background-color: blue;\n",
        "    color: white;\n",
        "    text-align: center;'>\n",
        "Original\n",
        "</div>)\");"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 22,
      "id": "104f5359-2518-4a4c-bb79-b5b52041d745",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "data": {
            "text/html": [
              "\n",
              "<div style='\n",
              "    width: 90px;\n",
              "    height: 50px;\n",
              "    line-height: 50px;\n",
              "    background-color: red;\n",
              "    color: white;\n",
              "    text-align: center;'>\n",
              "Updated\n",
              "</div>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "xcpp::display(rect, \"some_display_id\");"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 23,
      "id": "8f6ab60e-eabf-4ecc-b856-a3e7f6b165b9",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "// Update the rectangle to be red\n",
        "rect.m_content = R\"(\n",
        "<div style='\n",
        "    width: 90px;\n",
        "    height: 50px;\n",
        "    line-height: 50px;\n",
        "    background-color: red;\n",
        "    color: white;\n",
        "    text-align: center;'>\n",
        "Updated\n",
        "</div>)\";\n",
        "\n",
        "xcpp::display(rect, \"some_display_id\", true);"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "aa21443e-f927-4af1-b2ba-46ddd76dee65",
      "metadata": {},
      "source": [
        "### Clear output"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 24,
      "id": "25021165-8dfe-42ff-b6c4-383ad3c8822e",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "#include <chrono>\n",
        "#include <thread>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 25,
      "id": "7e05d371-633d-4419-95d1-29f77985859b",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "goodbye\n"
          ]
        }
      ],
      "source": [
        "std::cout << \"hello\" << std::endl;\n",
        "std::this_thread::sleep_for(std::chrono::seconds(1));\n",
        "xcpp::clear_output();  // will flicker when replacing \"hello\" with \"goodbye\"\n",
        "std::this_thread::sleep_for(std::chrono::seconds(1));\n",
        "std::cout << \"goodbye\" << std::endl;"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 26,
      "id": "101ce1e3-9875-49ab-bf9b-e4e69ad4bf68",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "goodbye\n"
          ]
        }
      ],
      "source": [
        "std::cout << \"hello\" << std::endl;\n",
        "std::this_thread::sleep_for(std::chrono::seconds(1));\n",
        "xcpp::clear_output(true);  // prevents flickering\n",
        "std::this_thread::sleep_for(std::chrono::seconds(1));\n",
        "std::cout << \"goodbye\" << std::endl;"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4e69d1e7-3a55-4f91-8b82-15056ec0173e",
      "metadata": {},
      "source": [
        "### SIMD Acceleration through WebAssembly Intrinsics\n",
        "\n",
        "Example inspired by https://emscripten.org/docs/porting/simd.html#webassembly-simd-intrinsics"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 27,
      "id": "7a8d42ee-79a6-4b5c-8d79-35d688e40c17",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "#include <wasm_simd128.h>\n",
        "#include <stdio.h>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 28,
      "id": "f6a65b84-ad63-455d-9704-a597b3b0f45c",
      "metadata": {
        "trusted": true
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "v3: [3.3, 7.7, 12.1, 16.5]\n"
          ]
        }
      ],
      "source": [
        "v128_t v1 = wasm_f32x4_make(1.2f, 3.4f, 5.6f, 7.8f);\n",
        "v128_t v2 = wasm_f32x4_make(2.1f, 4.3f, 6.5f, 8.7f);\n",
        "\n",
        "v128_t v3 = wasm_f32x4_add(v1, v2);\n",
        "\n",
        "printf(\"v3: [%.1f, %.1f, %.1f, %.1f]\\n\",\n",
        "    wasm_f32x4_extract_lane(v3, 0),\n",
        "    wasm_f32x4_extract_lane(v3, 1),\n",
        "    wasm_f32x4_extract_lane(v3, 2),\n",
        "    wasm_f32x4_extract_lane(v3, 3));"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "73aa865d-f643-4b72-9701-f6e312914690",
      "metadata": {},
      "source": [
        "# Taking input from the user"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "6efd2bbc-525a-4659-9431-aefc819e8cb7",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "std::string name;\n",
        "std::cin >> name;"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "8ec65830-4cb5-4d01-a860-f6c46ac4f60f",
      "metadata": {
        "trusted": true
      },
      "outputs": [],
      "source": [
        "std::cout << \"Your name is \" << name;"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "C++23",
      "language": "cpp",
      "name": "xcpp23"
    },
    "language_info": {
      "codemirror_mode": "text/x-c++src",
      "file_extension": ".cpp",
      "mimetype": "text/x-c++src",
      "name": "C++",
      "version": "23"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}