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); }
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.
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());
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.
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:
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
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.