// etlProbe.cpp - exercise ETL: vector + string + map + optional + function.
//
//   $025010 = 0xBEEF  main entered
//   $025002 = sum of vector [1..5] = 15
//   $025004 = vector size = 5
//   $025006 = string size = 10 ("Hello, ETL")
//   $025010 = (already 0xBEEF) main entered
//   $025020 = map size after 3 inserts = 3
//   $025022 = map lookup map[2] = 200
//   $025030 = optional has_value() = 1 after assignment
//   $025032 = optional value = 0x4242
//   $025040 = function-wrapped lambda result = 42 * 2 = 84
//   $025008 = 0x900D  end reached
#include <stdint.h>
#include "etl/vector.h"
#include "etl/string.h"
#include "etl/map.h"
#include "etl/optional.h"
#include "etl/delegate.h"

static int doubler(int x) { return x * 2; }

int main(void) {
    *(volatile uint16_t *)0x025010UL = 0xBEEF;

    // vector
    etl::vector<int, 8> v;
    for (int i = 1; i <= 5; i++) v.push_back(i);
    int sum = 0;
    for (etl::vector<int, 8>::const_iterator it = v.begin(); it != v.end(); ++it) sum += *it;
    *(volatile uint16_t *)0x025002UL = (uint16_t)sum;
    *(volatile uint16_t *)0x025004UL = (uint16_t)v.size();

    // string
    etl::string<32> s("Hello, ");
    s += "ETL";
    *(volatile uint16_t *)0x025006UL = (uint16_t)s.size();

    // map
    etl::map<int, int, 8> m;
    m[1] = 100;
    m[2] = 200;
    m[3] = 300;
    *(volatile uint16_t *)0x025020UL = (uint16_t)m.size();
    *(volatile uint16_t *)0x025022UL = (uint16_t)m[2];

    // optional
    etl::optional<int> opt;
    opt = 0x4242;
    *(volatile uint16_t *)0x025030UL = (uint16_t)(opt.has_value() ? 1 : 0);
    *(volatile uint16_t *)0x025032UL = (uint16_t)opt.value();

    // function — type-erased callable, holding a free function pointer
    etl::delegate<int(int)> fn = etl::delegate<int(int)>::create<doubler>();
    *(volatile uint16_t *)0x025040UL = (uint16_t)fn(42);

    *(volatile uint16_t *)0x025008UL = 0x900D;
    return 0;
}
