ForEach Methods Implementation for Multidimensional Array in C#

I am working with System.Array and I found that the input parameter of ForEach method public static void ForEach<T>(T() array, Action<T> action); is specified on one dimensional array case. I am trying to generalize this to multidimensional array.

The experimental implementation

Here’s the experimental implementation of generalized ForEach method.

class ArrayHelpers
{
    public static void ForEach<T>(Array array, in Action<T> action)
        where T : unmanaged
    {
        if (ReferenceEquals(array, null))
        {
            throw new ArgumentNullException(nameof(array));
        }

        if (ReferenceEquals(action, null))
        {
            throw new ArgumentNullException(nameof(action));
        }

        foreach (T item in array)
        {
            action.Invoke(item);
        }
        return;
    }
}

Test cases

The Test cases for one dimensional case, two dimensional case and three dimensional case are as below.

//    One dimensional case
Console.WriteLine("One dimensional case");
int() test = new int() { 1, 2, 3, 4 };
ArrayHelpers.ForEach<int>(test, ShowSquares);

//    two dimensional case
Console.WriteLine("Two dimensional case");
int(,) test2 = { { 0, 1 }, { 2, 3 } };
ArrayHelpers.ForEach<int>(test2, ShowSquares);

//    three dimensional case
Console.WriteLine("Three dimensional case");
int(,,) test3 = { { { 0, 1 }, { 2, 3 } }, { { 0, 1 }, { 2, 3 } } };
ArrayHelpers.ForEach<int>(test3, ShowSquares);

/// <summary>
/// Reference: https://docs.microsoft.com/en-us/dotnet/api/system.array.foreach?view=net-5.0
/// </summary>
/// <param name="val">The input value for displaying and calculating square result</param>
private static void ShowSquares(int val)
{
    Console.WriteLine("{0:d} squared = {1:d}", val, val * val);
}

The output of the above tests:

One dimensional case
1 squared = 1
2 squared = 4
3 squared = 9
4 squared = 16
Two dimensional case
0 squared = 0
1 squared = 1
2 squared = 4
3 squared = 9
Three dimensional case
0 squared = 0
1 squared = 1
2 squared = 4
3 squared = 9
0 squared = 0
1 squared = 1
2 squared = 4
3 squared = 9

I am wondering the things about the potential drawback or risks of this implementation.

All suggestions are welcome.

beginner – dynamic queue implementation in C++

Hello everyone I’ve implemented a dynamic queue along side with a randkm access iterator, can I get a review ? And thanks in advance.

iterator:

#pragma once
#include <iterator>

namespace con {
template <class T> class rnd_iterator {
  T *m_Ptr;

public:
  /*
   * type aliases
   */
  using value_type = T;
  using iterator_type = rnd_iterator<value_type>;
  using iterator_category = std::random_access_iterator_tag;
  using pointer = value_type *;
  using const_pointer = const pointer;
  using difference_type = std::ptrdiff_t;
  using reference = value_type &;
  using const_reference = const value_type &;
  /*
   * constructors
   */
  rnd_iterator(const rnd_iterator<T> &other) noexcept : m_Ptr(other.m_Ptr) {}
  rnd_iterator(T *p) noexcept : m_Ptr(p) {}
  /*
   * access operators
   */
  reference operator*() { return *m_Ptr; }
  reference operator()(std::size_t idx) { return m_Ptr(idx); }
  pointer operator->() { return m_Ptr; }
  /*
   * increment/decrement and assign operators
   */
  rnd_iterator &operator=(pointer oth) {
    m_Ptr = oth;
    return *this;
  }
  rnd_iterator &operator+=(pointer oth) {
    m_Ptr += oth;
    return *this;
  }
  rnd_iterator &operator-=(pointer oth) {
    m_Ptr -= oth;
    return *this;
  }
  iterator_type &operator=(const iterator_type &rhs) {
    m_Ptr = rhs.m_Ptr;
    return *this;
  }
  friend iterator_type &operator+=(const iterator_type &lhs,
                                   const iterator_type &rhs) {
    lhs.m_Ptr += rhs.m_Ptr;
    return lhs;
  }
  friend iterator_type &operator-=(const iterator_type &lhs,
                                   const iterator_type &rhs) {
    lhs.m_Ptr -= rhs.m_Ptr;
    return lhs;
  }
  rnd_iterator operator++() {
    ++m_Ptr;
    return *this;
  }
  rnd_iterator operator++(int) {
    auto temp = *this;
    m_Ptr++;
    return temp;
  }
  rnd_iterator &operator--() {
    --m_Ptr;
    return *this;
  }
  rnd_iterator operator--(int) {
    auto temp = *this;
    m_Ptr--;
    return temp;
  }
  /*
   * comparison operators
   */
  friend bool operator!=(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr != rhs.m_Ptr;
  }
  friend bool operator!=(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr != rhs;
  }
  friend bool operator==(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr == rhs.m_Ptr;
  }
  friend bool operator==(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr == rhs;
  }
  friend bool operator<(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr < rhs.m_Ptr;
  }
  friend bool operator<(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr < rhs;
  }
  friend bool operator<=(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr <= rhs.m_Ptr;
  }
  friend bool operator<=(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr <= rhs;
  }
  friend bool operator>(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr > rhs.m_Ptr;
  }
  friend bool operator>(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr > rhs;
  }
  friend bool operator>=(const iterator_type &lhs, const iterator_type &rhs) {
    return lhs.m_Ptr >= rhs.m_Ptr;
  }
  friend bool operator>=(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr >= rhs;
  }
  friend difference_type operator+(const iterator_type &lhs,
                                   const iterator_type &rhs) {
    return lhs.m_Ptr + rhs.m_Ptr;
  }
  friend difference_type operator+(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr + rhs;
  }
  friend iterator_type operator+(const iterator_type &lhs,
                                 difference_type rhs) {
    return lhs.m_Ptr + rhs;
  }
  friend difference_type operator-(const iterator_type &lhs,
                                   const iterator_type &rhs) {
    return lhs.m_Ptr - rhs.m_Ptr;
  }
  friend iterator_type operator-(const iterator_type &lhs,
                                 difference_type rhs) {
    return lhs.m_Ptr - rhs;
  }
  friend difference_type operator-(const iterator_type &lhs, pointer rhs) {
    return lhs.m_Ptr - rhs;
  }
};
}

