500          list_children(l.list_children),
 
  501          list_handler(l.list_handler) {
 
  503        tbb::spin_mutex::scoped_lock lock(mutex);
 
  509        Flush(
const char* file_ = 
nullptr, 
int line_ = -1) : file(file_), line(line_) {}
 
  514#define LOGFLUSH Logger::Flush(__FILE__, __LINE__) 
  516    Logger& operator<<(
const Level& level) {
 
  517        if (!thread_local_data) { thread_local_data = 
new thread_local_data_t(); }
 
  518        thread_local_data->current_level = level;
 
  522    Logger& operator<<(
const std::string& a) {
 
  523        if (thread_local_data->current_level <= real_max_logged_level) {
 
  524            thread_local_data->current_msg << a;
 
  529    template <
typename T>
 
  530    Logger& operator<<(
const T& n) {
 
  531        if (thread_local_data->current_level <= real_max_logged_level) {
 
  532            thread_local_data->current_msg << n;
 
  538        if (thread_local_data->current_level <= real_max_logged_level) {
 
  539            thread_local_data->current_db_name = a;
 
  544    Logger& write(
size_t size, 
const double* vector, 
size_t incr, 
const std::string& subname = 
"") {
 
  545        if (thread_local_data->current_level <= real_max_logged_level) {
 
  546            size_t dim[1][2] = {{size, incr}};
 
  547            write_untyped(1, dim, 
'd', vector, subname);
 
  553          size_t size, 
const b2000::csda<double>* vector, 
size_t incr,
 
  554          const std::string& subname = 
"") {
 
  555        if (thread_local_data->current_level <= real_max_logged_level) {
 
  556            size_t dim[1][2] = {{size, incr}};
 
  557            write_untyped(1, dim, 
'z', vector, subname);
 
  563          size_t size, 
const std::complex<double>* vector, 
size_t incr,
 
  564          const std::string& subname = 
"") {
 
  565        if (thread_local_data->current_level <= real_max_logged_level) {
 
  566            size_t dim[1][2] = {{size, incr}};
 
  567            write_untyped(1, dim, 
'z', vector, subname);
 
  572    Logger& write(
size_t size, 
const float* vector, 
size_t incr, 
const std::string& subname = 
"") {
 
  573        if (thread_local_data->current_level <= real_max_logged_level) {
 
  574            size_t dim[1][2] = {{size, incr}};
 
  575            write_untyped(1, dim, 
'f', vector, subname);
 
  580    Logger& write(
size_t size, 
const int* vector, 
size_t incr, 
const std::string& subname = 
"") {
 
  581        if (thread_local_data->current_level <= real_max_logged_level) {
 
  582            size_t dim[1][2] = {{size, incr}};
 
  583            write_untyped(1, dim, 
'i', vector, subname);
 
  589          size_t size, 
const unsigned int* vector, 
size_t incr, 
const std::string& subname = 
"") {
 
  590        if (thread_local_data->current_level <= real_max_logged_level) {
 
  591            size_t dim[1][2] = {{size, incr}};
 
  592            write_untyped(1, dim, 
'j', vector, subname);
 
  597    Logger& write(
size_t size, 
const long* vector, 
size_t incr, 
const std::string& subname = 
"") {
 
  598        if (thread_local_data->current_level <= real_max_logged_level) {
 
  599            size_t dim[1][2] = {{size, incr}};
 
  600            write_untyped(1, dim, 
'l', vector, subname);
 
  606          size_t size, 
const unsigned long* vector, 
size_t incr, 
const std::string& subname = 
"") {
 
  607        if (thread_local_data->current_level <= real_max_logged_level) {
 
  608            size_t dim[1][2] = {{size, incr}};
 
  609            write_untyped(1, dim, 
'm', vector, subname);
 
  615          size_t dim1, 
size_t dim2, 
const double* matrix, 
size_t ldv,
 
  616          const std::string& subname = 
"") {
 
  617        if (thread_local_data->current_level <= real_max_logged_level) {
 
  618            size_t dim[2][2] = {{dim1, 1}, {dim2, ldv}};
 
  619            write_untyped(2, dim, 
'd', matrix, subname);
 
  625          size_t dim1, 
size_t dim2, 
const b2000::csda<double>* matrix, 
size_t ldv,
 
  626          const std::string& subname = 
"") {
 
  627        if (thread_local_data->current_level <= real_max_logged_level) {
 
  628            size_t dim[2][2] = {{dim1, 1}, {dim2, ldv}};
 
  629            write_untyped(2, dim, 
'z', matrix, subname);
 
  635          size_t dim1, 
size_t dim2, 
const std::complex<double>* matrix, 
size_t ldv,
 
  636          const std::string& subname = 
"") {
 
  637        if (thread_local_data->current_level <= real_max_logged_level) {
 
  638            size_t dim[2][2] = {{dim1, 1}, {dim2, ldv}};
 
  639            write_untyped(2, dim, 
'z', matrix, subname);
 
  645          size_t dim1, 
size_t dim2, 
const float* matrix, 
size_t ldv,
 
  646          const std::string& subname = 
"") {
 
  647        if (thread_local_data->current_level <= real_max_logged_level) {
 
  648            size_t dim[2][2] = {{dim1, 1}, {dim2, ldv}};
 
  649            write_untyped(2, dim, 
'f', matrix, subname);
 
  655          size_t dim1, 
size_t dim2, 
const int* matrix, 
size_t ldv,
 
  656          const std::string& subname = 
"") {
 
  657        if (thread_local_data->current_level <= real_max_logged_level) {
 
  658            size_t dim[2][2] = {{dim1, 1}, {dim2, ldv}};
 
  659            write_untyped(2, dim, 
'd', matrix, subname);
 
  665          size_t dim1, 
size_t dim2, 
const long* matrix, 
size_t ldv,
 
  666          const std::string& subname = 
"") {
 
  667        if (thread_local_data->current_level <= real_max_logged_level) {
 
  668            size_t dim[2][2] = {{dim1, 1}, {dim2, ldv}};
 
  669            write_untyped(2, dim, 
'd', matrix, subname);
 
  674    Logger& operator<<(
const Flush& flush) {
 
  675        for (real_list_handler_t::iterator i = real_list_handler_begin;
 
  676             i != real_list_handler_end && thread_local_data->current_level <= i->second; ++i) {
 
  677            if (thread_local_data->current_level <= i->second) {
 
  679                      get_name(), thread_local_data->current_level, flush.file, flush.line,
 
  680                      thread_local_data->current_msg.str(), thread_local_data->list_dbo.begin(),
 
  681                      thread_local_data->list_dbo.end());
 
  684        thread_local_data->current_level = not_set;
 
  685        thread_local_data->current_msg.str(
"");
 
  686        thread_local_data->list_dbo.clear();
 
  690    void log(
const Level level, 
const std::string& msg, 
const char* file = 
nullptr, 
int line = -1) {
 
  691        if (!thread_local_data) { thread_local_data = 
new thread_local_data_t(); }
 
  692        for (real_list_handler_t::iterator i = real_list_handler_begin;
 
  693             i != real_list_handler_end && level <= i->second; ++i) {
 
  695                  get_name(), level, file, line, msg, thread_local_data->list_dbo.begin(),
 
  696                  thread_local_data->list_dbo.end());
 
  700#define LOG(level, msg) log(level, msg, __FILE__, __LINE__) 
  702    bool is_enabled_for(
const Level level)
 const { 
return level <= real_max_logged_level; }
 
  704    const std::string get_name()
 const {
 
  706            if (parent != &root_logger) {
 
  707                return parent->get_name() + 
"." + name;
 
  716    void add_handler(Handler* handler, Level& level) {
 
  717        if (list_handler.count(handler)) {
 
  718            if (list_handler[handler] < level) { list_handler[handler] = level; }
 
  720            list_handler[handler] = level;
 
  723        tbb::spin_mutex::scoped_lock lock(mutex);
 
  728    void remove_handler(Handler* handler) {
 
  729        list_handler.erase(handler);
 
  731        tbb::spin_mutex::scoped_lock lock(mutex);
 
  736    Logger& get_logger(
const std::string& logger_name) {
 
  737        int p = logger_name.find(
'.');
 
  738        list_children_t::iterator i = list_children.find(logger_name.substr(0, p));
 
  739        if (i == list_children.end()) {
 
  741                      .insert(list_children_t::value_type(
 
  742                            logger_name.substr(0, p), 
Logger(logger_name.substr(0, p), 
this)))
 
  748            return i->second.get_logger(logger_name.substr(p + 1));
 
  752    template <
typename Function>
 
  753    void for_each(Function f)
 const {
 
  755        for (list_children_t::const_iterator i = list_children.begin(); i != list_children.end();
 
  757            i->second.for_each(f);
 
  761    void print_list(std::ostream& out, 
const std::string& prefix = 
"")
 const {
 
  762        for_each(PrintName(out, prefix));
 
  765    static Logger root_logger;
 
  769          size_t ndim, 
size_t dim[][2], 
char element_type, 
const void* value,
 
  770          const std::string& subname = 
"") {
 
  771        thread_local_data->list_dbo.push_back(DBObject(
 
  772              thread_local_data->current_msg.str().size(), thread_local_data->current_db_name,
 
  773              subname, ndim, dim, element_type, value));
 
  776    Logger(
const std::string& name_, 
Logger* parent_) : name(name_), parent(parent_) {
 
  778        tbb::spin_mutex::scoped_lock lock(mutex);
 
  785              const std::pair<Handler* const, Level>& a,
 
  786              const std::pair<Handler* const, Level>& b)
 const {
 
  787            return b.second < a.second;
 
  792        PrintName(std::ostream& out_, 
const std::string& prefix_) : out(out_), prefix(prefix_) {}
 
  793        void operator()(
const Logger& l) { out << prefix << l.get_name() << std::endl; }
 
  795        const std::string& prefix;
 
  802    typedef std::map<std::string, Logger> list_children_t;
 
  803    list_children_t list_children;
 
  804    typedef std::map<Handler*, Level> list_handler_t;
 
  805    list_handler_t list_handler;
 
  807    Level real_max_logged_level;
 
  808    typedef std::vector<std::pair<Handler*, Level> > real_list_handler_t;
 
  809    real_list_handler_t real_list_handler;
 
  810    real_list_handler_t::iterator real_list_handler_begin;
 
  811    real_list_handler_t::iterator real_list_handler_end;
 
  813    struct thread_local_data_t {
 
  814        std::ostringstream current_msg;
 
  817        typedef std::list<DBObject> list_dbo_t;
 
  820    static thread_local_storage thread_local_data_t* thread_local_data;
 
  823    static tbb::spin_mutex mutex;