mercredi 31 mai 2023

Is converting a vector to a list more efficient for removing k random elements?

Suppose I have a vector of N items and I want to remove k random elements from it. The complexity of vector erase is linear in the number of items after the erased item. So for k random elements it would be O(Nk). My question is the following: Would it be more efficient to convert a vector to a list in O(N) time and perform erase in the list format in constant time?

I know it depends on N and k, and benchmarking would reveal the best for a specific case. But, I wonder if it is a common thing that people usually do?

node-handle vs std::unique_ptr

Reading the documentation of the node-handle interface and studying some implementations of the standard library, I noticed that many features of the node-handle type can simply be emulated by a specialization of the std::unique_ptr smart pointer. In fact, the functionalities of the node-handle type are very similar to the functionalities of a std::unique_ptr smart pointer. It has only an interface more compliant with the features of an associative container, such as the key_type and mapped_type aliases and the functions to get a reference of the underlying value or key/mapped value.

So, are there any other advantages therefore the standard had introduced a node-handle type over a simple specialization of std::unique_ptr as node_type?

mardi 30 mai 2023

Trouble printing a re-hashed table

I'm working on my Hash Table assignment and I ran into an issue when printing the new table after re-hashing all the values. The compiler reports this error:

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid
Aborted (core dumped)

Now there are a lot of questions on SO about this, but none of them seemed to answer my question. It was mostly people assigning a non-string value to a std::string.

I am reading my original data from a .csv file and I am supposed to store them in a Hash Table and print them. When I fetch the data for the first time I can print them just fine, but after re-hashing the error I listed above gets thrown.

I tried producing a minimal reproducible example but if I decrease the input size(from 250K to 3 inputs) re-hashing seems to work just fine and no error gets raised.

Am I doing something completely wrong? Could my data be corrupted? Am I dealing with a massive pointer ownership problem (I have to use raw pointers)?

I know I pasted a lot fo code and I am very far from a minimal reproducible example, but I couldn't find a different way to ask a bout this.

When using gdb to debug the code (after rehashing) it stops and terminates when it hits the

std::cout << entry << std::endl;

void CovidDB::rehash()

void CovidDB::rehash() {
  auto is_prime = [](int num) {
    if (num <= 1)
      return false;

    for (int i = 2; i <= std::sqrt(num); ++i) {
      if (num % i == 0)
        return false;
    }
    return true;
  };

  auto find_next_prime = [&is_prime](int num) {
    while (true) {
      if (is_prime(num))
        return num;
      ++num;
    }
  };

  int new_size = size * 2;
  int new_prime_size = find_next_prime(new_size);

  CovidDB new_table(new_prime_size);

  for (auto row : HashTable) {
    for (auto entry : row) {
      if (entry != nullptr) {
        new_table.add(entry);
      }
    }
  }

  HashTable = new_table.HashTable;
  size = new_prime_size;

#ifdef LOG
  std::cout << "\n[LOG]: Rehashed, new table size: " << size << std::endl;
  try {
    if (new_table.size != size) {
      throw std::logic_error("\n[size mismatch!]");
    }
  }
  catch (std::exception& error) {
    std::cerr << "[Error]:\t" << error.what() << std::endl;
  }
#endif //LOG
  return;
}

bool CovidDB::add(DataEntry* entry)

bool CovidDB::add(DataEntry* entry) {
  int index = hash(entry->get_country());
  bool added = false;

  if (HashTable[index].empty()) {
    HashTable[index].push_back(entry);
  }
  else {
    for (DataEntry* existing_entry : HashTable[index]) {
      std::atomic<bool> valid(false);
      valid.store(
        hash(existing_entry->get_country()) == hash(entry->get_country()) &&
        existing_entry->get_country() == entry->get_country()
      );
      if (valid && entry != nullptr) {
        existing_entry->set_date(entry->get_date());
        existing_entry->set_c_cases(existing_entry->get_c_cases() + entry->get_c_cases());
        existing_entry->set_c_deaths(existing_entry->get_c_deaths() + entry->get_c_deaths());
        added = true;
        //delete entry;
        break;
      }
    }
    if (!added) {
      HashTable[index].push_back(entry);
    }
  }

  return added;
}

void CovidDB::display_table()

void CovidDB::display_table() {
  bool is_empty = true;

  for (const auto& vec : HashTable) { //if 1st dimension is empty
    if (!vec.empty()) {
      is_empty = false;
      break;
    }
  }

  try {
    if (is_empty) {
      throw std::logic_error("\n[Data Base is empty]\n");
      return;
    }
  }
  catch (std::exception& error) {
    std::cerr << "[Error]:\t" << error.what() << std::endl;
    return;
  }

  for (auto vec : HashTable) {
    for (auto entry : vec) {
      if (entry != nullptr) {
        std::cout << entry << std::endl;
        sleep(50);
      }
    }
  }
  }
  std::cout << std::endl;
  return;
}

overloaded ostream operator

  inline static void print_data_entry(std::ostream& stream, DataEntry* entry) {
    char const SPACE = ' ';
    if (entry != nullptr) {
      stream << "[Date: " << entry->get_date() << "]," << SPACE
        << "[Country: " << entry->get_country() << "]," << SPACE
        << "[Cases: " << entry->get_c_cases() << "]," << SPACE
        << "[Deaths: " << entry->get_c_deaths() << "]";
    }
  }

  inline friend std::ostream& operator<<(std::ostream& stream, DataEntry* entry) {
    print_data_entry(stream, entry);
    return stream;
  }

Unexpected behavior with `std::chrono::system_clock` and `std::chrono::steady_clock` in `std::condition_variable::wait_until`

I'm working with std::condition_variable::wait_until in C++ and I'm using std::chrono::system_clock and std::chrono::steady_clock to manage the waiting time. After reading the documentation, I understand that the sleeping time should not be affected by changes in the system time when using std::chrono::steady_clock, while it may change when using std::chrono::system_clock.

However, my code is behaving differently: for both clock types, the waiting time is affected by the system time. Here's a minimal reproducible example:

#include <iostream>
#include <chrono>
#include <thread>
#include <mutex>
#include <ctime>
#include <sys/time.h>
#include <condition_variable>
#include <atomic>

std::atomic<bool> flag = false;
std::condition_variable cv;


void wait_using_system_clock()
{
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    std::mutex mtx;
    std::unique_lock lock(mtx);
    cv.wait_until(lock, std::chrono::system_clock::now() + std::chrono::seconds(20), [](){return flag.load();});

    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
    std::cout << "Time difference [using system clock] = " << std::chrono::duration_cast<std::chrono::seconds>(end - begin).count() << "s" << std::endl;
}

void wait_using_steady_clock()
{
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    std::mutex mtx;
    std::unique_lock lock(mtx);
    cv.wait_until(lock, std::chrono::steady_clock::now() + std::chrono::seconds(20), [](){return flag.load();});

    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
    std::cout << "Time difference [using steady clock] = " << std::chrono::duration_cast<std::chrono::seconds>(end - begin).count() << "s" << std::endl;
}

void set_system_time_forward()
{
    std::this_thread::sleep_for(std::chrono::seconds(2)); // Ensure other threads has executed cv.wait_until
    struct timeval tv;
    gettimeofday(&tv, NULL);
    tv.tv_sec += 15;
    settimeofday(&tv, NULL);
}

int main()
{
    std::thread t1(wait_using_system_clock);
    std::thread t2(wait_using_steady_clock);

    std::thread t3(set_system_time_forward);
    t1.join();
    t2.join();
    t3.join();

    return 0;
}

I execute the wait_using_system_clock and wait_using_steady_clock functions on different threads. Another thread is used to change the system time after 2 seconds. I expect that the function wait_using_steady_clock should not be affected by this change and should wait for 20 seconds, but instead, both functions finish their execution in approximately 5 seconds, printing:

Time difference [using system clock] = 5s
Time difference [using steady clock] = 5s

Can anyone help me understand why this discrepancy exists between the expected and actual behavior? Is there something I'm missing in the documentation or misunderstanding about these classes?

Why doesn't passing vector

