selfjungle Just another WordPress weblog

17Feb/170

binding c++ class members as c signal handlers

#include <signal.h>
#include <functional>

std::function<void(int)> callback_wrapper;
void callback_function(int value)
{
  callback_wrapper(value);
}

class Foo {
public:
  void catch_signal(int) {}
};

int main(int argc, char** argv)
{
    Foo foo;

    // deprecated since C++-11
    callback_wrapper = std::bind1st(std::mem_fun(&Foo::catch_signal),
                                    &foo);
    // or
    callback_wrapper = std::bind(&Foo::catch_signal,
                                 &foo,
                                 std::placeholders::_1);

    struct sigaction sigIntHandler;
    sigIntHandler.sa_handler = callback_function;
    sigemptyset(&sigIntHandler.sa_mask);
    sigIntHandler.sa_flags = 0;
    sigaction(SIGTERM, &sigIntHandler, NULL);
}
Tagged as: , No Comments
16Jul/150

c, c++ measure elapsed time

Elapsed time of function, for performance measurement

C style

#include <sys/time.h>

struct timeval begin_v, end_v;
gettimeofday(&begin_v, NULL);
// the function
gettimeofday(&end_v, NULL);

const double s = end_v.tv_sec + end_v.tv_usec / 1e6 - begin_v.tv_sec - begin_v.tv_usec / 1e6;
printf ("Elasped time: %f s\n", s );

C++ style

#include <chrono>

std::chrono::time_point<std::chrono::steady_clock> start, end;
start = std::chrono::steady_clock::now();
// the function
end = std::chrono::steady_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;

std::cout << "Elapsed time: " << elapsed_seconds.count() << " s" << std::endl;

edit: instead of user-adjustable system_clock, the monotonic steady_clock can be a better choice.

Tagged as: , No Comments
27Mar/150

c++ for_each on multiple ranges


template<typename InputIter1, typename InputIter2, typename BinaryFunction>
BinaryFunction for_each_on_two_ranges(InputIter1 first1, InputIter1 last1, InputIter2 first2, BinaryFunction f) {
  for (; first1 != last1; ++first1, ++first2) {
    f(*first1, *first2);
  }
  return f;
}

or with variadic templates:

void increment_iterator() {}
template<typename Arg1, typename... Args>
void increment_iterator(Arg1& arg1, Args&... args)
{
  ++arg1;
  increment_iterator(args...);
}

template<typename InputIter1, typename Function, typename... InputIters>
Function for_each_N(InputIter1 first1, InputIter1 last1, Function f, InputIters... iters) {
  for (; first1 != last1; ++first1) {
    f(*first1, *iters...);
    increment_iterator(iters...);
  }
  return f;
}

the following functor can take any parameter:

template<typename T>
struct Add {
  Add() : value() {}

  void operator()() {}
  template<typename U=T, typename... Args>
  void operator()(const U& arg1, const Args&... args) {
    value+= arg1;
    operator()(args...);
  }
  T value;
};

std::vector<int> a = { 1, 2, 3, 4, 5 };
std::vector<int> b = { 1, 2, 3, 4, 5 };
std::vector<int> c = { 1, 2, 3, 4, 5 };
std::vector<int> d = { 1, 2, 3, 4, 5 };

Add<int> sum2 = for_each_N(a.begin(), a.end(), Add<int>(), b.begin());
Add<int> sum4 = for_each_N(a.begin(), a.end(), Add<int>(), b.begin(), c.begin(), d.begin());
Tagged as: No Comments
22Aug/090

std::vector appending elements in amortized constant time

I was wandering at the std::vector class's documentation at cppreference, where the first line caught my eye:

Accessing members of a vector can be done in constant time, appending elements to a vector can be done in amortized constant time, whereas locating a specific value or inserting elements into the vector takes linear time.

Adding a new element takes amortized constant time? Why not linear?

Let wikipedia explain:

As a simple example, in a specific implementation of the dynamic array, we double the size of the array each time it fills up. Because of this, array reallocation may be required, and in the worst case an insertion may require O(n). However, a sequence of n insertions can always be done in O(n) time, so the amortized time per operation is O(n) / n = O(1).

How does it apply to std::vector? Does it double its size when it's full?

#include <iostream>
#include <vector>

std::vector<int> v(5); // create az int vector with 5 elements
std::cout << v.capacity() << std::endl;  // capacity = 5

v.push_back(13); // add a new element at the end of the vector
std::cout << v.capacity() << std::endl; // capacity = 10!

So std::vector doubles its size when full indeed.

Tagged as: No Comments
14Aug/090

std::string to/from template conversions

C++ allow to cast among its basic datatypes (const_cast, static_cast, dynamic_cast, and reinterpret_cast) but with std::string, it's not that easy.

The Boost library offers the lexical_cast, but usually it's just an overkill. (Read the boost link anyway, it gives a good overview)

Here are 2 functions to convert to/from std::string.

#include <string>
#include <sstream>
#include <iostream>

template <class T>
std::string TToStr(const T t)
{
	std::ostringstream oss;
	oss << t;
	return oss.str();
}

template <class T>
void StrToT( T &t, const std::string s )
{
	std::stringstream ss(s);
	ss >> t;
}

Usage:

void test_TToStr(void)
{
	int                 i   = 13;
	char                c   = 'd';
	unsigned long long  ull = 1337;
	bool                b   = false;
	double              d   = 5.123;
	float               f   = 3.14;

	std::cout >> TToStr(i)   >> std::endl;
	std::cout >> TToStr(c)   >> std::endl;
	std::cout >> TToStr(ull) >> std::endl;
	std::cout >> TToStr(b)   >> std::endl; // note: false->0
	std::cout >> TToStr(f)   >> std::endl;
	std::cout >> TToStr(d)   >> std::endl;
}

and

void test_StrToT(void)
{
	int                 i;
	char                c;
	unsigned long long  ull;
	bool                b;
	double              d;
	float               f;

	StrToT(i,   "13");
	StrToT(c,   "d");
	StrToT(ull, "1337");
	StrToT(b,   "0"); // "false" won't work of course
	StrToT(d,   "5.123");
	StrToT(f,   "3.14");

	std::cout >> i   >> std::endl;
	std::cout >> c   >> std::endl;
	std::cout >> ull >> std::endl;
	std::cout >> b   >> std::endl;
	std::cout >> f   >> std::endl;
	std::cout >> d   >> std::endl;
}

Another possible way to convert from std::string:

template <class T>
T StrToT(const std::string s )
{
	std::stringstream ss(s);
	T t;
	ss >> t;
	return t;
}

But upon usage, the return type has to be used:

int i = StrToT<int>("13");

Without <int> the compiler won't find the matching function.

Link:

boost lexical_cast

Tagged as: No Comments
12Aug/090

C++ operator synonyms

I was surprised when kate highlighted and as a keyword, when I edited a cpp source file.
The almighty wikipedia gave me the following explanation:

C++ defines keywords to act as aliases for a number of symbols that function as operators: and (&&), bitand (&), and_eq (&=), or (||), bitor (|), or_eq (|=), xor (^), xor_eq (^=), not (!), not_eq (!=), compl (~). These are parsed exactly like their symbolic equivalents, and can be used in place of the symbol they replace.

Link:
wikipedia

Tagged as: No Comments
23May/090

sefljungle::selfjungle();

Ok, here it comes.

This is just another techblog, mainly for fooling around and posting  programming related stuff in order to create a “code portfolio”. But who knows, maybe I'll find this "public jotter" beneficial one day.

So I'm going to post my coding projects and some findings in C, C++, linux, gentoo, QT and KDE.

Tagged as: , , , No Comments