# -*- mode:org; mode:visual-line; coding:utf-8; -*-

*** C++ Header Tools

A collection of C++ (mostly, C++11) header-only utility libraries.

**** Examples

Below you can find code snippets. For full examples and some tests, see the [[examples]] folder. In some cases, sample programs are included in the header files themselves, and they can be enabled by specific CPP defines.

***** logger

A thread-safe facility-based logging mechanism.

#+BEGIN_EXAMPLE
#include "logger.hpp"
...
logger::Logger::set_default_level("info");
int c = 0;
LOG(info) << "now you see me; c=" << ++c << "\n";
assert(c == 1);
LOG(debug) << "now you don't; c=" << ++c << "\n";
assert(c == 1);
#+END_EXAMPLE

***** zstr

A ZLib wrapper.

#+BEGIN_EXAMPLE
#include "zstr.hpp"
...
zstr::ifstream(argv[1]) >> i;
#+END_EXAMPLE

***** alg

Collection of new and extended SL algorithms. Contents:

- =for_each[_it][_advance]=: Apply functor to elements in range. Options: take iterator pair or range as input; pass iterator instead of element to functor; store next iterator prior to applying functor (e.g. use: remove elements from a list in one pass.)

- =(min|max|minmax)[_value]_of=: Find min and/or max in range. Options: take iterator pair or range as input; optionally use functor to extract key; return iterator(s) or value(s).

- =mean_stdv_of=: Find mean and sample stdv of elements in range. Options: take iterator pair or range as input; optionally use functor to extract key.

- =(equal|all|any)_of=: Check that all elements in a range are equal, or that all are true, or that at least one is true. Options: take iterator pair or range as input; optionally use functor to extract key.

- =os_join=: Use =operator <<= overloads to print range or to convert it to string using a custom separator. Options: take iterator pair or range as input; optionally use functor to extract key.

#+BEGIN_EXAMPLE
#include "alg.hpp"
...
std::list<int> l{3, 6, 10, 18};
// erase elements == 0 mod 5 => l == {3, 6, 18}
alg::for_each_it_advance(l, [&l] (std::list<int>::iterator it) { if (*it%5 == 0) l.erase(it); });
// iterator to minimum value mod 5 => iterator to 6
auto it_min_val_mod_5 = alg::min_of(l, [] (int i) { return i%5; });
// all equal mod 3 => true
bool equal_mod_3 = alg::equal_of(l, [] (int i) { return i%3; });
// to ostream => "l: 3, 6, 18"
std::cout << "l: " << alg::os_join(l, ", ") << std::endl;
#+END_EXAMPLE

***** logsum

Floating point additions in logarithmic space using table lookup.

*Note*: This library is based on Sean Eddy's code, originall part of HMMER. The version included in here is header-only, and it using implicit table initialization (no need to explicitly call =p7_FLogsumInit()=).

#+BEGIN_EXAMPLE
#include "logsum.hpp"
...
float r = p7_FLogsum(.5, .3); // ~= log(exp(.5) + exp(.3))
#+END_EXAMPLE

***** pfor

A C++11-based parallel for, with optional output sorting.

#+BEGIN_EXAMPLE
#include "pfor.hpp"
...
std::vector< unsigned > v(1000);
unsigned crt_idx = 0;
pfor::pfor< unsigned >(
    4,                // num_threads
    10,               // chunk_size
    [&] (unsigned& i) // get_item
    {
        if (crt_idx >= v.size()) return false;
        i = crt_idx++; return true;
    },
    [&] (unsigned& i) // process_item
    {
        v[i] = i*i;
    });
#+END_EXAMPLE

***** tpool

A C++11-based thread pool.

#+BEGIN_EXAMPLE
#include "tpool.hpp"
...
void some_work(unsigned tid, unsigned i);
...
// create a pool of 4 worker threads
tpool::tpool p(4);
// perform 10 rounds of work
for (int unsigned = 0; round < 10; ++round)
{
    // in each round, work on n items
    for (unsigned i = 0; i < n; i += 2)
    {
        p.add_job(std::bind(some_work, std::placeholders::_1, i));
        // Note: the lambda must capture i by value, not by reference
        p.add_job([&,i] (unsigned tid) { some_work(tid, i + 1); });
    }
    p.wait_jobs();
}
#+END_EXAMPLE

**** License

[[LICENSE][MIT License]].