queue:

#pragma once
#include "iterator.hpp"
#include <algorithm>
#include <cassert>
#include <initializer_list>
#include <iostream>
#include <iterator>
#include <limits>
#include <memory>
#include <type_traits>
#include <utility>

namespace con {
template <class T, class Allocator = std::allocator<T>> class queue {
  Allocator m_Alloc;
  std::size_t m_Size, m_Capacity;
  std::allocator_traits<Allocator> m_AllocTraits;
  T *m_RawData;
  void m_ReallocAnyway(std::size_t t_NewCapacity) {
    std::size_t f_old = m_Capacity;
    T *f_temp = m_Alloc.allocate(sizeof(T) * t_NewCapacity);
    try {
      for (std::size_t i = 0; i < m_Size; i++) {
        new (&f_temp(i)) T(std::move_if_noexcept(m_RawData(i)));
        m_AllocTraits.destroy(m_Alloc, std::addressof(m_RawData(i)));
      }
      m_Alloc.deallocate(m_RawData, f_old);
      m_RawData = f_temp;
    } catch (const std::exception &exc) {
      m_Alloc.deallocate(f_temp, sizeof(T) * t_NewCapacity);
      throw std::move(exc);
    }
  }
  void m_Realloc(std::size_t t_NewCapacity) {
    if (t_NewCapacity > m_Capacity) {
      m_ReallocAnyway(t_NewCapacity);
    } else {
      return;
    }
  }
  void m_ShiftToLeft() {
    for (std::size_t i = 0; i < m_Size; i++) {
      new (&m_RawData(i)) T(std::move_if_noexcept(m_RawData(i + 1)));
    }
  }
  template <class F>
  void m_ShiftFromTo(std::size_t from, std::size_t to, F &&func) {
    for (; from < to; from++) {
      new (&m_RawData(from))
          T(std::move_if_noexcept(m_RawData(func(from, to))));
    }
  }
  template <class It> void m_ShiftRangeFromTo(It from, It to) {
    for (; from != to; from++) {
      new (std::addressof(*from))
          T(std::move_if_noexcept(*(from + (to - from))));
    }
  }
  template <class Iter> void m_DestroyRange(Iter beg, Iter end) {
    for (; beg != end; beg++) {
      m_AllocTraits.destroy(m_Alloc, std::addressof(*beg));
    }
  }
  void m_CheckOrAlloc(std::size_t t_Size) {
    if (t_Size >= m_Capacity) {
      m_Realloc(m_Capacity * 2);
    }
  }

public:
  using value_type = T;
  using allocator_type = Allocator;
  using size_type = decltype(m_Size);
  using difference_type = std::ptrdiff_t;
  using reference = value_type &;
  using const_reference = const value_type &;
  using pointer = typename std::allocator_traits<Allocator>::pointer;
  using const_pointer =
      typename std::allocator_traits<Allocator>::const_pointer;
  using iterator = con::rnd_iterator<value_type>;
  using const_iterator = const iterator;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

  explicit queue(size_type cap = (sizeof(value_type) * 5),
                 const Allocator &alloc = Allocator{}) noexcept
      : m_Alloc(alloc), m_Size(0), m_Capacity(cap),
        m_RawData(m_Alloc.allocate(m_Capacity)) {}
  explicit queue(const std::initializer_list<T> &init,
                 const Allocator &alloc = Allocator{}) noexcept
      : m_Alloc(alloc), m_Size(init.size()), m_Capacity(sizeof(value_type) * 5),
        m_RawData(m_Alloc.allocate(m_Capacity)) {
    m_Size = init.size();
    m_CheckOrAlloc(m_Size);
    std::uninitialized_copy(init.begin(), init.end(), m_RawData);
  }
  explicit queue(const queue<value_type> &oth) : queue() {
    if (std::is_destructible<value_type>::value)
      clear();
    m_Size = oth.size();
    m_CheckOrAlloc(m_Size);
    std::uninitialized_copy(oth.begin(), oth.end(), m_RawData);
  }
  explicit queue(queue<value_type> &&oth) noexcept : queue() {
    if (std::is_destructible<value_type>::value)
      clear();
    m_Size = oth.size();
    m_CheckOrAlloc(m_Size);
    std::uninitialized_move(oth.begin(), oth.end(), m_RawData);
  }
  template <class It> queue(It begin, It end) noexcept : queue() {
    assert(begin <= end);
    size_type f_size = std::distance(begin, end);
    m_CheckOrAlloc(f_size);
    m_Size = f_size;
    std::uninitialized_copy(begin, end, m_RawData);
  }
  explicit queue(const queue<value_type> &&oth) = delete;
  iterator begin() noexcept { return iterator(m_RawData); }
  iterator end() noexcept { return iterator(m_RawData + size()); }
  reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
  reverse_iterator rend() noexcept { return reverse_iterator(begin()); }

  const_iterator begin() const noexcept { return const_iterator(m_RawData); }
  const_iterator end() const noexcept {
    return const_iterator(m_RawData + size());
  }
  const_reverse_iterator rbegin() const noexcept {
    return const_reverse_iterator(m_RawData + size());
  }
  const_reverse_iterator rend() const noexcept {
    return const_reverse_iterator(m_RawData);
  }

  const_iterator cbegin() const noexcept { return const_iterator(m_RawData); }
  const_iterator cend() const noexcept {
    return const_iterator(m_RawData + size());
  }
  const_reverse_iterator crbegin() const noexcept { return rbegin(); }
  const_reverse_iterator crend() const noexcept { rend(); }

  bool empty() const noexcept { return size() == 0; }
  size_type size() const noexcept { return m_Size; }
  size_type capacity() const noexcept { return m_Capacity; }
  size_type max_capacity() const noexcept {
    return std::numeric_limits<size_type>::max();
  }
  const_pointer data() const { return m_RawData; }
  void clear() requires(std::is_destructible<value_type>::value) {
    for (size_type i = 0; i < size(); i++) {
      m_AllocTraits.destroy(m_Alloc, std::addressof(m_RawData(i)));
    }
    m_Size = 0;
  }
  void reserve(size_type cp) { m_CheckOrAlloc(cp); }
  void resize(size_type sz) {
    m_Size = sz;
    m_CheckOrAlloc(sz);
  }
  void erase(iterator val) {
    if (val != end()) {
      difference_type x = val - begin();
      pointer p = m_RawData + x;
      m_AllocTraits.destroy(m_Alloc, std::addressof(*val));
      m_ShiftFromTo(std::distance(begin(), iterator(p)), size(),
                    ()(auto l, ((maybe_unused)) auto _) { return l + 1; });
      m_Size--;
    } else {
      return;
    }
  }
  void erase(iterator first, iterator last) {
    assert(first <= last && "queue::erase invalid range");
    m_DestroyRange(first, last);
    m_ShiftRangeFromTo(first, last);
    m_Size -= std::distance(first, last);
  }
  void erase(reverse_iterator first, reverse_iterator last) {
    assert(first <= last && "queue::erase invalid range");
    m_DestroyRange(first, last);
    m_ShiftRangeFromTo(first, last);
    m_Size -= std::distance(first, last);
  }
  void erase(reverse_iterator val) {
    if (val != rend()) {
      m_AllocTraits.destroy(m_Alloc, std::addressof(*val));
      m_ShiftFromTo(std::distance(val, rend()) - 1, size(),
                    ()(auto l, ((maybe_unused)) auto _) { return l + 1; });
      m_Size--;
    } else {
      return;
    }
  }
  void erase(const value_type &obj) { erase(std::find(begin(), end(), obj)); }
  void rerase(const value_type &obj) {
    erase(std::find(rbegin(), rend(), obj));
  }
  iterator find(const value_type &obj) {
    return std::find(begin(), end(), obj);
  }
  reverse_iterator rfind(const value_type &obj) {
    return std::find(rbegin(), rend(), obj);
  }
  const_iterator find(const_reference obj) const {
    return std::find(begin(), end(), obj);
  }
  const_reverse_iterator rfind(const value_type &obj) const {
    return std::find(rbegin(), rend(), obj);
  }

  void enqueue(const value_type &oth) requires(
      std::is_copy_constructible<value_type>::value) {
    m_CheckOrAlloc(size());
    new (&m_RawData(m_Size++)) value_type(oth);
  }
  void enqueue(value_type &&oth) requires(
      std::is_move_constructible<value_type>::value) {
    m_CheckOrAlloc(size());
    new (&m_RawData(m_Size++)) value_type(std::move(oth));
  }
  ((nodiscard)) value_type
  dequeue() requires(std::is_destructible<value_type>::value) {
    --m_Size;
    value_type temp = m_RawData(0);
    m_AllocTraits.destory(m_Alloc, std::addressof(m_RawData(0)));
    m_ShiftToLeft();
    return temp;
  }
  template <class... Args> void emplace(Args &&...args) {
    enqueue(value_type(std::forward<Args>(args)...));
  }
  value_type at(size_type index) const {
    if (index >= size()) {
      throw std::range_error("out of bounds queue"); // yes helpful error
    } else {
      return m_RawData(index);
    }
  }
  reference at(size_type index) {
    if (index >= size()) {
      throw std::range_error("out of bounds queue"); // yes helpful error
    } else {
      return m_RawData(index);
    }
  }
  value_type operator()(size_type index) const { return m_RawData(index); }
  reference operator()(size_type index) { return m_RawData(index); }

  queue<value_type> &operator=(const queue<value_type> &oth) {
    if (&oth != this) {
      clear();
      m_Size = oth.size();
      m_CheckOrAlloc(m_Size);
      std::uninitialized_copy(oth.begin(), oth.end(), m_RawData);
    }
    return *this;
  }
  queue<value_type> &operator=(queue<value_type> &&oth) {
    if (&oth != this) {
      clear();
      m_Size = oth.size();
      m_CheckOrAlloc(m_Size);
      std::uninitialized_move(oth.begin(), oth.end(), m_RawData);
      oth.~queue();
    }
    return *this;
  }
  queue<value_type> &operator=(const queue<value_type> &&oth) = delete;
  ~queue() {
    m_Alloc.deallocate(m_RawData, m_Capacity);
    std::exchange(m_RawData, nullptr);
    std::exchange(m_Size, 0);
  }
  ~queue() requires(std::is_destructible<value_type>::value) {
    clear();
    m_Alloc.deallocate(m_RawData, m_Capacity);
    std::exchange(m_RawData, nullptr);
    std::exchange(m_Size, 0);
  }
};
}
```

asynchronous – Asynchronously Iterable Queue Implementation for JavaScript

While studying Deno which is a kind of Node with everything normalized to modern JS and TS, I quickly met the;

import { serve } from "https://deno.land/std@0.87.0/http/server.ts";

const server = serve({ hostname: "0.0.0.0", port: 8080 });

for await (const request of server) {
  request.respond({ status: 200, body: "Whatever" });
}

Here the server object is an asynchronous iterator. Whenever a request is received it turns the for await of loop once. I believe server must be instantiated from an Asynchronously Iterable Queue type.

So i tried to implement a similar asynchronous Queue over the best synchronous Queue type in JS that i am aware of.

Obviously, in an AsyncQueue we can not have .dequeue() or .peek() functions since in this case dequeueing happens automatically by the resolution of the first promise and there is no point to peek at the first promise in a Queue of promises. Instead here we have a .next() function for dequeueing alongside with an .enqueue() function to insert new promises.

An important aspect of this AsyncQueue is that it must be able to accept new promises both sychronously and asynchronously which means it will run forever.

So the code is below and i would like to know if it can be simplified any further or perhaps there are things to enhance the performance or whatnot. Please bear with my indentation style since i will not change it. Also i like to use the Private Class Fields very much.

class AsyncQueue {

  #HEAD;
  #LAST;

  static #LINK = class {
    #RESOLVER;

    constructor(promise,resolver){
      this.promise = new Promise(resolve => ( this.#RESOLVER = resolve
                                            , promise.then(value => resolver({value, done: false}))
                                            ));
      this.next    = void 0;
    }

    get resolver(){
      return this.#RESOLVER;
    }
  }

  constructor(){
    new Promise(resolve => this.#HEAD = new AsyncQueue.#LINK(Promise.resolve(null),resolve));
  };

  enqueue(promise){
    this.#LAST = this.#LAST ? this.#LAST.next = new AsyncQueue.#LINK(promise,this.#LAST.resolver)
                            : this.#HEAD      = new AsyncQueue.#LINK(promise,this.#HEAD.resolver)
  }

  next(){
    var promise = this.#HEAD.promise.then(value => ({value, done: false}));
    this.#HEAD.next ? this.#HEAD = this.#HEAD.next
                    : this.#LAST = void 0;
    return promise;
  };

  (Symbol.asyncIterator)() {
    return this;
  };
};


var aq = new AsyncQueue();

async function getAsyncValues(){
  for await (let item of aq){
    console.log(`The Promise resolved with a value of ${item.value}`);
  };
};


getAsyncValues();
// synchronous insertion of promises
for (var i=1; i <= 5; i++) aq.enqueue(new Promise(resolve => setTimeout(resolve, 1000*i, `done at ${1000*i}ms`)));
// asynchronous insertion od a promise
setTimeout(aq.enqueue.bind(aq),7500,Promise.resolve("this is an asynchronnous insertion"));

object oriented – A Tiny Image Tagger Implementation in C#

I am trying to implement a tiny image tagger with customized tag options in C#. The main window is as follows.

MainUIFigure

The left block is a picture box MainPictureBox and there are two buttons, PreviousButton and NextButton. Furthermore, there are some tags in a group box AttributeGroupBox. A save button SaveButton is used for saving tagged information.

The implemented functions:

  • Load images automatically in the folder which the program located.

  • Each image could be tagged.

  • The tag information of each image could be saved as a text file LabelResult.txt.

The experimental implementation

class Attribute
{
    public enum AttributeEnum
    {
        Mountain,
        Cat
    }

    public AttributeEnum attributeEnum;

    public override string ToString()
    {
        if (this.attributeEnum.Equals(AttributeEnum.Cat))
        {
            return "Cat";
        }
        if (this.attributeEnum.Equals(AttributeEnum.Mountain))
        {
            return "Mountain";
        }
        return "";
    }
}
public partial class Form1 : Form
{
    List<string> ImagePaths;
    List<Attribute> AttributeList;
    int index = 0;
    string targetDirectory = "./";
    public Form1()
    {
        InitializeComponent();

        
        System.IO.FileSystemWatcher watcher = new FileSystemWatcher()
        {
            Path = targetDirectory,
            Filter = "*.jpg | *.jpeg| *.bmp | *.png"
        };
        // Add event handlers for all events you want to handle
        watcher.Created += new FileSystemEventHandler(OnChanged);
        // Activate the watcher
        watcher.EnableRaisingEvents = true;

        ImagePaths = new List<string>();
        
        string() fileEntries = System.IO.Directory.GetFiles(targetDirectory);
        foreach (string fileName in fileEntries)
        {
            string filenameExt = System.IO.Path.GetExtension(fileName);
            if (filenameExt.Equals(".jpg") ||
                filenameExt.Equals(".jpeg") ||
                filenameExt.Equals(".bmp") ||
                filenameExt.Equals(".png")
                )
            {
                ImagePaths.Add(fileName);
            }
        }
        MainPictureBox.SizeMode = PictureBoxSizeMode.Zoom;
        MainPictureBox.Image = Image.FromFile(ImagePaths(0));

        AttributeList = new List<Attribute>();
        
    }

    private void OnChanged(object source, FileSystemEventArgs e)
    {
        ImagePaths.Clear();
        string() fileEntries = System.IO.Directory.GetFiles(targetDirectory);
        foreach (string fileName in fileEntries)
        {
            string filenameExt = System.IO.Path.GetExtension(fileName);
            if (filenameExt.Equals(".jpg") ||
                filenameExt.Equals(".jpeg") ||
                filenameExt.Equals(".bmp") ||
                filenameExt.Equals(".png")
                )
            {
                ImagePaths.Add(fileName);
            }
        }
    }

    private void PreviousButton_Click(object sender, EventArgs e)
    {
        index--;
        if (index <= 0)
        {
            index = 0;
        }
        MainPictureBox.Image = Image.FromFile(ImagePaths(index));
        GC.Collect();
    }

    private void NextButton_Click(object sender, EventArgs e)
    {
        NextAction();
    }

    private void NextAction()
    {
        index++;
        if (index >= ImagePaths.Count)
        {
            index = ImagePaths.Count - 1;
        }
        MainPictureBox.Image = Image.FromFile(ImagePaths(index));
        GC.Collect();
    }

    private void SaveButton_Click(object sender, EventArgs e)
    {
        Attribute attribute = new Attribute();
        
        if (radioButton1.Checked)
        {
            attribute.attributeEnum = Attribute.AttributeEnum.Mountain;
        }
        if (radioButton2.Checked)
        {
            attribute.attributeEnum = Attribute.AttributeEnum.Cat;
        }
        MessageBox.Show(attribute.ToString());
        AttributeList.Add(attribute);
        AttributeListToTxt();
        NextAction();
    }

    private void AttributeListToTxt()
    {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < this.AttributeList.Count; i++)
        {
            sb.Append(this.ImagePaths(i) + "t" + this.AttributeList(i).ToString() + Environment.NewLine);
        }
        File.WriteAllText("LabelResult.txt", sb.ToString());
    }
}

All suggestions are welcome.

If there is any possible improvement about:

  • Potential drawback or unnecessary overhead
  • The design of implemented methods

please let me know.

spring boot – erro ao utilizar o mapper Caused by: java.lang.ClassNotFoundException: Cannot find implementation for mapper

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘authorController’ defined in file (C:Usersalexsandrosmeclipse-workspacebookstoremanagertargetclassescomalexbookstoremanagerauthorcontrollerAuthorController.class): Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘authorService’ defined in file (C:Usersalexsandrosmeclipse-workspacebookstoremanagertargetclassescomalexbookstoremanagerauthorserviceAuthorService.class): Bean instantiation via constructor failed; nested exception is java.lang.ExceptionInInitializerError
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:917) ~(spring-context-5.3.4.jar:5.3.4)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:582) ~(spring-context-5.3.4.jar:5.3.4)
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~(spring-boot-2.4.3.jar:2.4.3)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:767) ~(spring-boot-2.4.3.jar:2.4.3)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) ~(spring-boot-2.4.3.jar:2.4.3)
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:426) ~(spring-boot-2.4.3.jar:2.4.3)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:326) ~(spring-boot-2.4.3.jar:2.4.3)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1311) ~(spring-boot-2.4.3.jar:2.4.3)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300) ~(spring-boot-2.4.3.jar:2.4.3)
at com.alex.bookstoremanager.BookstoremanagerApplication.main(BookstoremanagerApplication.java:10) ~(classes/:na)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~(na:na)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~(na:na)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~(na:na)
at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~(na:na)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~(spring-boot-devtools-2.4.3.jar:2.4.3)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘authorService’ defined in file (C:Usersalexsandrosmeclipse-workspacebookstoremanagertargetclassescomalexbookstoremanagerauthorserviceAuthorService.class): Bean instantiation via constructor failed; nested exception is java.lang.ExceptionInInitializerError
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:315) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:296) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~(spring-beans-5.3.4.jar:5.3.4)
… 25 common frames omitted
Caused by: java.lang.ExceptionInInitializerError: null
at com.alex.bookstoremanager.author.service.AuthorService.(AuthorService.java:12) ~(classes/:na)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~(na:na)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64) ~(na:na)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~(na:na)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) ~(na:na)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481) ~(na:na)
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:212) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:117) ~(spring-beans-5.3.4.jar:5.3.4)
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:311) ~(spring-beans-5.3.4.jar:5.3.4)
… 39 common frames omitted
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: Cannot find implementation for com.alex.bookstoremanager.author.mapper.AuthorMapper
at org.mapstruct.factory.Mappers.getMapper(Mappers.java:61) ~(mapstruct-1.3.1.Final.jar:na)
at com.alex.bookstoremanager.author.mapper.AuthorMapper.(AuthorMapper.java:12) ~(classes/:na)
… 48 common frames omitted
Caused by: java.lang.ClassNotFoundException: Cannot find implementation for com.alex.bookstoremanager.author.mapper.AuthorMapper
at org.mapstruct.factory.Mappers.getMapper(Mappers.java:75) ~(mapstruct-1.3.1.Final.jar:na)
at org.mapstruct.factory.Mappers.getMapper(Mappers.java:58) ~(mapstruct-1.3.1.Final.jar:na)
… 49 common frames omitted

Classe AuthorService:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alex.bookstoremanager.author.mapper.AuthorMapper;
import com.alex.bookstoremanager.author.repository.AuthorRepository;

@Service
public class AuthorService {

private final static AuthorMapper authorMapper = AuthorMapper.INSTANCE;

private AuthorRepository authorRepository;

@Autowired
public AuthorService(AuthorRepository authorRepository) {
    this.authorRepository = authorRepository;
}

}

classe AuthorMapper:

package com.alex.bookstoremanager.author.mapper;

import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

import com.alex.bookstoremanager.author.dto.AuthorDTO;
import com.alex.bookstoremanager.author.entity.Author;

@Mapper(componentModel = “spring”)
public interface AuthorMapper {

AuthorMapper INSTANCE = Mappers.getMapper(AuthorMapper.class);

Author toModel(AuthorDTO authorDTO);

AuthorDTO toDTO(Author author);

}

assembly – setjmp and longjmp implementation in mmix

I’ve written an implementation of setjmp and longjmp in MMIX (assuming no name mangling).
I also hand-assembled it.
Are there any mistakes anyone can spot?

    // Memory stack pointer is stored in $254.
    // jmp_buf is rO, next address after setjmp call, memory stack pointer,
    // then possibly other data (for sigsetjmp/siglongjmp).
    // rG is preserved over a longjmp call
    // (not that it should change over one, anyway)
    // You'll have to store the frame pointer to the memory stack
    // yourself.
setjmp IS @
    GET    $1,rO            // FE01000A
    STOU   $1,$0,0          // AF010000
    GET    $1,rJ            // FE010004
    STOU   $1,$0,8          // AF010008
    STOU   $254,$0,16       // AFFE0010
    SETL   $0,0             // E3000000
    POP    1,0              // F8010000
longjmp IS @
    LDOU   $254,$0,0        // 8FFE0000
    SAVE   $255,0           // FAFF0000
    GET    $1,rG            // FE000013
    // why 15? We save 13 special registers, two local registers,
    // and the number 2, as well as any global registers.
    // That's 256-rG + 16, and we add only 15 because $255 is the address
    // of the saved rGA.
    SETL   $0,271           // E300010F
    SUBU   $1,$1,$0         // 26010100
    SLU    $1,$1,3          // 39000003
    // now $255 is topmost saved register, $255+$1 is bottommost such,
    // $254 is rO after.
    SUBU   $0,$254,$1       // 2600FE01
    LDOU   $2,$255,$1       // 8E02FF01
    STOU   $2,$0,$1         // AE020001
    8ADDU  $1,$1,1          // 2D010101
    PBNZ   $1,@-12          // 5B01FFFD
    OR     $255,$0,0        // C1FF0000
    UNSAVE 0,$255           // FB0000FF
    // now we have restored rO, but not other stuff
    LDOU   $254,$0,16       // 8FFE0010
    LDOU   $0,$0,8          // 8F000008
    PUT    rJ,$0            // F6040000
    OR     $0,$1,0          // C1000100
    POP    1,0              // F8010000

The register stack was the hard part here. Everything between the SAVE and the UNSAVE inclusive is essentially just “set register stack pointer properly”; after that it takes no time at all to fix up the other registers and return.

If you have any other questions, I’m happy to explain my reasons for each tetra of that code.

beginner – gpuIncreaseOne Function Implementation in CUDA

I am trying to perform the basic operations + with CUDA for GPU computation. The function vectorIncreaseOne is the instance for the operation details and gpuIncreaseOne function is the structure for applying the operation to each element in the parameter data_for_calculation.

The experimental implementation

The experimental implementation of gpuIncreaseOne function is as below.

#include <stdio.h>
#include <cuda_runtime.h>
#include <cuda.h>
#include <helper_cuda.h>
#include <math.h>

__global__ void CUDACalculation::vectorIncreaseOne(const long double* input, long double* output, int numElements)
{
    int i = blockDim.x * blockIdx.x + threadIdx.x;

    if (i < numElements)
    {
        if (input(i) < 255)
        {
            output(i) = input(i) + 1;
        }
    }
}

int CUDACalculation::gpuIncreaseOne(float* data_for_calculation, int size)
{
    // Error code to check return values for CUDA calls
    cudaError_t err = cudaSuccess;

    // Print the vector length to be used, and compute its size
    int numElements = size;
    size_t DataSize = numElements * sizeof(float);

    // Allocate the device input vector A
    float *d_A = NULL;
    err = cudaMalloc((void **)&d_A, DataSize);
    if (err != cudaSuccess)
    {
        fprintf(stderr, "Failed to allocate device vector A (error code %s)!n", cudaGetErrorString(err));
        exit(EXIT_FAILURE);
    }

    // Allocate the device input vector B
    float *d_B = NULL;
    err = cudaMalloc((void **)&d_B, DataSize);
    if (err != cudaSuccess)
    {
        fprintf(stderr, "Failed to allocate device vector B (error code %s)!n", cudaGetErrorString(err));
        exit(EXIT_FAILURE);
    }

    // Allocate the device output vector C
    float *d_C = NULL;
    err = cudaMalloc((void **)&d_C, DataSize);
    if (err != cudaSuccess)
    {
        fprintf(stderr, "Failed to allocate device vector C (error code %s)!n", cudaGetErrorString(err));
        exit(EXIT_FAILURE);
    }

    // Copy the host input vectors A and B in host memory to the device input vectors in
    // device memory
    err = cudaMemcpy(d_A, data_for_calculation, DataSize, cudaMemcpyHostToDevice);

    if (err != cudaSuccess)
    {
        fprintf(stderr, "Failed to copy vector A from host to device (error code %s)!n", cudaGetErrorString(err));
        exit(EXIT_FAILURE);
    }

    // Launch the Vector Add CUDA Kernel
    int threadsPerBlock = 256;
    int blocksPerGrid =(numElements + threadsPerBlock - 1) / threadsPerBlock;
    printf("CUDA kernel launch with %d blocks of %d threadsn", blocksPerGrid, threadsPerBlock);
    vectorIncreaseOne <<<blocksPerGrid, threadsPerBlock>>>(d_A, d_C, numElements);

    err = cudaGetLastError();

    if (err != cudaSuccess)
    {
        fprintf(stderr, "Failed to launch vectorAdd kernel (error code %s)!n", cudaGetErrorString(err));
        exit(EXIT_FAILURE);
    }

    // Copy the device result vector in device memory to the host result vector
    // in host memory.
    err = cudaMemcpy(data_for_calculation, d_C, DataSize, cudaMemcpyDeviceToHost);

    if (err != cudaSuccess)
    {
        fprintf(stderr, "Failed to copy vector C from device to host (error code %s)!n", cudaGetErrorString(err));
        exit(EXIT_FAILURE);
    }

    // Free device global memory
    err = cudaFree(d_A);

    if (err != cudaSuccess)
    {
        fprintf(stderr, "Failed to free device vector A (error code %s)!n", cudaGetErrorString(err));
        exit(EXIT_FAILURE);
    }

    err = cudaFree(d_B);

    if (err != cudaSuccess)
    {
        fprintf(stderr, "Failed to free device vector B (error code %s)!n", cudaGetErrorString(err));
        exit(EXIT_FAILURE);
    }

    err = cudaFree(d_C);

    if (err != cudaSuccess)
    {
        fprintf(stderr, "Failed to free device vector C (error code %s)!n", cudaGetErrorString(err));
        exit(EXIT_FAILURE);
    }
    return 0;
}

Test cases

The test case for gpuIncreaseOne function is as below.

auto data_pointer = (float*)malloc(100 * sizeof(float));
for (int i = 0; i < 100; i++)
{
    data_pointer(i) = static_cast<float>(1);
}
CUDACalculation::gpuIncreaseOne(data_pointer, 100);


free(data_pointer);

All suggestions are welcome.

If there is any possible improvement about:

  • Potential drawback or unnecessary overhead
  • Error handling

please let me know.

An expirable LRU cache implementation

I implemented an ExpireLRUCache class, which will clear the data when it times out. There are two ways to achieve this:

  1. Use a timer to clear the expire data
  2. Call the clean function in Add and Get

If I use a struct in class, and it use the template typename, how to deal with this?

I put the declaration of Node at the top, because it will be used when it is used. Is it reasonable?

template <typename K, typename V>
class ExpireLRUCache {
 private:
  using Timestamp = std::chrono::time_point<std::chrono::system_clock>;
  struct Node {
    K key;
    V value;
    Timestamp timestamp;
  };

 public:
  using NodePtr = std::shared_ptr<Node>;
  using NodeIter = typename std::list<NodePtr>::iterator;
  using ExpiredCallBack = std::function<void(K, V)>;
  
  // Default timeout is 3000ms.
  ExpireLRUCache(size_t max_size)
     : max_size_(max_size), time_out_(3000), expired_callback_(nullptr) {}

  ExpireLRUCache(size_t max_size, uint32_t time_out, ExpiredCallBack call_back)
     : max_size_(max_size), time_out_(time_out), expired_callback_(call_back) {}

  void Add(K key, V value);
  V Get(K key);

  size_t Size() const;

 private:
  void Expired();

  mutable std::mutex mutex_;
  std::list<NodePtr> list_;
  std::unordered_map<K, NodeIter> map_;

  size_t max_size_;
  // ms
  uint32_t time_out_;

  ExpiredCallBack expired_callback_;  
};

template <typename K, typename V>
void ExpireLRUCache<K, V>::Add(K key, V value) {
  std::lock_guard<std::mutex> lock(mutex_);
  // if full, delete oldest
  if (list_.size() >= max_size_) {
    auto oldest = list_.back();
    list_.pop_back();
    map_.erase(oldest->key);
  }

  // if exist, delete it in the list, and then add to the front
  // then overwrite in map.
  if (map_.find(key) != map_.end()) {
    NodeIter iter = map_(key);
    list_.erase(iter);
  }

  auto timestamp = std::chrono::system_clock::now();
  NodePtr node = std::make_shared<Node>(Node{key, value, timestamp});
  list_.push_front(node);
  map_(key) = list_.begin();
}

template <typename K, typename V>
V ExpireLRUCache<K, V>::Get(K key) {
  std::lock_guard<std::mutex> lock(mutex_);
  
  // Todo(zero): how to call
  Expired();

  if (map_.find(key) != map_.end()) {
    return (*map_(key))->value;
  } else {
    return V{};
  }
}

template <typename K, typename V>
void ExpireLRUCache<K, V>::Expired() {
  auto time_now = std::chrono::system_clock::now();

  while( !list_.empty() ) {
    auto oldest = list_.back();
    auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(
                    time_now - oldest->timestamp);
    if (diff.count() > time_out_) {
      list_.pop_back();
      map_.erase(oldest->key);
      expired_callback_(oldest->key, oldest->value);
    } else {
      break;
    }
  }
}

template <typename K, typename V>
size_t ExpireLRUCache<K, V>::Size() const {
  std::lock_guard<std::mutex> lock(mutex_);
  return map_.size();
}
```