error: C++ requires a type specifier for all declarations dfs(int node,int parent,vector<int> adj[],vector<int>& vis,vector<int>& time,vector<int>& low,vector<vector<int>>& bridges){ ^ i dont see anything wrong with my code ive declared vector and previously on leetcode never required to include vector lib

see question and code in this pic

lundi 29 mai 2023

How can I convert a lambda function arguments and store it in std::function

I have a list of functions stored in a vector:

std::vector<std::function<void(uint32_t)>> mFunctions;

I want to add a function as a public API that accepts a different argument but casts it to uint32_t:

enum class MyHandle : uint32_t { Null = 0; };


void addFunction(std::function<void(MyHandle)> &&fn) {
  mFunctions.push_back(fn);
}

How can I achieve this?

dimanche 28 mai 2023

Does snprintf clobber the buffer after null-terminator?

Consider the following code:

char buffer[5]{};
snprintf(buffer, sizeof(buffer), "hi");

snprintf writes 'h', 'i' and '\0' to buffer.

My question is: is there any guarantee that the snprintf won't touch buffer[3] and buffer[4] according to the standard? Visual Studio 2019 keeps the unused buffer untouched, but is this a standard behavior?

How does C++ store lambda functions and their scope outside of a method? [duplicate]

Understanding the storage of lambda functions in C++

Hello I am learning C++ and came across a code where they used a lambda function in an object's constructor and saved it in a function pointer. The code is as follows

#include <cstdio>
#include <functional>

class A{
public:
    A() : counter {} {
        lambda = [this](int update){
            this->counter += update;
            return this->counter;
        }; // This lambda is persisting even after exiting the method, which seems wrong

        int temp = 10; //This address gets destroyed after the function call
        int_ptr = &temp;
    }

    std::function<int(int)> lambda;
    int counter;
    int* int_ptr;
};

int main(){
    A a1;
    auto res = a1.lambda(20);
    res = a1.lambda(20); // Working
    printf("Result of the lambda = %d\n", res);
    printf("Value pointed by the pointer = %d\n", *a1.int_ptr); //Improper Useage
    return 0;
}

My question is that the lambda definition we defined in the constructor should not be valid outside the constructor since lambda's scope is automatic. In the same note the '''temp''' variable's scope is also automatic and even if we have access to its address outside the function's scope accessing it is wrong.

Shouldn't the same also be valid for the lambda ?

Should My string class supply implicit conversion to std::string

I defined a string class and one of its constructors accepts std::string, that is to say std::string can be directly converted to my string. And for some reason, I want to provide an implicit conversion method for my string to std::string. It looks like:

class MyString {
public:
  MyString(const std::string& str) : data(str) {}

  operator const std::string& () const {
    return data;
  }

private:
  std::string data;
};

After I provided a method for implicit conversion to std::string, I only found a compilation error: the type selection error of the c++ ternary expression. Something like: b ? std::string("") : MyString("").

But I worry that there may be some unknown hazards in being able to convert from std::string to MyString, and directly from MyString to std::string. Is it OK? Why? Thanks All.

Use of copy constructor and overloading the assignment operator

this is a homework question. I am working on my Hash Table assignment and I got stuck on the re-hash function. When I run the code I pasted below this error gets thrown:

terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid
Aborted (core dumped)

And after reading this I'm still very confused on what's happening.

My best effort of producing a minimal reproducible example:


// {
// @note I really tried to shorten it down as much as possible, but I still need certain functions and class declarations in order for the code to run
// }

#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <iomanip>
#include <atomic>

class DataEntry {
private:
  std::string date;
  std::string country;
  int c_cases;
  int c_deaths;
  
public:
  DataEntry() {
    this->date = "\0";
    this->country = "\0";
    this->c_cases = 0;
    this->c_deaths = 0;
  }
  
  inline void set_date(std::string set_date) { this->date = set_date;};
  inline void set_country(std::string set_country) { this->country = set_country;};
  inline void set_c_deaths(int set_c_deaths) { this->c_deaths = set_c_deaths;};
  inline void set_c_cases(int set_c_cases) { this->c_cases = set_c_cases;};
  
  inline int get_c_cases() { return c_cases;};
  inline int get_c_deaths() { return c_deaths;};
  
  inline std::string get_date() { return date;};
  inline std::string get_country() { return country;};   
};

class CovidDB {
private:
  int size = 17;
  std::vector<std::vector<DataEntry*>> HashTable;
  
public:
  inline CovidDB() {
    HashTable.resize(size);
  }

  /** @note Copy constructor */
  CovidDB(const CovidDB& other) {
    size = other.size;
    HashTable.resize(size);
    for (int i = 0; i < size; ++i) {
      for (const auto& entry : other.HashTable[i]) {
        HashTable[i].push_back(new DataEntry(*entry));
      }
    }
  }

  inline void clear() {
    for (auto& row : HashTable) {
      for (auto& entry : row) {
        delete entry;
      }
      row.clear();
    }
    HashTable.clear();    
    HashTable.shrink_to_fit();
    ///@link https://stackoverflow.com/questions/12587774/destructor-not-being-called
  }

  inline ~CovidDB() { //handles memory
    clear();
  }

  /** @note Move constructor */
  CovidDB(CovidDB&& other) noexcept { 
    size = other.size;
    HashTable = std::move(other.HashTable);
    other.size = 0;
  }

  /** @note Overloaded assigment operator*/
  CovidDB& operator=(const CovidDB& other) {
  if (this == &other) {
    return *this;  // Self-assignment
  }
  // clear the data and resources
  for (auto& row : HashTable) {
    for (auto& entry : row) {
      delete entry;
    }
    row.clear();
  }
  HashTable.clear();
  HashTable.shrink_to_fit();

  // copy the data from the other object
  size = other.size;
  HashTable.resize(size);
  for (int i = 0; i < size; ++i) {
    for (const auto& entry : other.HashTable[i]) {
      HashTable[i].push_back(new DataEntry(*entry));
    }
  }
  return *this;
 }
 void rehash();
 void display_table();
 bool add(DataEntry*);
 int re_hash_key(std::string);
 int hash(std::string);
};

int CovidDB::re_hash_key(std::string country) {
  int sum = 0;
  int count = 0;
  
  for (char c : country) {
    sum = sum + ((count + 1) * c);
    count++;
  }
  return sum % size; //returns the new hash
}

void CovidDB::rehash() {
  auto is_prime = [](int num) {
    if (num <= 1)
      return false;

    for (int i = 2; i <= std::sqrt(num); ++i) {
      if (num % i == 0)
        return false;
    }
    return true;
  };

  auto find_next_prime = [&is_prime](int num) {
    while (true) {
      if (is_prime(num))
        return num;
      ++num;
    }
  };

  int new_size = size * 2;
  int new_prime_size = find_next_prime(new_size);
  size = new_prime_size; //re-assign size

  //CovidDB new_table(std::move(HashTable));//call move constructor, size 37

  std::vector<std::vector<DataEntry*>> newHashTable(size); //temp object
  newHashTable.resize(size);

  // rehash all entries from the original table to the new table
  for (std::vector<DataEntry*> row : HashTable) {
    for (DataEntry* entry : row) {
      int re_hash_i = re_hash_key(entry->get_country());
      newHashTable[re_hash_i].push_back(entry);
    }
  }

  // Clear the original table and update it with the new table
  clear(); //predefined function that I removed due to MRE 
  HashTable = newHashTable;
  std::cout << "SIZE: " << size << std::endl;
  return;
}

void CovidDB::display_table() {
  for(std::vector<DataEntry*> vec : HashTable) {
    for(DataEntry* entry : vec) {
      if (entry != nullptr) { //guard against dereferencing nullptr
        std::cout << std::flush;
        std::cout << "[Date: " << entry -> get_date() << "], "
                  << "[Country: " << entry -> get_country() << "], "
                  << "[Cases: " << entry -> get_c_cases() << "], "
                  << "[Deaths: " << entry -> get_c_deaths() << "] "
                  << std::endl;
      }
    }
  }
  std::cout << std::endl;
  return;
}

int CovidDB::hash(std::string country) {
  int sum = 0;
  int count = 0;
  
  for (char c : country) {
    sum = sum + ((count + 1) * c);
    count++;
  }
  return sum % size; //returns the hash
}

bool CovidDB::add(DataEntry* entry) {
  int index = hash(entry->get_country());
  HashTable[index].push_back(entry);
  return true;
}

int main() {
  CovidDB base;
  DataEntry* data1 = new DataEntry();
  DataEntry* data2 = new DataEntry();

  data1->set_date("01/01/23");
  data1->set_country("Slovenia");
  data1->set_c_cases(1);
  data1->set_c_deaths(1);

  data2->set_date("02/02/23");
  data2->set_country("Slovenia");
  data2->set_c_cases(1);
  data2->set_c_deaths(1);

  // Add the entries to the CovidDB
  base.add(data1);
  base.add(data2);

  base.display_table();
  base.rehash();
  base.display_table();
}

The main problem is my re-hash method. My general idea was to:

  • Get the new size size * 2 and then next_prime(new_size) to get the actual size, I used a couple of lambdas to achieve that. That part works since the new size is 37 as it should be.

  • I emailed my professor about my problem and she said I need to follow the rule of 5 so I made my move constructor and my overloaded operator. I don't believe the move constructor is my answer here since I don't want a copy of my original table, but I want to parse all of the existing entries, re-hash and add them to the table. I could be wrong.

  • Finally, I decided to create a new object CovidDB and re-hash all of the. old/existing entries and push them into the new table. This sort of works but my compiler says there is no definition of the = and the [] operator if I make a new object. If I make a new 2D std::vecotr<std::vector<DataEntry*>> instead of an object that works Again I don't think that's the right solution.

The strange part to me is the fact that here:

bool CovidDB::add(DataEntry* entry) {
  int index = hash(entry->get_country());
  HashTable[index].push_back(entry);
  return true;
}

I can index my HasHTable object using the [] operator, but I can't do the same thing in my re_hash function. I get this error:

error: no match for ‘operator[]’ (operand types are ‘CovidDB’ and ‘int’)
  155 |       new_table[re_hash_i].push_back(entry);

for this:

CovidDB new_table;

  for (std::vector<DataEntry*> row : HashTable) {
    for (DataEntry* entry : row) {
      int re_hash_i = re_hash_key(entry->get_country());
      new_table[re_hash_i].push_back(entry);
    }
  }

Can someone help me figure out where I potentially went wrong and why would an error be thrown for the [] operator in one case but not the other?

I tried rubber duck debugging the code, especially the operator but came up empty-handed. My debugger throws me into the std::vector library.

why does default constructor being outside class or inside class make a difference in whether the class is POD?

In the following code, why is POD considered POD while notPOD considered not POD? The only difference between them is whether the definition for defaulted default constructor is placed inside or outside the class. I always thought that both do the same thing but it's apparently not the case.

#include <iostream>
struct POD {
    POD() = default;
};
struct notPOD {
    notPOD();
};
notPOD::notPOD() = default;
int main() {
    std::cout << std::boolalpha << std::is_pod<POD>() << ' ' << std::is_pod<notPOD>() << '\n';
}

VS Code opens header files while debugging a code in C++. How to prevent this from happening?

Before I started Debugging: Before I started Debugging

After I started Debugging: After I started Debugging

As it can be seen in the second image, allocator.h header file is being opened when the debugger ecountered a vector in the first image (highlighted in yellow line). Whole debugging process is so annoying and time taking this when this happens. How to stop this from happening?

VS Code version : 1.78.2 OS : Windows 10

I tried resetting VS Code to defaults, but couldn't fix the problem.

samedi 27 mai 2023

How do I fix the 'expected ';' before string constant' error while running a C++ program in Windows using GCC compiler?

I'm trying to run a C++ program in Windows (using the gcc compiler).On the six line of code below:

char a[1];
cout << "Vui long nhap mot chu cai:";
cin >>a;
if(strupr(a)) {
    strlwr (a);
    cout "Chu cai cua ban sau khi in thuong la:" << strlwr(a) << endl;
    return 0;
}


return 0;

error: expected ';' before string constant

#include #include <string.h>

I DONT Know Pls help me

Different compilation results with template and non-template class having constexpr constructor

A constructor fails to quality as constexpr if the class contains std::vector as its data member since std::vector doesn't have constexpr constructor (atleast until C++17 standards, for C++20 I came across this draft). The issue is if the class itself is templatized, the code successfully gets compiled despite the fact that it has constexpr constructor and std::vector as data member.

Consider following two code snippets:

#include <vector>

class Y {
public:
  constexpr Y(){}
  std::vector<int> v{};
};

int main() {
  Y ob;
  return 0;
}

This code fails to compile whereas the following one compiles successfully

#include <vector>

template<typename T>
class X{
public: 
  constexpr X(){}
  std::vector<T> v;
};

int main() {
  X<int> ob;
  return 0;
}

I do have a slight feel that this might have to do something with how template class is compiled since when I declare a constexpr instance of X constexpr X<int> ob; , it fails to compile but unable to figure out what's actually going under the hood.

What could be causing the Segmentation Fault when attempting to print a 2D vector

This is a homework question. I am working on my Hash Table assignment and I ran into some issues when trying to print the table.

Constraints:

  • C++11
  • No std::map or std::unordered_map

Minimal Reproducible Example

#include <iostream>
#include <vector>
#include <atomic>
#include <ctime>
#include <iomanip>
#include <string>

class DataEntry {
public:
  std::string get_date() { return date; }
  std::string get_country() { return country; }
  int get_c_cases() { return c_cases; }
  int get_c_deaths() { return c_deaths; }
  inline void set_date(std::string set_date) { this->date = set_date;};
  inline void set_country(std::string set_country) { this->country = set_country;};
  inline void set_c_deaths(int set_c_deaths) { this->c_deaths = set_c_deaths;};
  inline void set_c_cases(int set_c_cases) { this->c_cases = set_c_cases;};

private:
  std::string date;
  std::string country;
  int c_cases;
  int c_deaths;
};

class CovidDB {
private:
  std::vector<std::vector<DataEntry*>> HashTable;
  int size = 17;

public:
  void display_table();
  bool add(DataEntry* entry);
  int hash(std::string country);
};

int CovidDB::hash(std::string country) {
  int sum = 0;
  int count = 0;
  
  for (char c : country) {
    sum = sum + ((count + 1) * c);
    count++;
  }
  return sum % size; //returns the hash
}

void CovidDB::display_table() {
  for (const auto& vec : HashTable) {
    for (const auto& entry : vec) {
      if (entry != nullptr) {
        std::cout << "[Date: " << entry->get_date() << "], "
                  << "[Country: " << entry->get_country() << "], "
                  << "[Cases: " << entry->get_c_cases() << "], "
                  << "[Deaths: " << entry->get_c_deaths() << "]" << std::endl;
      }
    }
  }
}

bool CovidDB::add(DataEntry* entry) {
  time_t now = time(0);
  tm* ltm = localtime(&now);
  // DATE FORMAT: mm/dd/yy
  std::string current_date_str = std::to_string(1 + ltm->tm_mon) + "/" + std::to_string(ltm->tm_mday) + "/" + std::to_string(ltm->tm_year % 100);
  std::istringstream iss(current_date_str);
  std::tm current_date = {};
  iss >> std::get_time(&current_date, "%m/%d/%y");
  
  std::tm entry_date = {};
  std::istringstream iss2(entry -> get_date());
  iss2 >> std::get_time(&entry_date, "%m/%d/%y");
  
  if (mktime(&current_date) > mktime(&entry_date)) {
    std::cout << "[Record rejected]" << std::endl;   
    return false;
  }
  
  int index = hash(entry -> get_country());
  
  if (HashTable[index].empty()) {
    HashTable[index].push_back((entry));
  } else {
    bool added = false;
    for (DataEntry* existing_entry : HashTable[index]) {

      std::atomic<bool> valid(false);
      valid.store(hash(existing_entry->get_country()) == hash(entry->get_country()) &&
                       existing_entry->get_country() == entry->get_country());
      if (valid) {
        existing_entry->set_date(entry -> get_date());
        existing_entry->set_c_cases(existing_entry->get_c_cases() + entry->get_c_cases());
        existing_entry->set_c_deaths(existing_entry->get_c_deaths() + entry->get_c_deaths());
        added = true;
        delete entry;
        break;
      }
    }
    if (!added) {
      HashTable[index].push_back(entry);
    }
  }
  return true;
  return true;
}

int main() {
  CovidDB db;

  // Create two DataEntry objects
  DataEntry* entry1 = new DataEntry();
  entry1->set_date("01/01/23");
  entry1->set_country("Slovenia");
  entry1->set_c_cases(1);
  entry1->set_c_deaths(1);

  DataEntry* entry2 = new DataEntry();
  entry2->set_date("02/02/23");
  entry2->set_country("Slovenia");
  entry2->set_c_cases(1);
  entry2->set_c_deaths(1);

  // Add the entries to the CovidDB
  db.add(entry1);
  db.add(entry2);

  // Display the table
  db.display_table();

  // Clean up memory
  delete entry1;
  delete entry2;

  return 0;
}

The print function seems to work fine for 80% of the time (estimate), for instance when I am pushing data from .csv file into the 2D vector and print it works fine, but when I try to group 2 entries of the same hash

eg:

Country: Slovenia
Date: 01/01/23
Cases: 1
Deaths: 1
Country: Slovenia
Date: 02/02/23
Cases: 1
Deaths: 1

It segfaults...I am aware that SEGFAULT means one is trying to access memory that doesn't belong to him (usually trying to deref a nullptr)

I tried loads of stuff before asking a question here:

Rubber duck Debugging

I noticed that the outer loop runs hash-1 times by putting std::court << "here"; in-between the loops, which means that something goes wrong when it comes to the index of the entry.

I also changed auto to std::vecotr<DataEntry*> vec and to DataEntry* since the outer vector is a vector of vectors and the inner vectors are vectors of DataEntry pointers.

Debugging

I tried debugging the executable with gbd, since I can't configure my Vs Code debugger, but it throws an error

Missing separate debuginfos, use: yum debuginfo-install glibc-2.28-211.el8.x86_64 libgcc-8.5.0-16.el8_7.x86_64 libstdc++-8.5.0-16.el8_7.x86_64

I googled it and the only solution I found was to root install these libraries, which I can't, since this is the school's server and running sudo will get me kicked off.

I tried the XCode debugger but for some reason my code there runs differently...Could it be because the ssh is Linux and the other one isn't?

Guards

I added "guards" to prevent printing an empty hash table, and a guard so that I'm not de-referencing a nullptr, unfortunately, had no effect.

Do atomics in C++11 cache repeatable reads in a register or are they only atomic?

Do atomics cache repeatable reads in a register ? Or are they just only atomic, i.e. a read may not be split in multiple parts ?

MSVC++, clang++ / clang-cl and g++ don't cache atomic reads without memory ordering:

#include <atomic>

using namespace std;

int x( atomic_int const &ai )
{
    int
        a = ai.load( memory_order_relaxed ),
        b = ai.load( memory_order_relaxed );
    return a + b;
}

g++:

movl    (%rdi), %edx
movl    (%rdi), %eax
addl    %edx, %eax
ret

clang-cl:

mov eax, dword ptr [rcx]
add eax, dword ptr [rcx]
ret

cl:

mov edx, DWORD PTR [rcx]
mov eax, DWORD PTR [rcx]
add eax, edx
ret 0`

vendredi 26 mai 2023

Is there any way I can lock a list of mutex?

My code is like the following. A Element holds a pointer to a mutex, and there is a vector that holds all Elements.

If I know the count of elements at compile time, I can construct a scoped_lock to lock all these mutexes. However, I don't know the size of the vector now. So how can I lock all the mutexes and generate a lock guard safely?

#include <vector>
#include <mutex>

struct Element {
    Element() {
        mut = new std::mutex();
    }
    Element(Element && other) : mut(other.mut) {
        other.mut = nullptr;
    }
    ~Element() { delete mut; }
    std::mutex * mut;
};

int main() {
    std::vector<Element> v;
    v.push_back(Element());
    v.push_back(Element());
    v.push_back(Element());

    std::scoped_lock(*v[0].mut, *v[1].mut, *v[2].mut);
}

jeudi 25 mai 2023

How can I fix linker error 'Undefined symbols for architecture arm64' when importing namespaces in C++ on a Mac M1?

I try to import functoin to server.cpp from routes.cpp file. If I put all code in one file, it will compile successfully. I use MAC M1 to develop. I get the error message.

Undefined symbols for architecture arm64:
  "handleRoutes::paresHttpReq(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>)", referenced from:
      tcp_connection::start() in main.cpp.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

This is my file structure.

-blog  
  -routes
    -mainRoutes.h
    -routes.cpp
  -TCPconnection
    -server.cpp
  -main.cpp
  -CMakeLists.txt

mainRoutes.h

#pragma once
#ifndef _MAINROUTES_H_
#define _MAINROUTES_H_

#include <string>

namespace handleRoutes
{
    void paresHttpReq(const std::string);

}

#endif

routes.cpp

#include "mainRoutes.h"
#include <iostream>
#include <vector>
#include <string>
#include <boost/algorithm/string.hpp>

namespace handleRoutes
{
    void paresHttpReq(const std::string &rawRequest) {...}

}

server.cpp

#include <iostream>
#include <string>
#include <boost/bind/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <boost/algorithm/string.hpp>
#include "../routes/mainRoutes.h"
        
        ...
        std::array<char, 1024> buffer;
        boost::system::error_code readError;
        size_t bytesRead = socket_.read_some(boost::asio::buffer(buffer), readError);
        std::string rawRequest(buffer.data(), bytesRead);
        handleRoutes::paresHttpReq(rawRequest); <--- error
        ...

CMakeLists.txt

cmake_minimum_required(VERSION 3.12)
project(Blog CXX)

set(CMAKE_CXX_STANDARD 11)

add_library(mainRoutes OBJECT ./routes/mainRoutes.h)

add_executable(main main.cpp $<TARGET_OBJECTS:mainRoutes>)

find_package(Boost REQUIRED COMPONENTS system)

if(Boost_FOUND)
  target_link_libraries(main PRIVATE Boost::system)
endif()

include_directories(${Boost_INCLUDE_DIRS})

I check header files is exist. The namespace is same in all file.

malloc: Double free of object 0x7fbf95f18160 on string to uint64_t [closed]

I am trying to convert response I am getting from jsonrpc lib (string) to uint64_t but am getting malloc error. I am not allocating any memory myself so do not know what to look into exactly

uint64_t getBalance(jsonrpc::Client client, std::string address){
    Json::Value params;
    params.append(address);
    params.append("latest");

    Json::Value response = client.CallMethod("eth_getBalance", params);
    std::cout << response << std::endl;

    if (!response.isNull() && response.isString()) {
            return std::strtoull(response.asCString(), nullptr, 16);
    }

    return 0;
}

The above is my code and it gives me the following after correctly returning the value: rpcClient(21770,0x7ff8530d9680) malloc: Double free of object 0x7fbf95f18160 rpcClient(21770,0x7ff8530d9680) malloc: *** set a breakpoint in malloc_error_break to debug

I am calling the getBalance function in main and printing the balance on console. I am not catching the value in any variable, just calling the function in the std::cout line.

mercredi 24 mai 2023

Is it possible to use the brace initialiser list syntax for private members? [duplicate]

The following code compiles

#include <vector>
struct Foo
{
    int a;
    int b;
};

int main()
{
    std::vector<Foo> foos;
    foos.emplace_back(Foo{1, 2});
}

However, it fails if I replace struct with class1. Aside from doing that (I would like to keep the members private), is there something I can do to enable me to use the Foo{1, 2} notation? I'm keen to avoid writing a constructor for Foo myself.

I'm using C++17 although of course will be interested in general C++ answers.


1 Compile error (MSVC) is

1>c:\...: error C2440: 'initializing': cannot convert from 'initializer list' to 'Foo'
1>c:\...: note: No constructor could take the source type, or constructor overload resolution was ambiguous
1>c:\...: error C2672: 'std::vector<Foo,std::allocator<_Ty>>::emplace_back': no matching overloaded function found
1>        with
1>        [
1>            _Ty=Foo
1>        ]

Compilation failed for type int(&)const

int()const does not make sense for free function but is allowed in c++ type system.

Why do int(&)()const & int(&&)()const cause following compilation error on Clang provided int()const is allowed:

<source>:19:79: error: reference to function type cannot have 'const' qualifier
    static_assert(std::is_same_v<std::add_rvalue_reference_t<int()const>, int(&)()const>);
                                                                              ^
1 error generated.

int()const compiles fine

int main(void) {
    static_assert(std::is_same_v<std::add_rvalue_reference_t<int()const>, int()const>);
    return EXIT_SUCCESS;
}

mardi 23 mai 2023

Does delete free the space allocated by vectors in an array?

Suppose I create an array of vectors, and then I allocate memory for num_vectors many vectors. What happens when delete gets executed after making some push_back operations in random vector elements? I wonder if all the allocated memory (by new and push_back) gets freed.

int num_vectors = 123456;
std::vector<uint64_t>* arr_vecs;
arr_vecs = new std::vector<uint64_t>[num_vectors];

int random_ix;
int random_val = 999;

random_ix = 1;
arr_vecs[random_ix].push_back(random_val);

random_ix = 88;
arr_vecs[random_ix].push_back(random_val);

random_ix = 123;
arr_vecs[random_ix].push_back(random_val);

delete[] arr_vecs;

The question is not about good/bad practices in modern C++. I rather ask a specific question.

It seems like it gets freed, however I would like to have a better intuition about the expected behavior.

What is idea behind calling calling global operator delete from member operator delete?

In Qt's ExternalRefCountData (part of QSharedPtr implementation) https://codebrowser.dev/qt5/qtbase/src/corelib/tools/qsharedpointer_impl.h.html#159

I found code:

  inline void operator delete(void *ptr) { ::operator delete(ptr); }

What is purpose of this code?

I suppose without this line the things would be the same:

auto *d = new ExternalRefCountData;
delete d;//(2)

without ExternalRefCountData::operator delete line (2) should call ::operator delete(ptr); directly, so ExternalRefCountData::operator delete is useless? Or I missed something?

lundi 22 mai 2023

ifstream.read() does not read anything?

I got some file-reading problems in my project, so I wrote following test codes.

I'm tring to read a file by ifstream.read(),but anything has been read.

I've searched numerous related questions, but still can't figure out why my code doesn't work. please help.

#include <iostream>
#include <fstream>

int main() {
    /*--------------- write file ----------------*/
    std::ofstream ofs("testfile", std::ios::binary);
    const char *content = "11223344";
    ofs.write(content, sizeof content);

    system("chmod 777 testfile");

    /*--------------- read file ----------------*/

    char arr[8] = {0};
    const int length = sizeof arr / sizeof arr[0];
    std::ifstream ifs("testfile", std::ios::binary);

    std::cout << "good: " << ifs.good() << std::endl;  // 1

    ifs.seekg(0, ifs.end);
    int file_size = ifs.tellg();
    ifs.seekg(0, ifs.beg);
    std::cout << "file_size: " << file_size << std::endl << std::endl;  // 0

    if (ifs) {
        ifs.read(&arr[0], 2);
        std::cout << "after read," << std::endl;
        std::cout << "gcount: " << ifs.gcount() << std::endl;  // 0
        std::cout << "good: " << ifs.good() << std::endl;  // 0
        ifs.read(&arr[2], 2);
        ifs.read(&arr[4], 2);
        ifs.read(&arr[6], 2);
    } else {
        std::cout << "file not found" << std::endl;
    }

    for (int i = 0; i < length; ++i) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

The output is

good: 1
file_size: 0

after read,
gcount: 0
good: 0
0 0 0 0 0 0 0 0 

dimanche 21 mai 2023

Extern global variable usage in Standard Library

  1. Global Variables are usually discouraged. What is the rational behind Global Variables with external linkage in C++ Standard Library?

  2. Is it true that extern variable is only declaration but not definition?

An example is the gcc implementation of std::call_once in mutex.h Thread local Global Variables with external linkage are declared:

  extern __thread void* __once_callable;
  extern __thread void (*__once_call)();

in

  /// @cond undocumented
# ifdef _GLIBCXX_HAVE_TLS
  // If TLS is available use thread-local state for the type-erased callable
  // that is being run by std::call_once in the current thread.
  extern __thread void* __once_callable;
  extern __thread void (*__once_call)();

  // RAII type to set up state for pthread_once call.
  struct once_flag::_Prepare_execution
  {
    template<typename _Callable>
      explicit
      _Prepare_execution(_Callable& __c)
      {
    // Store address in thread-local pointer:
    __once_callable = std::__addressof(__c);
    // Trampoline function to invoke the closure via thread-local pointer:
    __once_call = [] { (*static_cast<_Callable*>(__once_callable))(); };
      }

    ~_Prepare_execution()
    {
      // PR libstdc++/82481
      __once_callable = nullptr;
      __once_call = nullptr;
    }

    _Prepare_execution(const _Prepare_execution&) = delete;
    _Prepare_execution& operator=(const _Prepare_execution&) = delete;
  };
# else
  // Without TLS use a global std::mutex and store the callable in a
  // global std::function.
  extern function<void()> __once_functor;

  extern void
  __set_once_functor_lock_ptr(unique_lock<mutex>*);

  extern mutex&
  __get_once_mutex();

  // RAII type to set up state for pthread_once call.
  struct once_flag::_Prepare_execution
  {
    template<typename _Callable>
      explicit
      _Prepare_execution(_Callable& __c)
      {
    // Store the callable in the global std::function
    __once_functor = __c;
    __set_once_functor_lock_ptr(&_M_functor_lock);
      }

    ~_Prepare_execution()
    {
      if (_M_functor_lock)
    __set_once_functor_lock_ptr(nullptr);
    }

  private:
    // XXX This deadlocks if used recursively (PR 97949)
    unique_lock<mutex> _M_functor_lock{__get_once_mutex()};

    _Prepare_execution(const _Prepare_execution&) = delete;
    _Prepare_execution& operator=(const _Prepare_execution&) = delete;
  };
# endif
  1. If __once_callable & __once_call are declared but not defined, where are they defined? I didn't find definitions of them in Standard Library header files in devtoolset-11 without extern. Are they defined in source files?

C++11 equivalent of std::apply()? (Plus, how to do it on member functions)

I have my RPC demo program below, but I'm stuck with the problems of reliably pushing parameters into the pipe and pulling them out in the same order.

  • see Serialize() and Invoke() (both the global version and the class centric ones)
  • The "initializer list" method of Serialize() stores the parameters left to right.
  • the "parameter pack expansion" method of Invoke() reads them right to left, which leaves them in reverse order.
    • Problem 1: I believe this is implementation specific
    • Solving it required pushing the parameters in the reverse order with the Reverser class so that when they were pulled out in the right to left order they were in the right parameters.
  • the "initializer list" Invoke() calls the gets the parameters from left to right, but seems to require std::apply() to call the function.
    • Problem 2: I can't upgrade to C++17, so is there a C++11 mechanism that can do what std::apply() is doing? (plus work on member functions as well, which I couldn't figure out the syntax)

TL;DR: I'm trying to come up with a reliable, non-implementation specific way to create some template functions to store their parameters into a pipe and restore them later in the same order and call the function. (All driven by the function's signature).

If all else fails, I have a working solution(using the Reverser class), it just feels hacky.

godbolt here: https://godbolt.org/z/bh4snvn57

#include <stdint.h>
#include <stdio.h>
#include <tuple>
#include <iostream>
#include <cstring>

#define REVERSER 1
#define SHOW_PUSH_PULL 0

//////////////////////////////////////////////////////////////////////
//string hashing operator and function
namespace detail
{
    // FNV-1a 32bit hashing algorithm.
    inline constexpr uint32_t fnv1a_32(char const *s, size_t count) 
    {
        return count ? (fnv1a_32(s, count - 1) ^ s[count - 1]) * 16777619u : 2166136261u;
    }
}    // namespace detail
inline constexpr uint32_t operator"" _hash(const char *  s, size_t count)
{
    return detail::fnv1a_32(s, count);
}
constexpr uint32_t hash(char const *s,size_t count)
{
    return detail::fnv1a_32(s,count);
}
//////////////////////////////////////////////////////////////////////

#if REVERSER
///////////////////////////////////////////////////////////////////////////////////
//Reverser class to reverse the order of parameters 
class Reverser
{
    uint8_t storage[1024+1];
    uint8_t *writeptr;
public:        
    template<typename T>
    void push(T &data)
    {
#if SHOW_PUSH_PULL         
        printf("    Push(%s)\n",typeid(data).name());
#endif        
        writeptr -= sizeof(data);
        memcpy(writeptr,&data,sizeof(data));
    }
    Reverser() {
        writeptr = &storage[1024];
    }
    void GetPtr(uint8_t *&ptr, size_t &bytes)
    {
        ptr = writeptr;
        bytes = uintptr_t(&storage[1024]) - uintptr_t(writeptr);
    }
};
///////////////////////////////////////////////////////////////////////////////////
#endif

///////////////////////////////////////////////////////////////////////////////////
//The "IPC" mechanism
class ByteQueue
{
    uint8_t storage[1024];
    uint8_t *writeptr;
public:        
    void push(uint8_t *pPtr, size_t bytes)    
    {
        memcpy(writeptr,pPtr,bytes);
        writeptr += bytes;
    }
    template<typename T>
    void push(T &data)
    {
        memcpy(writeptr,&data,sizeof(data));
        writeptr += sizeof(data);
    }
    template<typename T>
    void pull(T&data)
    {
        memcpy(&data,storage,sizeof(data));
        uint32_t uAmountToCopy = uintptr_t(writeptr)-uintptr_t(storage)-sizeof(data);
        memmove(storage,storage+sizeof(data),uAmountToCopy);
        writeptr -= sizeof(data);
    }
    ByteQueue() {
        writeptr = storage;
    }
};
ByteQueue g_ByteQueue;


void send_to_IPC_Pipe(uint8_t *pPtr, size_t uLength)
{
   g_ByteQueue.push(pPtr,uLength);
}


template<typename T>
void send_to_IPC_Pipe(T data)
{
#if SHOW_PUSH_PULL && !REVERSER
    printf("    Push(%s)\n",typeid(data).name());
#endif    
    g_ByteQueue.push(data);
}

template<typename T>
T get_from_IPC_Pipe()
{
    T var;
#if SHOW_PUSH_PULL
    printf("    Pull(%s)\n",typeid(T).name());
#endif
    g_ByteQueue.pull(var);
    return var;
}

template<typename ... Args>
void Serialize(uint32_t FunctionID, Args ... args)
{
    send_to_IPC_Pipe(FunctionID);
#if REVERSER    
    Reverser MyReverser;
    
    //push it into the reverser (oddly, it seems the parameters are parsed
    //in reverse order on the way Invoke() call, so we have to reverse them)
    //some magical syntax for C++11
    int dummy[]= { 0,(MyReverser.push(args),0)...};
    //hide the warning
    (void)dummy;

    uint8_t *pPtr;
    size_t uLength;
    MyReverser.GetPtr(pPtr,uLength);
    send_to_IPC_Pipe(pPtr,uLength);
#else
    int dummy[]= { 0,(send_to_IPC_Pipe(args),0)...};
    //hide the warning
    (void)dummy;
#endif
}

template<typename ... Args>
void Invoke(void(*function)(Args...))
{
#if REVERSER    
    function(get_from_IPC_Pipe<Args>()...);
#else
    std::tuple<Args...> args {get_from_IPC_Pipe<Args>()...};
    std::apply(function,std::move(args));    
#endif
}
//////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
void MyFunction(int a, float b, bool c)
{
    printf("ClientSide: %s, %d, %f, %i\n",__PRETTY_FUNCTION__,a,b,c);
    Serialize(hash(__PRETTY_FUNCTION__,strlen(__PRETTY_FUNCTION__)),a,b,c);
}
void MyFunctionServerSide(int a, float b, bool c)
{
    printf("ServerSide: %s, %d, %f, %i\n",__PRETTY_FUNCTION__,a,b,c);
}

void MyFunction2(int a, float b, bool c)
{
    printf("ClientSide: %s, %d, %f, %i\n",__PRETTY_FUNCTION__,a,b,c);
    Serialize(hash(__PRETTY_FUNCTION__,strlen(__PRETTY_FUNCTION__)),a,b,c);
}
void MyFunction2ServerSide(int a, float b, bool c)
{
    printf("ServerSide: %s, %d, %f, %i\n",__PRETTY_FUNCTION__,a,b,c);
}

void MyFunction3(float a, float b)
{
    printf("ClientSide: %s, %f, %f\n",__PRETTY_FUNCTION__,a,b);
    Serialize(hash(__PRETTY_FUNCTION__,strlen(__PRETTY_FUNCTION__)),a,b);
}
void MyFunction3ServerSide(float a, float b)
{
    printf("ServerSide: %s, %f, %f\n",__PRETTY_FUNCTION__,a,b);
}
///////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
void MyFunction4()
{
    printf("ClientSide: %s\n",__PRETTY_FUNCTION__);
    Serialize(hash(__PRETTY_FUNCTION__,strlen(__PRETTY_FUNCTION__)));
}
void MyFunction4ServerSide()
{
    printf("ServerSide: %s\n",__PRETTY_FUNCTION__);
}
///////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////
struct ClientSideClass
{
    template<typename ... Args>
    void Serialize(uint32_t FunctionID, Args ... args)
    {
        auto *pName = typeid(*this).name();
        uint32_t uClassID = hash(pName,strlen(pName));
        send_to_IPC_Pipe(uClassID);
        send_to_IPC_Pipe(FunctionID);
#if REVERSER        
        Reverser MyReverser;
        
        //push it into the reverser (oddly, it seems the parameters are parsed
        //in reverse order on the way Invoke() call, so we have to reverse them)
        //some magical syntax for C++11
        int dummy[]= { 0,(MyReverser.push(args),0)...};
        //hide the warning
        (void)dummy;

        uint8_t *pPtr;
        size_t uLength;
        MyReverser.GetPtr(pPtr,uLength);
        send_to_IPC_Pipe(pPtr,uLength);
#else
        int dummy[]= { 0,(send_to_IPC_Pipe(args),0)...};
        //hide the warning
        (void)dummy;

#endif
    }    
    void Method1(int a)
    {
        printf("ClientSide: %s: %d\n",__PRETTY_FUNCTION__,a);
        Serialize(hash(__PRETTY_FUNCTION__,strlen(__PRETTY_FUNCTION__)),a);
    }
    void Method1(int a,int b)
    {
        printf("ClientSide: %s: %d,%d\n",__PRETTY_FUNCTION__,a,b);
        Serialize(hash(__PRETTY_FUNCTION__,strlen(__PRETTY_FUNCTION__)),a,b);
    }

    void Method2(int a,int b)
    {
        printf("ClientSide: %s: %d,%d\n",__PRETTY_FUNCTION__,a,b);
        Serialize(hash(__PRETTY_FUNCTION__,strlen(__PRETTY_FUNCTION__)),a,b);
    }

};

struct ServerSideClass
{
    template<typename ... Args>
    void Invoke(void(ServerSideClass::*function)(Args...))
    {
#if REVERSER        
        (*this.*(function))(get_from_IPC_Pipe<Args>()...);
#else
        std::tuple<Args...> args {get_from_IPC_Pipe<Args>()...};
        std::apply(function,std::move(args));
#endif
    }    
    void Method1(int a)       { printf("ServerSide: %s: %d\n",__PRETTY_FUNCTION__,a); }
    void Method1(int a,int b) { printf("ServerSide: %s: %d,%d \n",__PRETTY_FUNCTION__,a,b); }
    void Method2(int a,int b) { printf("ServerSide: %s: %d,%d \n",__PRETTY_FUNCTION__,a,b); }
    void InvokeIt()
    {
        uint32_t uFunctionID = get_from_IPC_Pipe<uint32_t>();
        switch (uFunctionID)
        {
            case "void ClientSideClass::Method1(int)"_hash:
                {
                    void (ServerSideClass::*function)(int) = &ServerSideClass::Method1;
                    Invoke(function);
                }
                break;                    
            case "void ClientSideClass::Method1(int, int)"_hash:
                {
                    void (ServerSideClass::*function)(int,int) = &ServerSideClass::Method1;
                    Invoke(function);
                }
                break;                    
            case "void ClientSideClass::Method2(int, int)"_hash:
                Invoke(&ServerSideClass::Method2);
                break;                    
            default:
                printf("Unknown method\n");
        }
    }
};

///////////////////////////////////////////////////////////
ServerSideClass g_ServerSide;
void runRPCs()
{
    uint32_t uFunctionID = get_from_IPC_Pipe<uint32_t>();
//    printf("runRPC:function id(%u)\n",uFunctionID);
    switch (uFunctionID)
    {
        case "15ClientSideClass"_hash:
            g_ServerSide.InvokeIt();
            break;
        case "void MyFunction(int, float, bool)"_hash:
            Invoke(MyFunctionServerSide);
            break;
        case "void MyFunction2(int, float, bool)"_hash:
            Invoke(MyFunction2ServerSide);
            break;
        case "void MyFunction3(float, float)"_hash:
            Invoke(MyFunction3ServerSide);
            break;
        case "void MyFunction4()"_hash:
            Invoke(MyFunction4ServerSide);
            break;
        default:
            printf("Unknown function id\n");
            break;
    }
}

int main()
{
    ClientSideClass client;
//    auto *pName = typeid(ClientSide).name();
//    printf("--%s--\n",pName);
//    printf("%u\n","10ClientSide"_hash);
//    printf("%u\n",hash(pName,strlen(pName)));
    MyFunction(2,4.33,true);
    MyFunction4();
    MyFunction2(4,-4.33,false);
    MyFunction3(3.144,-4.33);
    client.Method1(5);
    client.Method1(3,7);
    client.Method2(8,9);
    runRPCs();
    runRPCs();
    runRPCs();
    runRPCs();
    runRPCs();
    runRPCs();
    runRPCs();
    return 0;
}

vendredi 19 mai 2023

boost::to_lower_copy() too expensive as it extracts a facet from the passed locale

I've got std::use_facet<std::ctype<char> > showing up in a profiler. It is called indirectly from boost::to_lower_copy(). I remember fixing this for a comparison operator by storing the reference returned from std::use_facet<> only once and repeatedly calling facet.tolower(char) with it, avoiding repeated calls to std::use_facet<>. Is there a way to avoid this short of writing one's own to_lower(const std::string&) function?

jeudi 18 mai 2023

C++ callback timer with start/stop functions

I need to create a class to replicate the functionality of a callback timer from a library I no longer have access to.

Basically, spawn an asynchronous thread that executes some function after a timeout is reached. However, if some condition is met before the timeout, the function is not executed, and the timer is cancelled.

I am not sure how to "stop" the timer based on some condition.

This is what I have so far (based on the answer to this post C++ Non-blocking async timer by wally)

#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>

class Timer 
{
public:

   Timer(size_t time, const std::function<void(void)>& callback) : 
      time(std::chrono::milliseconds(time)),
      callback(callback) {}

   ~Timer() 
   { 
      if (started) 
      { 
         wait_thread.join(); 
         started = false; 
      } 
   }

   // TODO: Implement stop()
   void stop()
   {
      // ???
   }

   // TODO: Implement start()
   void start()
   {
      if (!started)
      {
         started = true;
         wait_thread = std::thread{ [this]() { wait_then_call(); } };
      }
      else
      {
         std::cout << "Thread " << wait_thread.get_id() << " already been started! " << std::endl;
      }
   }

private:

   void wait_then_call()
   {
      std::unique_lock<std::mutex> lck(mtx);
      for (int i = 10; i > 0; --i)
      {
         std::cout << "Thread " << wait_thread.get_id() << " countdown at: " << '\t' << i << std::endl;
         cv.wait_for(lck, time / 10);
      }
      callback();
   }

   std::mutex mtx;
   std::condition_variable cv{};
   std::chrono::milliseconds time;
   std::function <void(void)> callback;
   std::thread wait_thread;
   bool started = false;

};

Testing:

int main()
{
   auto f = []() {std::cout << "Executing Callback Function"; };

   Timer t1{ 3000, f };
   t1.start();

   Timer t2{ 10000, f };
   t2.start();

   // main thread is free to continue doing other things
}

How can I compile and generate libraries of boost version 1.82.0 in Aix?

Compiling the boost C++ library 1.82.0 on AIX 7.2 using xlclang++

I am trying to build the b2 binary using xlclang++ but getting std errors

class.cpp:
warning: unknown warning option '-WL' [-Wunknown-warning-option]
/usr/include/sys/inttypes.h:98:18: error: 'short wchar_t' is invalid
typedef unsigned short  wchar_t;                ^
/usr/include/sys/inttypes.h:98:1: warning: typedef requires a name [-Wmissing-declarations]
typedef unsigned short  wchar_t;
object.h:62:38: error: use of undeclared identifier 'std'
        inline explicit object(const std::string &val)`
                                     ^

mercredi 17 mai 2023

What is the difference between & and && [closed]

What is the difference between the & and && operators in C++11?

According to the docs, && acts as an rvalue reference. It may be used in-conjunction with std::move to reference expressions (whether they have an identity or not).

& is also acting as a rvalue reference. It is used to reference an lvalue (object with an identifiable location in memory). Therefore & cannot be used with expressions.

Is this correct?

Shared Memory: Consumer process of shared memory does not read the data from memory region

I am working on a gstreamer based streaming application. I have created set of gstreamer plugins as per project requirements. I am facing a challenge of sharing data between the main application and one of the gstreamer plugin. I have tried different IPC mechanisms such as files, namedPipes and message queues. These IPC mechanisms do not cater solution to my problem. I am finally using shared memory to transfer data from the main application to the plugin. I need to pass a struct data that contains 4-5 integer array variables.

My main application is producer of the data and plugin is the consumer.

The below code is for the producer:

#ifndef __IPC_SHMW__
#define __IPC_SHMW__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>

typedef struct {
  int x[20];
  int y[20];
  int w[20];
  int h[20];
  int num;
} send_data_WR; 

class IPC_DATA_SEND {
        public:
                int shmid;
                key_t key = 1996;
                send_data_WR *_data;

                int create_shm(){
                        shmid = shmget(key, sizeof(send_data_WR), IPC_CREAT | 0666);
                        printf("SHMID Write Process %d \n",shmid);
                        if (shmid < 0) {
                                perror("shmget");
                                exit(1);
                        } 
                        _data = (send_data_WR*) shmat(shmid, NULL, 0);
                        if (_data == (send_data_WR *) -1) {
                                perror("shmat");
                                exit(1);
                        }
                        //std::cout << "SHMID Write Address " << _data << std::endl;
                        printf("SHMID Write Address %x \n", _data);
                }

                int write_data(send_data_WR * data){
                        _data->num = data->num;
                        for(int i=0; i<data->num; i++){
                                _data->x[i] = data->x[i];
                                _data->y[i] = data->y[i];
                                _data->w[i] = data->w[i];
                                _data->h[i] = data->h[i];
                                printf("Write: x=%d y=%d w=%d h=%d \n", _data->x[i], _data->y[i], _data->w[i], _data->h[i]);
                        }
                        sleep(1);
                        return 0;
                }

                int clean_shm(){
                        // Detach shared memory segment
                        shmdt(_data);
                        // Remove shared memory segment
                        shmctl(shmid, IPC_RMID, NULL);
                        return 0;
                }
};

#endif

The below code is for the consumer plugin:

#ifndef __IPC_SHMR__
#define __IPC_SHMR__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>


typedef struct {
  int x[20];
  int y[20];
  int w[20];
  int h[20];
  int num;
} read_data_WR; 

class IPC_DATA_READ {
        public:
                int shmid;
                key_t key = 1996;
                read_data_WR *_data;

                int read_shm(){
                        shmid = shmget(key, sizeof(read_data_WR), 0);
                        printf("SHMID Read Process %d \n",shmid);
                        if (shmid < 0) {
                                perror("shmget");
                                exit(1);
                        }

                        _data = (read_data_WR*) shmat(shmid, NULL, 0);
                        if (_data == (read_data_WR *) -1) {
                                perror("shmat");
                                exit(1);
                        }
                        printf("SHMID Read Address %x \n",_data);
                }

                int read_data(read_data_WR * data){
                        printf("Inside Read Data SHM \n");
                        printf("[Read SHM] num = %d \n", _data->num);
                        data->num = _data->num;
                        printf("[Read SHM] data num = %d \n", data->num);
                        for(int i=0; i<data->num; i++){
                                data->x[i] = _data->x[i];
                                data->y[i] = _data->y[i];
                                data->w[i] = _data->w[i];
                                data->h[i] = _data->h[i];
                                printf("Read: x=%d y=%d w=%d h=%d \n", data->x[i], data->y[i], data->w[i], data->h[i]);
                        }
                        return 0;
                }

                int clean_shm(){
                        // Detach shared memory segment
                        shmdt(_data);
                        // Remove shared memory segment
                        shmctl(shmid, IPC_RMID, NULL);
                        return 0;
                }
};

#endif //__IPC_SHMR__

There are no issues with the compilation. The code compiles successfully and when I start the main application, the producer code starts writing to the shared memory region.

I could verify it by set of print statements. However, when I start the working of my plugin (consumer), there is no data available. The print statements just print 0.

I checked the fd & the address locations of the data pointed by the pointer of each process and I see the fd has different values and pointers are pointing to different addresses.


SHMID Write Process 0
SHMID Write Address 8a087000
...
SHMID Read Process 1
SHMID Read Address 8a05c000

I tried figuring out what might be the issue.

I have not found any solution online and i am not able to get to the root cause of the problem. Can someone help me, in understanding what i am doing wrong.

Thanks

mardi 16 mai 2023

Error when using C++11 List Initialization Syntax g++ compiler

When I use list initialization to init my class members, the complier complains it's a function.

The g++ output:

$ g++ main.cpp -o main 
In file included from main.cpp:1:
./Cat.h:9:9: error: function definition does not declare parameters
    int age{};
        ^
...

compiler version:

$ g++ -v            
Apple clang version 14.0.3 (clang-1403.0.22.14.1)
Target: arm64-apple-darwin22.4.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

source doe, Cat.h:

...
class Cat {
private:
    int age{};
    std::string name{};
public:
    Cat(int age, std::string name) : age(age), name(std::move(name)) {
        std::cout << "Cat: Constructor with two parameter is called" << std::endl;
    }
...
};

main.cpp

#include "Cat.h"

Cat getCat() {
    Cat cat{1, "Kitty"};
    return cat;
}

int main() {
    Cat cat = getCat();
    return 0;
}

Getting Error while running thread on a overloaded functions

static bool breakThread= false;

void TestMeUsingMiltiThreading(unsigned int uParentID)
{
    std::cout << "Thread " << uParentID << " Invoked Current thread " << std::this_thread::get_id();
    using namespace std::literals::chrono_literals;
    while (!breakThread)
    {
        std::cout << "Thread " << std::this_thread::get_id() << " is working..." << std::endl;
        std::this_thread::sleep_for(1s);//Thread wait for 1s before contuning further
    }
}
void TestMeUsingMiltiThreading()
{
    std::cout << "Current thread id is=" << std::this_thread::get_id();
    using namespace std::literals::chrono_literals;
    while (!breakThread)
    {
        std::cout << "Thread "<< std::this_thread::get_id() <<" is working..."<< std::endl;
        std::this_thread::sleep_for(1s);//Thread wait for 1s before contuning further
    }
}

.
.
.
int main()
{
.
.
.
std::thread worder(TestMeUsingMiltiThreading); //error here
.
.
.
}

Error: E0289 no instance of constructor "std::thread::thread" matches the argument list

How to fix this, I want to run threads over overloaded functions

Smooth step slow to fast [closed]

Всем привет, есть функция Lerp(float a, float b, float t) {return a + (b - a) * t} Она мне нравиться для использования анимаций интерфейса или прочих задач, но мне понадобилась функция которая будет вместо того чтобы переходит с быстрой на медленную скорость, переходила с медленного на быструю.

Не нашел не одной такой функции

why vector

From CppReference Value initialization:

This is the initialization performed when an object is constructed with an empty initializer.

Syntax

(1)   T ()
(2)   new T ()
(3)   Class::Class(...) : member () { ... }
(4)   T object {}; (since C++11)
(5)   T {} (since C++11)
(6)   new T {} (since C++11)
(7)   Class::Class(...) : member {} { ... } (since C++11)

Explanation

Value initialization is performed in these situations:

  • (1), (5) when a nameless temporary object is created with the initializer consisting of an empty pair of parentheses or braces (since C++11);
  • (2), (6) when an object with dynamic storage duration is created by a new-expression with the initializer consisting of an empty pair of
    parentheses or braces (since C++11);
  • (3), (7) when a non-static data member or a base class is initialized using a member initializer with an empty pair of parentheses or braces (since C++11);
  • (4) (since C++11) when a named object (automatic, static, or thread-local) is declared with the initializer consisting of a pair of braces.

This is fine as vector<T> v{}; seems has syntax (4).

Then it says

The effects of value initialization are:

    1. if T is a class type with no default constructor or with a user-declared (until C++11)user-provided or deleted (since C++11) default constructor, the object is default-initialized;
    1. if T is a class type with a default constructor that is not user-declared (until C++11)neither user-provided nor deleted (since C++11) (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;
    1. if T is an array type, each element of the array is value-initialized;
    1. otherwise, the object is zero-initialized.

I assume this falls into case 2 as vector<T> has a default constructor that takes 0 parameter. Then this 'vector v' shall be zero-initialized, instead of default-initialized?

lundi 15 mai 2023

Create protected function in base class and receive slots as arguments

I have created a base and derived class. Both have some common code which differs only in the slots when I have use connect. I intend to create a common function which is protected and takes as an argument the slot function pointer.

class Base
{
protected:
virtual void createcommon(void(*)(int));

slots:
void slotBase(int);
};

class Derived
{
slots:
void slotDerived(int);
}

void Base::createcommon(void(*slotPtr)(int))
{
//some common stuff
connect(m_comboBox, QOverload<int>::of(&QComboBox::ACurrentIndexChanged), this, slotPtr);
}

void Base::xyz()
{
createcommon(&Base::slotBase); //does not work, compiler says "argument of type void (Base::*)(int) is incompatible with type void (*)(int).
}

void Derived::func()
{
createcommon(&Derived::slotDerived); //does not work, compiler says "argument of type void (Derived::*)(int) is incompatible with type void (*)(int).
}

Is it possible to do so via function pointers? Otherwise the option left is to create a second virtual function like virtual void initConnect() in both Base and Derived classes to connect appropriately.

Hey mansi do you have idea about BLE technology [closed]

BLE technology scanning advertising connection do you know that type of developing

One device source & other is slave.your text

Composite Design Pattern Inheritance [duplicate]

I wrote an inventory system to learn the composite design pattern. I apologize for the format this is my first post.

#pragma once
class InventoryManager
{
public:
    virtual int ReturnInventoryCostTotal() { return 0; };
    virtual void AddItem(InventoryManager a) {};
    virtual void RemoveItem() {};
};
////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "InventoryManager.h"
#include <vector>
class Shelf : public InventoryManager
{
public:
    std::vector<InventoryManager> inventory;
    int ReturnInventoryCostTotal()override;
    void AddItem(InventoryManager a)override;
    void  RemoveItem()override;
};
//////////////////////////////////////////////////////////////////////////////////////
#include "shelf.h"
#include <iostream>
int Shelf::ReturnInventoryCostTotal()
{
    int numberOfItemsInInventory = inventory.size();
    int total = 0 ;
    for (int i = 0; i < numberOfItemsInInventory; i++)
    {
        total = total + inventory[i].ReturnInventoryCostTotal();
    }
    std::cout << total << std::endl;
    return total;
}

void Shelf::AddItem(InventoryManager a)
{
    inventory.push_back(a);
}

void Shelf::RemoveItem()
{
}
/////////////////////////////////////////////////////////////////////////
#pragma once
#include "InventoryManager.h"
class Item : public InventoryManager
{
public:
 int cost;
 Item(int cdst) { cost = cdst; };
 int ReturnInventoryCostTotal()override;
 void AddItem(InventoryManager a)override;
 void RemoveItem()override;
};

#include "Item.h"
int Item::ReturnInventoryCostTotal()
{
    return cost;
}

I am trying to call the Item classes ReturnInventoryCostFunction but I keep calling the base Class function. The goal is to be able to get the total of all the items on a shelf. I dont think including the main() is necessary I know I am adding the items to the shelf correctly and have verified that the Shelf.ReturnInventoryCostFunction IS calling the base class InventoryManagers function instead of item to get the cost.

prog.cpp:49:9: error: expected initializer before * token Node*insertAtEnd(Node *head, int x) { ^ [closed]

class Solution{
  public:
    //Function to insert a node at the beginning of the linked list.
    Node *insertAtBegining(Node *head, int x) {
       Node *curr = new Node(x);
       curr->next=head;
       return curr;
     }
    }
    
    
    //Function to insert a node at the end of the linked list.
    Node *insertAtEnd(Node *head, int x)  {
      
        if(head==NULL){
            Node *curr=Node(x);
            return curr;
            
        }
        Node *curr=head;
        while(curr->next!=NULL){
            curr=curr->next;
        }
        curr-next=new Node(x);
        return head;
    }
};

I don't understand the error.

In C++ Inheritance, Derived class destructor not called when pointer object to base class is pointed to array of derived class

I have an Animal class with constructor and destructor. Cat have a private Brain* attribute. Upon construction, Cat creates his Brain using new Brain(); Upon destruction, Cat deletes his Brain. I don't understand why The cat's and brain's destructors not called, when my Base class destructor is virtual?

#include <iostream>

using std::cout ;
using std::endl ;

class Brain {
public:
    Brain (void){cout << "Brain constructor" << endl ;}
    ~Brain (void){cout << "Brain destructor" << endl ;}
} ;

class Animal
{
public:
    Animal (void){cout << "Animal constructor" << endl ;}
    virtual ~Animal (void){cout << "Animal destructor" << endl ;}
} ;

class Cat : public Animal
{
public:
    Cat (void){
                cout << "Cat constructor" << endl ;
        myPointer = new Brain() ;
    }
    ~Cat (void){
        cout << "Cat destructor" << endl ;
        delete myPointer ;
    }
private:
    Brain* myPointer ;
} ;

int main()
{
    const Animal* j = new Cat[1] ;
    delete [] j ;
}

Gives output

Animal constructor
Cat constructor
Brain constructor
Animal destructor

dimanche 14 mai 2023

Binding arbitrary function in wxwidgets

I want to create a number of composite objects, each containing a scrolled list and some buttons (for my example, I've reduced the code to creating just one of the objects with just one button). All of these objects will be very similar, except for the layout, size, and the functions called by the buttons (i.e. for each object, the callback for the same button can be different).

So, in the constructor for these composite objects, I want to receive the functions to bind to the buttons (again, in my example, it will be one button).

I have an example version that works (without the Bind function being passed), and an example that won't compile when I try to add the code passing in the function to Bind.

Here's the compiler error:

stack2.cpp: In constructor ‘MainPanel::MainPanel(wxFrame*)’:
stack2.cpp:106:94: error: no matching function for call to ‘MyAddRemoveList::MyAddRemoveList(MainPanel*, const char [12], const char [11], int, int, int, bool, void (MyAddRemoveList::*)(wxCommandEvent&))’
  106 | xLB_MULTIPLE | wxLB_HSCROLL | wxLB_NEEDED_SB, false, &MyAddRemoveList::OnAddToList);
                                                                           1,68          Top
tack2.cpp:61:1: note: candidate: ‘MyAddRemoveList::MyAddRemoveList(wxWindow*, const char*, const char*, int, int, long int, bool, func)’
   61 | MyAddRemoveList::MyAddRemoveList(wxWindow *panel, const char *display_name,
      | ^~~~~~~~~~~~~~~
stack2.cpp:62:79: note:   no known conversion for argument 8 from ‘void (MyAddRemoveList::*)(wxCommandEvent&)’ to ‘func’ {aka ‘void (*)(wxCommandEvent&)’}
   62 |       const char *table_name, int w, int h, long style, bool do_extract, func fpt) :
      |                                                                          ~~~~~^~~
stack2.cpp:41:7: note: candidate: ‘MyAddRemoveList::MyAddRemoveList(const MyAddRemoveList&)’
   41 | class MyAddRemoveList : public wxBoxSizer {
      |       ^~~~~~~~~~~~~~~
stack2.cpp:41:7: note:   candidate expects 1 argument, 8 provided
stack2.cpp:41:7: note: candidate: ‘MyAddRemoveList::MyAddRemoveList(MyAddRemoveList&&)’
stack2.cpp:41:7: note:   candidate expects 1 argument, 8 provided
make: *** [stack2.make:94: stack2.o] Error 1

I don't understand why the compiler can't cast void (*)(wxCommandEvent&) to void (MyAddRemoveList::*)(wxCommandEvent&). This is my problem.

Notes:

  • I'm new to stackoverflow, so please have mercy.
  • I'm completely new to both c++ and wxwidgets, so please have mercy.
  • I have pruned the code down to a minimal version (one that "works" without the Bind, and one with Bind that won't compile). But again, they're each about 100 lines and I don't know if that's too long to include in a question here.
  • POP OS 22.04
  • wxwidgets 3.0

Any help/suggestions would be much appreciated. Thanks in advance...

thread_local is equal to automatic variables ? What is the actual use of thead_local?

What is the actual need of thread_local, they get created when thread is created and destroyed when thread is finished, so do automatic variables, so what makes thread_local special ? Why do we need them ?

samedi 13 mai 2023

Correct template definition to wrap class member functions

I looked up to this and this SO answers, but none solves my problem.

Short description: the template function, where much more should happen than just that of this example, should be able to wrap any other function, also function members of a class.

Minimal working example:

#include <iostream>

template <typename T, typename ...ArgsT>
T wrapper(T(*func)(ArgsT...), ArgsT... args)
{
    return func(args...);
}

class TestClass
{
public:
    int mult_by_2_member(int a)
    {
        return a * 2;
    }

    static int mult_by_2_static(int a)
    {
        return a * 2;
    }

    void wrap_funcs()
    {
        // std::cout << "Wrapped member = " 
        //           << wrapper(&mult_by_2_member, 2)  // Prob: cannot convert `int(TestClass::*)(int) to int(*)(int)`
        //           << std::endl;
        std::cout << "Wrapped static = " << wrapper(mult_by_2_static, 2) << std::endl;
    }
};

int main()
{
    TestClass test_instance;
    test_instance.wrap_funcs();
    // skipping wrapping of a global function... that works correctly
}

The error message, as posted in the snippet above, is obvious. But I did not yet figure out how to solve it, or even whether the whole starting logic or intent is valid.

Any solution suggestions or sources of information?


EDIT

A possible solution would be:

/* as above */
static int mult_by_2_static(TestClass* p, int a)
{
   return p->mult_by_2_member(2);
}

void wrap_funcs()
{
    // std::cout << "Wrapped member = " << wrapper(&mult_by_2_member, 2) << " = " << std::endl;
    std::cout << "Wrapped static = " << wrapper(mult_by_2_static, this, 2) << std::endl;
}

But then I would have to "pre-wrap" all target member functions into static ones, which is a lot of boilerplate.

Why does A inter-thread happens-before C?

"if A synchronizes with B and B is sequenced before C, then A inter-thread happens-before C". What confuses me is that B and C are in the same thread. The compiler or CPU can reorder the instruction. why does A inter-thread always happen-before C? It seems that sequence-before makes no sense since reordering can happen.

vendredi 12 mai 2023

Auto registration of types with C++ ODR use

I'm trying to get a demo code working to show auto registration with the help of ODR use (I've only learned about this in the last day so forgive me if I'm not using that correctly).

This is the interesting bits of the code

// Interface for the class.
class ICompressionMethod {
 public:
  ICompressionMethod() = default;
  virtual ~ICompressionMethod() = default;

  virtual void Compress() = 0;
};

// Helper class holding static methods for factory
class CompressionMethodFactory {
 public:
  using TCreateMethod = std::unique_ptr<ICompressionMethod> (*)();

 public:
  CompressionMethodFactory() = delete;

  static bool Register(const std::string name, TCreateMethod createFunc) {
    if (auto it = s_methods.find(name); it == s_methods.end()) {
      s_methods[name] = createFunc;
      std::cout << name << " registered\n";
      return true;
    }
    return false;
  }

  static std::unique_ptr<ICompressionMethod> Create(const std::string& name) {
    if (auto it = s_methods.find(name); it != s_methods.end())
      return it->second();

    return nullptr;
  }

 private:
  static std::map<std::string, TCreateMethod> s_methods;
};


std::map<std::string, CompressionMethodFactory::TCreateMethod>
    CompressionMethodFactory::s_methods;



template <bool*>
struct OdrUse {};

template <typename T>
class RegisteredInFactory {
 protected:
  static bool s_bRegistered;
  static constexpr OdrUse<&s_bRegistered> odr{};
};


template <typename T>
bool RegisteredInFactory<T>::s_bRegistered =
    (CompressionMethodFactory::Register(T::kFactoryName, T::CreateMethod),
     true);


class ZipCompression : public ICompressionMethod,
                       public RegisteredInFactory<ZipCompression> {
 public:
  static constexpr const char* kFactoryName = "ZIP";
  void Compress() override {
    // if (s_bRegistered) std::cout << "registered\n";
    std::cout << "in compress\n";
  }

  static std::unique_ptr<ICompressionMethod> CreateMethod() {
    return std::make_unique<ZipCompression>();
  }
  static std::string GetFactoryName() { return "ZIP"; }
};

int main(int argc, char* argv[]) {

  std::cout << "main starts...\n";
  auto pMethod = CompressionMethodFactory::Create("ZIP");
  if (pMethod != nullptr) {
    pMethod->Compress();
  } else {
    std::cout << "factory creation failed\n";
  }
  std::cout << "end" << "\n";
  return 0;
}

Lot of the code has been copied from https://www.cppstories.com/2018/02/factory-selfregister/

I'm getting this error when compiling

$ g++ test_odr.cc
test_odr.cc: In instantiation of ‘bool RegisteredInFactory<ZipCompression>::s_bRegistered’:
test_odr.cc:50:27:   required from ‘class RegisteredInFactory<ZipCompression>’
test_odr.cc:59:31:   required from here
test_odr.cc:55:44: error: incomplete type ‘ZipCompression’ used in nested name specifier
   55 |     (CompressionMethodFactory::Register(T::kFactoryName, T::CreateMethod),
      |                                            ^~~~~~~~~~~~
test_odr.cc:55:61: error: incomplete type ‘ZipCompression’ used in nested name specifier
   55 |     (CompressionMethodFactory::Register(T::kFactoryName, T::CreateMethod),
      |                                                             ^~~~~~~~~~~~

Looking at the error, why does the compiler need RegisteredInFactory<ZipCompression> fully defined to access kFactoryName ?

Higher order functions in C++: Creating an integrator that accepts member functions

I would like to create a function-object class that numerically integrates some functions on-demand. Its public interface would consist of a method void T::step(double dt) that computes an integration step (and updates the internal state of the function-object with the new values), and getters to the current calculated values.

While I'm sure this could be done with pure stand-alone functions, the functions I'll be integrating have many intermediate calculation steps in common, and depend on many internal parameters which must be updated on every step (and are largely irrelevant to the user), so I thought of using a function-object to encapsulate this mechanism.

But now I've found myself wrestling the type-system, trying to define a function double integrate(double t, double dt, METHOD f) to actually compute each individual function's integration step, accepting member functions as arguments.

I've come up with

template <typename T>
double integrate(double t, double dt, double (T::*f)(double), T* obj)
{
  // Here I can reference `obj->*f(...)`
}

but I'm a bit uneasy, as it seems contrived and some people make it seem like function pointers are the devil when it comes to performance.

Using only C++11 features, is there a cleaner, more performant or more idiomatic approach to this?

what is the way to use class instance (no copy ctor ) for lambda used in condition variable wait_util? [duplicate]

code snippet looks like: //main.cpp:

in main()
{
   Demo demo; //Instance for class Demo

   while(1)
   {
     std::mutex cv_m;
     std::unique_lock<std::mutex> lock(cv_m);
     std::chrono::seconds time_period(20);
     auto time_duration = std::chrono::system_clock::now() + time_period;

     //this is wrong, but just show what I want to do
     if(demo.cond_var.wait_util(lock, timeDuration, [demo, event_num](){return demo.getEventNum() == event_num; })){
       std::cout<<" Reach the points!"<<std::endl;
       break;
     }
    else{
       std::cout<<"Timed out!"<<std::endl;
       break;
    }


   }

}

The purpose is to keep checking the event number (which will be updated by other threads), if it reaches to 20, break from the loop or till it times out.

Above code failed to compile with error: use of deleted function Demo(const Demo&) So my question is if without copy ctor, is there a way to do what I want to do? I may not able to allow to add the copy ctor for the class.

Thanks.

difference between introducing using std::cout vs std::string::size_type to a source file

I have been using using std::cout; or using std::cin, etc., to introduce the names successfully to a source file and use them further in the functions of the file. I tried to do the same with std::string::size_type and ended up getting 'error: using-declaration for member at non-class scope' in gcc and 'error: not a valid using-declaration at non-class scope' in MSVC compiler.

Here is the link to the code I have written : https://onlinegdb.com/-c6sJuZdrV.

Following is the relevant excerpt from it.

#include <iostream>
#include <string>

using std::cout;
using std::cin;
using std::endl;
using std::string;
using std::string::size_type;

void Part_2()
{
   string s1, s2;
   cout << "Enter the first string" << endl;
   cin >> s1;
   cout << "Enter the second string" << endl;
   cin >> s2;
   size_type s1Size = s1.size();
   size_type s2Size = s2.size();
}

I expected using std::string::size_type; to work just like using std::cout;. I found this Using declaration for a class member shall be a member declaration (C++2003) related question, but that's for a different use-case.

How can I make my code work?

jeudi 11 mai 2023

How to remove Tight coupling from the below code [closed]

How can I remove the tight coupling between Foo and Boo classes?

class Boo;

class Foo {
private:
        Boo *x;
    public:
        static void Print(Boo *b) { cout << "Some Solution " << endl; } 
};

class Boo {
    public:
        void Print() {Foo::Print(this); }
};


int main ()
{
    Boo *b = new Boo;
    b->Print();
    return 0;
}

How can I remove the tight coupling between Foo and Boo classes?

How can I unpack variadic template, so as to initialize respective members?

I am new to variadic templates and packed arguments and all. I want to have a "entity component system" in my program, and while trying to add component to the entity, I came to realize that my attempt has a major flaw.

Anyways here is my failed attempt.

struct A{
    float x;
    float y;
    
    A(float _x, float _y):x(_x), y(_y){}
};

struct B{
    float x;
    float y;
    float z;
    
    B(float _x, float _y, float _z):x(_x), y(_y), z(_z){}
};

struct Entity{
    A* a = NULL;
    B* b = NULL;
    
    Entity(){}
    
    template<typename T, typename... args>
    void Add(args... _args){
        if(typeid(T) == typeid(A))
            a = new A(_args...);
        else if(typeid(T) == typeid(B))
            b = new B(_args...);
        else
            throw("Invalid component added");
    }
};

And implementation looks like this..

Entity ent;
ent.Add<A>(12.24f, 123.246f);
ent.Add<B>(1.f, 1.2f, 1.23f);

I want the implementation to work somehow.. what has to be changed for it??

Whenever I run this code, score 1 gives some obscene number, and Im not sure how to fix it [closed]

I've tried to fix this issue by defining int score_1 and int score_2 in different forms, but It still doesn't work.

I update int score_1 to be 10 when running, and int score_2 to 5 while running, yet when I ask for display int score_1 gives an obscene number. I'm relatively new to this, so I'm sorry if this is an easy fix. I'm not sure if this is something can be done, or if this is something that requires numerous files.

I have attempted to give the variable an assigned integer (int_score1 = 0;) however this leads to my program assuming int_score1 is consistently 0.

#include <iostream>
#include <cmath>
#include <climits>
#include <float.h>
#include <string>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <array>
#include <fstream>
#include <memory>


using std::cout;
using std::cin;
using std::string;
using std::endl;
using std::hex;
using std::oct;
using std::array;
using std::ifstream;
using std::ofstream;
using std::vector;
using std::fstream;

void charades()
{
    int choice;
    int score_1;
    int score_2;
    cout << "Press 0 to quit" << endl;
    cout << "Press 1 to add a point to Team 1" << endl;
    cout<< "Press 2 to add a point to Team 2" << endl;
    cout << "Press 3 to display totals of Both Teams" << endl;
    cin >> choice;
    switch(choice)
    {
        case 0:
        cout << "Goodbye!" << endl;
        exit(0);
        break;
        case 1:
        score_1 += 1;
        break;
        case 2:
        score_2 +=1;
        break;
        case 3:
        if ( score_1>score_2)
        {
            cout << "Team 1 is beating Team 2 " << endl;
            cout << score_1<< " to " << score_2 << endl;
            //score 1 is giving long number
        };
        if (score_1< score_2)
        {
            cout << "Team 2 is beating Team 1 "<< endl;
            cout << score_2 << " To "<< score_1<< endl;
            //score 1 is giving long number
        };
        if(score_1==score_2)
        {
            cout<<"Both teams are tied at "<< score_1 << " !"<< endl;
            //works
        };
    
    
    
    }
};

int main()
{
    int choice;
    cout << "Would you like to score?\n 1. Charades" << endl;
    cin >> choice;
    do
    {
        switch(choice)
        {
            case 0:
            cout << "Goodbye!";
            exit(0);
            break;
            case 1:
            charades();
            break;
        }
    }
    while (choice !=0);

}

Flash an active Qt tree widget item green

I would like to flash (between green & white) an active item in my QTreeWidget in Qt. This means it should stop flashing the previous items that were active once. I have tried the following and not had it working as I want it. Please help.

**void Dialog::slotTestRunUpdate(QString sTestName)
{**
    QHashIterator<QString, QWidget*> hashIt(treeFormHash); //iterator for testnames and test forms// 
    //e.g treeFormHash.insert("Test 1",    pCTest1FormObj);
    treeFormHash.insert("Test 2",    pCTest2FormObj);
    treeFormHash.insert("Test 3",    pCTest3FormObj);
    treeFormHash.insert("Test 4",    pCTest4FormObj);
    treeFormHash.insert("Test 5",    pCTest5FormObj);//

    QTreeWidgetItemIterator treeIt(ui->treeWidget); //iterator for items in QTreeWidget
    //Store a pointer to the last active item
    QTreeWidgetItem* prevItem = nullptr;

    while(*treeIt) //Search for an existing item with the specified text//
    {
        QTreeWidgetItem* item = *treeIt;
        ui->treeWidget->clearSelection();

        if(item->text(0) == sTestName) {
            qDebug() << "treeIt=" << item->text(0) << "\r\n";

            //A timer to flash between green and white//
            QTimer *timer = new QTimer(this); //a timer object

            timer->setInterval(1000); //interval of 1s
            timer->start(); //start timer

            //When the timer times out, it toggles the background color of the active item between green and white.
            //The timer is connected to a lambda function that captures the item variable by value.
            //The lambda function checks the current background color of the item and switches it to the opposite color.
            QObject::connect(timer, &QTimer::timeout, [=]() mutable{
            if (item->background(0).color() == Qt::green) {item->setBackground(0, Qt::white);}
                else { item->setBackground(0, Qt::green); }
            });

            //Stop flashing the last active item
            if ((prevItem != nullptr) && (prevItem != item)) { prevItem->setBackground(0, Qt::white); timer->stop(); delete timer;}

            ui->treeWidget->setCurrentItem(item);
            item->setSelected(true);
            ui->verticalLayout->itemAt(0)->widget()->setVisible(false);
            
            while(hashIt.hasNext()) {
                hashIt.next();
                //qDebug() << "i: " << hashIt.key() << " " << hashIt.value();
                if(hashIt.key() == sTestName) {
                    ui->verticalLayout->insertWidget(0, hashIt.value());
                    ui->verticalLayout->itemAt(0)->widget()->setVisible(true); break;} }

            prevItem = item;
            return;}
        treeIt++;}   
**}**

mardi 9 mai 2023

How to use enum identifier when a macro of same name exists?

I am trying to work with an enum where one of the enum values is defined as a macro.

enum class Method
{
  GET, 
  POST, 
  PUT, 
  HEAD 
  // I want to add DELETE
};

This enum is being used ahead where values are being converted to string.

But when I add DELETE it says this is defined as a macro in one of the .h files I am using in the class - winnt.h.

In winnt.h, DELETE is defined as:

#define DELETE                           (0x00010000L)

The compiler gives an error saying 'expected an identifier'.

I don't want to change my code WHERE the enum is being used and converted to a string.

How can I add this DELETE value to my enum?

lundi 8 mai 2023

Why is my program still slow after using threading?

I am working on one of my assignments that involves a HashTable. I ran into an issue when reading data from a .csv file. The file contains Covid-19 data from the WHO website (300K lines+). My original code which read the file took around 2 minutes to read the file so I decided to use threading inorder to speed up the process. I set num_threads to std::thread::hardware_concurrency(); which is 64 on my laptop (MacBook Pro 2021 M2 chip). After executing the code can still see some delay (6 seconds) which is definetly faster than my first solution.

Is there a way to speed it up even more? Is there a different way to approach this problem?

I don't want to assign a hardcoded value to num_threads because in the end the TA's will be running the program and I don't know what laptop they're using.

Code:

void process_chunk(std::vector<std::string> chunk, CovidDB* db, std::mutex* mtx) {
    std::string latest_date_str = "01/01/00"; // initialize to an old date
    std::tm latest_date = {};
    std::istringstream iss(latest_date_str);
    iss >> std::get_time(&latest_date, "%m/%d/%y");
    for (auto line : chunk) {
        std::stringstream ss(line);
        std::string country, date_str, cases_str, deaths_str;
        std::getline(ss, date_str, ',');
        std::getline(ss, country, ',');
        std::getline(ss, cases_str, ',');
        std::getline(ss, deaths_str, ',');

        int cases = std::stoi(cases_str);
        int deaths = std::stoi(deaths_str);

        std::tm entry_date = {};
        std::istringstream iss2(date_str);
        iss2 >> std::get_time(&entry_date, "%m/%d/%y");

        if (mktime(&entry_date) > mktime(&latest_date)) {
            latest_date_str = date_str;
            latest_date = entry_date;
        } 

        DataEntry* entry = new DataEntry();
        entry->set_country(country);
        entry->set_date(latest_date_str);
        entry->set_c_cases(cases);
        entry->set_c_deaths(deaths);

        std::lock_guard<std::mutex> lock(*mtx);
        db->add(entry);
    }
}
void CovidDB::add_covid_data(std::string const COVID_FILE) {
    std::ifstream file(COVID_FILE);

    if (!file) {
        std::cout << "\n[File ERROR]\n " << COVID_FILE << std::endl;
        std::exit(EXIT_FAILURE);
    }

    std::string line;
    std::getline(file, line); // skip header line

    std::string latest_date_str = "01/01/00"; // initialize to an old date
    std::tm latest_date = {};
    std::istringstream iss(latest_date_str);
    iss >> std::get_time(&latest_date, "%m/%d/%y");

    const int num_threads = std::thread::hardware_concurrency();
    std::vector<std::vector<std::string>> chunks(num_threads);

    int i = 0;
    while (std::getline(file, line)) {
        chunks[i % num_threads].push_back(line);
        i++;
    }

    file.close();

    std::vector<std::thread> threads;
    std::mutex mtx;

    for (auto chunk : chunks) {
        threads.emplace_back(process_chunk, chunk, this, &mtx);
    }

    for (auto& thread : threads) {
        thread.join();
    }
}

MakeFile:

CXX = g++
CXXFLAGS = -std=c++11 -pthread -g -Wall -Wextra -Werror -pedantic -Wno-unused-parameter -Wno-return-type -Wno-unused-variable
LDFLAGS = -pthread

all: main

main: CovidDB.o main.o
    $(CXX) $(CXXFLAGS) -o $@ $^

CovidDB.o: CovidDB.cpp CovidDB.h
    $(CXX) $(CXXFLAGS) -c $<

main.o: main.cpp CovidDB.h
    $(CXX) $(CXXFLAGS) -c $<

clean:
    rm -f main *.o

I tried increassing the amout of threads, I expected it to run faster but nothing really changed