vendredi 25 juin 2021

Boost::qi parse string

I need to parse "title" from the next hls tag

Pattern of the tag: #EXTINF:<duration>[,<title>]

For example of real tag:

#EXTINF:10,Title of the segment => I need "Title of the segment" phrase

#EXTINF:20,Title => I need "Title" phrase

#EXTINF:12 => I need "" phrase

I wrote the next code

double duration;
std::string title;

boost::spirit::qi::rule<Iterator, std::string()> quoutedString;
quoutedString %= lexeme[+(char_)];

bool r = parse(first, last,
    ("#EXTINF:" >> double_[ref(duration) = _1] >> -(',' >> quoutedString[ref(title) = _1] ) )
);
if (!r || first != last) {
    addMinorProblem(stateObj, _("Cannot parse information from #EXTINF tag"));
    return false;
}

But I got the next error in compilation process:

error: call of overloaded ‘ref(std::__cxx11::string&)’ is ambiguous
         ("#EXTINF:" >> double_[ref(duration) = _1] >> -(',' >> quoutedString[ref(title) = _1] ) )

Please help me. What am I doing wrong?

C++: Assigning derived class pointer to base class pointer

Not very familiar with C++, so apologies for the potentially nooby question (though, I couldn't find an answer to this, despite semi-similar questions).

In a codebase I'm working on (sorry, can't share exact code), there's a Base class and a Derived class. I have a pointer to the derived class, d.

At some point, I set

Base* b = d;

What's super weird is that the pointers end up with different values! b ends up with an address exactly 8 greater than what d was.

I couldn't repro this with a straight-forward Base/Derived class, so I'm convinced there's something being done in the particular classes I'm working with.

Can anyone shed some light on how this can be possible? What in C++ might allow for something like this?

Thanks in advance!

unable to create 2d matrix inside a class

The error is : "member matrix::rows is not a type name" and "member matrix::init is not a type name". If it compiles successfully I shall have a matrix rows = ROWS and columns = COLS. What am i doing wrong here:

#include <vector>
class matrix
{
    int ROWS{}, COLS{}, init{-1};
    std::vector<std::vector<int>> table(ROWS, std::vector<int>(COLS, init));
};

I don't understand how to create structs data type for MPI

I'm trying to create a MPI_datatype of a struct that looks like this:

struct Body{
      double X;
      double Y;
      double Z;
      double Vx;
      double Vy;
      double Vz;
      double Ax;
      double Ay;
      double Az;
      bool mine;
      int S;
    };