An expirable LRU cache implementation c++?

I implemented an ExpireLRUCache class, which will clear the data when it’s times out. There are two ways to achieve this.

  1. Use a timer to clear the expire data
  2. Call the clean function in Add and Get

If I use a strut in class, and it use the template typename, how to deal with this?

I put the declaration of Node at the top and “, because it will be used when it is used. Is it reasonable?

template <typename K, typename V>
class ExpireLRUCache {
 private:
  using Timestamp = std::chrono::time_point<std::chrono::system_clock>;
  struct Node {
    K key;
    V value;
    Timestamp timestamp;
  };

 public:
  using NodePtr = std::shared_ptr<Node>;
  using NodeIter = typename std::list<NodePtr>::iterator;
  using ExpiredCallBack = std::function<void(K, V)>;
  
  // Default timeout is 3000ms.
  ExpireLRUCache(size_t max_size)
     : max_size_(max_size), time_out_(3000), expired_callback_(nullptr) {}

  ExpireLRUCache(size_t max_size, uint32_t time_out, ExpiredCallBack call_back)
     : max_size_(max_size), time_out_(time_out), expired_callback_(call_back) {}

  void Add(K key, V value);
  V Get(K key);

  size_t Size() const;

 private:
  void Expired();

  mutable std::mutex mutex_;
  std::list<NodePtr> list_;
  std::unordered_map<K, NodeIter> map_;

