0
#include <list>
#include <vector>
#include <mutex>


typedef std::list<void *> funcList;

typedef struct {
  funcList* functionsList;
  char* listName;
}ListAccess_t;

namespace FuncListManager{
  //namespace {
    std::vector<funcList> funcBuffer;
    std::mutex funcMutex;
 // }

  static size_t findEmptyList() {
    for (size_t index = 0; index < funcBuffer.size(); index++) {
      if (funcBuffer[index].empty()) {
        return index;
      }
    }
    return funcBuffer.size();
  }

  size_t getAvalableListIndex() {
    std::lock_guard<std::mutex> lock(funcMutex);
    if (funcBuffer.size() != findEmptyList()) {
      return findEmptyList();
    }
    else {
      return -1;
    }
  }

  void addFunction(size_t listIndex, void* func) {
    std::lock_guard<std::mutex> lock(funcMutex);
    funcBuffer[listIndex].push_back(func);
  }

  void removeFunction(size_t listIndex, void* func) {
    std::lock_guard<std::mutex> lock(funcMutex);
    if (listIndex < funcBuffer.size()) {
      auto& myFuncList = funcBuffer[listIndex];

      auto it = std::find(myFuncList .begin(), myFuncList .end(), func);

      if (it != myFuncList .end()) {
        myFuncList .erase(it);
      }
    }
  }

  void createFunctionList(size_t capacity) {
    std::lock_guard<std::mutex> lock(funcMutex);
    funcBuffer.resize(capacity);
  }

  funcList* getFunctionListPointer(size_t listIndex) {
    std::lock_guard<std::mutex> lock(funcMutex);
    if (listIndex < funcBuffer.size()) {
      return &funcBuffer[listIndex];
    }
    return nullptr;
  }
}

void (*addNumber_t)(int a, int b);

void addnumber(int a, int b) {
  int c = a + b;
}


int main() {
  
  FuncListManager::createFunctionList(5);
  size_t index = FuncListManager::getAvalableListIndex();

  addNumber_t = &addnumber;
  FuncListManager::addObserver(index, (void*)&addnumber);
  ListAccess_t *listAccess = new ListAccess_t();

  listAccess->functionsList= FuncListManager::getObserverListPointer(index);
  listAccess->listName = "list access";

  ObserverList *list = listAccess->functionsList;

  for (auto& func: *list) {
    ((addNumber_t)func)(1,2); //how to call add function here
    int i = 0;
  }

  FuncListManager::removeFunction(index, (void*)&addnumber);

  return 0;
}

I have to create vector of lists and each list is the collection of address of functions (which are referenced with function pointers). How it is possible to call the functions which are added to the vector of lists?

I don't want to use the classes, it's a library under a namespace.

I tried to call the extracted function from the list, but it throws compilation error.

6
  • 2
    addNumber_t is a variable, not a type. typedef void (*addNumber_t)(int, int); would declare it as a type alias. Commented Aug 31, 2023 at 9:07
  • Is it technically (as per the specification) possible to use a void* pointer to point to functions? IIRC it's not, pointers to functions are a different thing from general pointers to data or objects. Commented Aug 31, 2023 at 9:08
  • 2
    typedef std::list<void *> funcList;? How would you call a function if you lose its type? +@Someprogrammerdude remark. Commented Aug 31, 2023 at 9:08
  • 1
    And why do you use typedef for structures? A struct in C++ is just like a class, and the structure (or class) tag name is also a type name. And generally, avoid the confusing typedef keyword for creating type-aliases, in favor of using. As in using funcList = std::list<void*>; (but please keep my previous comment in mind) Commented Aug 31, 2023 at 9:10
  • @Someprogrammerdude I think so. If I recall, ordinary function pointers do fit in a pointer, whereas pointer-to-member-function is special and does not necessarily fit (although in practice it tends to). Commented Aug 31, 2023 at 9:13

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.