I searched online hot to do it and found some examples. On the man page ( https://www.open-mpi.org/doc/v3.0/man3/MPI_Type_struct.3.php ) of MPI_Type_struct it says that C++ is deprecated, and that I should use MPI_Type_create_struct. Then man page of MPI_Type_create_struct ( https://www.open-mpi.org/doc/v3.0/man3/MPI_Type_create_struct.3.php ). I saw an example of someone creating a data type with MPI_Type_create_struct ( Trouble Understanding MPI_Type_create_struct ). But in here he says that you have to resize the data type and does some weird things with foo, &lb, and &extend that I don't understand. Inc the end, someone said that resize dint make much sense and that MPI_Type_create_resized should be used.

My version of the code is

  Body MPI;
  int count=11;
  const int array_of_blocklengths[11] = {1,1,1,1,1,1,1,1,1,1,1};
  MPI_Aint array_of_displacements[11]={16,16,16,16,16,16,16,16,16,1,8};
  MPI_Datatype array_of_types[3] = {MPI_DOUBLE, MPI_C_BOOL, MPI_INT};
  MPI_Datatype tmp_type, MPI_BODY;
  MPI_Aint lb, extent;
  MPI_Type_create_struct(count, array_of_blocklengths, array_of_displacements, array_of_types, &tmp_type);
  MPI_Type_get_extent(tmp_type, &lb, &extent);
  MPI_Type_create_resized(tmp_type, lb, extent, &MPI_BODY);
  MPI_Type_commit(&MPI_BODY);

But this doesn't work and the program explodes when I run it. Compiles fine though.

I would like if someone can explain to me what's the deal with the array_of_displacements, the problem with MPI_Type_get_extent and MPI_Type_create_resized and what should I do to create my data type.

I am looking to create a very simply code to track the hours that I study throughout the week. This would be through c++, any ideas or suggestions?

I was thinking that a database would be the base for this but I want to be able to export these tracked hours on a file. Currently I have not tried anything, I am really just looking for suggestions

Why is std::priority_queue sorting its container's elements?

I noticed that std::priority_queue stores the elements in sorted manner. Obviously storing elements in sorted manner would be a bad design choice as time complexity of push and pop would shoot up to O(n). But it turns out std::priority_queue magically sort elements in linear time.

Here is the code that I used for testing.

#include <iostream>
#include <queue>
#include <algorithm>
#include <vector>
#include <chrono>
#include <random>
#include <climits>
#include <fstream>
#include <ios>

int main() {
  int size = 10'000'000;

  std::random_device rd;
  std::mt19937 mt{rd()};
  std::uniform_int_distribution<int> uid{1, INT32_MAX};

  std::vector<int> vs;
  for (int i = 0; i < size; ++i) {
    vs.push_back(uid(mt));
  }

  // Measures time taken by make_heap
  std::vector<int> vs1{vs};
  auto start = std::chrono::system_clock::now();
  std::make_heap(vs1.begin(), vs1.end());
  auto end = std::chrono::system_clock::now();
  std::chrono::duration<double> diff = end - start;
  std::cout << "Time taken by make_heap: " << diff.count() << std::endl;

  // Measures time taken by priority_queue
  std::vector<int> vs2{vs};
  start = std::chrono::system_clock::now();
  std::priority_queue<int, std::vector<int>, std::greater<int>> qs{vs2.begin(), vs2.end()};
  end = std::chrono::system_clock::now();
  diff = end - start;
  std::cout << "Time taken by priority_queue: " << diff.count() << std::endl;

  // Measures time taken by sort
  std::vector<int> vs3{vs};
  start = std::chrono::system_clock::now();
  std::sort(vs3.begin(), vs3.end());
  end = std::chrono::system_clock::now();
  diff = end - start;
  std::cout << "Time taken by sort: " << diff.count() << std::endl;
    
  std::ofstream ofile;
  ofile.open("priority_queue_op.txt", std::ios::out);
  for (int i = 0; i < size; ++i) {
    ofile << qs.top() << std::endl;
    qs.pop();
  }
  ofile.close();

  ofile.open("sort_op.txt", std::ios::out);
  for (auto& v : vs3)
    ofile << v << std::endl;
  ofile.close();

  // run `diff priority_queue_op.txt sort_op.txt`

  return 0;
}
$ g++ -O3 test.cpp -o test
$ ./test
Time taken by make_heap: 0.133292
Time taken by priority_queue: 0.151002
Time taken by sort: 0.910701
$ diff priority_queue_op.txt sort_op.txt
$

From the above output it is seems like std::priority_queue is sorting the elements in linear time.

This site suggests that std::priority_queue uses heap functions from standard library to manage heap internally. Even the source code confirms it.

Line 596 - 605

      template<typename _InputIterator>
    priority_queue(_InputIterator __first, _InputIterator __last,
               const _Compare& __x = _Compare(),
               _Sequence&& __s = _Sequence())
    : c(std::move(__s)), comp(__x)
    {
      __glibcxx_requires_valid_range(__first, __last);
      c.insert(c.end(), __first, __last);
      std::make_heap(c.begin(), c.end(), comp);
    }

An insert procedure is used to insert elements followed by std::make_heap to build the heap. So how are the elements magically sorted? And even if there is something how is it happening in linear time?

What does std::put_time actually do for the default locale?

Reading the cppreference.com page about std::put_time, it is not exactly clear to me what it does.

Is it guaranteed, for an ostream whose locale has been set to L, to act as though std::strftime() was called with the LC_XXX enviroment variables set to L?

If not, does it typically do that? Or am I misunderstanding?