  size_t max_size_;
  // ms
  uint32_t time_out_;

  ExpiredCallBack expired_callback_;  
};

template <typename K, typename V>
void ExpireLRUCache<K, V>::Add(K key, V value) {
  std::lock_guard<std::mutex> lock(mutex_);
  // if full, delete oldest
  if (list_.size() >= max_size_) {
    auto oldest = list_.back();
    list_.pop_back();
    map_.erase(oldest->key);
  }

  // if exist, delete it in the list, and then add to the front
  // then overwrite in map.
  if (map_.find(key) != map_.end()) {
    NodeIter iter = map_(key);
    list_.erase(iter);
  }

  auto timestamp = std::chrono::system_clock::now();
  NodePtr node = std::make_shared<Node>(Node{key, value, timestamp});
  list_.push_front(node);
  map_(key) = list_.begin();
}

template <typename K, typename V>
V ExpireLRUCache<K, V>::Get(K key) {
  std::lock_guard<std::mutex> lock(mutex_);
  
  // Todo(zero): how to call
  Expired();

  if (map_.find(key) != map_.end()) {
    return (*map_(key))->value;
  } else {
    return V{};
  }
}

template <typename K, typename V>
void ExpireLRUCache<K, V>::Expired() {
  auto time_now = std::chrono::system_clock::now();

  while( !list_.empty() ) {
    auto oldest = list_.back();
    auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(
                    time_now - oldest->timestamp);
    if (diff.count() > time_out_) {
      list_.pop_back();
      map_.erase(oldest->key);
      expired_callback_(oldest->key, oldest->value);
    } else {
      break;
    }
  }
}

template <typename K, typename V>
size_t ExpireLRUCache<K, V>::Size() const {
  std::lock_guard<std::mutex> lock(mutex_);
  return map_.size();
}
```

c++11 – C++ generic callback implementation

I have a code that takes messages from flash player in a form of XML parse them into function and arguments and calls a registered callback for that function.
The piece of code that I want to replace is something nicely done (almost) generic Callback mechanism:
code for the generic callback implementation of flashSDK (ASInterface.inl).

The problem with it is that this code is written for flash and I want to replace the flash and use other service that will have the same interface. Is there any standard implementation of this callback mechanism (std? boost? something else open sourced?)?

This code implements generic callbacks mechanism that you can register function with number of arguments and types in a map:

void SomethingHappened(int a, int b) {print a + b;}
void SomethingElseHappened(string abcd) {print abcd;}
callbacks("SomethingHappened") = &SomethingHappened;
callbacks("SomethingElseHappened") = &SomethingElseHappened;

and than search for it and call with an array of arguments:

Callbacks::iterator itCallback = callbacks.find(functionName);
if (itCallback != callbacks.end())
{
    HRESULT result = itCallback->second.Call(arguments, returnValue);
}

full usage example:

//init callbacks
typedef std::map<std::wstring, Callback> callbacks;
void SomethingHappened(int a, int b) {print a + b;}
void SomethingElseHappened(string abcd) {print abcd;}
callbacks(functionName) = &SomethingHappened;

void MessageArrived(string xmlInput)
{
    string functionName = parseFunctionName(xmlInput);
    Callbacks::iterator itCallback = callbacks.find(functionName);
    if (itCallback != callbacks.end())
    {
        //parse arguments
        std::vector<std::wstring> args;
        _Args::split(xml, args);
        ASValue::Array arguments;
        for (size_t i = 0, s = args.size(); i < s; ++i)
        {
            ASValue arg; arg.FromXML(args(i));
            arguments.push_back(arg);
        }
        ASValue returnValue;
        //***this is where the magic happens: call the function***
        HRESULT result = itCallback->second.Call(arguments, returnValue);
        return result;
    }
}