+ namespace impl {
+
+ /**
+ * Manages the standard-logger and the logger-stack.
+ *
+ * CAREFULL: THIS FUNCTION CONTAINS GLOBAL STATE!
+ */
+ std::vector<logger_set*>& logger_stack() {
+ static auto stack = std::vector<logger_set*> {};
+ // To avoid infinite recursion, the base-logger must
+ // not auto-register but be added manually
+ static auto std_logger = logger_set {{std::cout}, auto_register::off};
+ // in order to avoid use-after-free bugs, the logger must be created after
+ // the stack, to avoid that it's destructor tries to access
+ // parts of the destroyed stack
+
+ static auto dummy = [&] {
+ stack.push_back( &std_logger );
+ return 0;
+ }();
+
+ ( void ) dummy;
+ return stack;
+ }
+
+ void reassign_stack_pointer( logger_set*& ptr ) {
+ const auto old_ptr = ptr;
+
+ if( ptr ) {
+ ptr->m_stackpointer = &ptr;
+ }
+
+ ( void ) old_ptr;
+ assert( ptr == old_ptr );
+ }
+
+ void register_logger( logger_set& set ) {
+ auto& stack = logger_stack();
+
+ // we need to reassign everything if the vector reallocated:
+ const auto old_capacity = stack.capacity();
+ stack.push_back( &set );
+
+ if( stack.capacity() == old_capacity ) {
+ reassign_stack_pointer( stack.back() );
+ } else {
+ for( auto& ptr : stack ) {
+ reassign_stack_pointer( ptr );
+ }
+ }
+ }
+
+ /**
+ * Pops loggers from the stack until the last one is not a nullptr
+ */
+ void pop_loggers() {
+ auto& stack = logger_stack();
+
+ while( !stack.empty() and stack.back() == nullptr ) {
+ stack.pop_back();
+ }
+
+ assert( stack.empty() or stack.back() != nullptr );
+ }
+
+ logger_set& active_logger() {
+ const auto result = logger_stack().back();
+ assert( result != nullptr );
+ return *result;
+ }
+
+ } // namespace impl
+
+ logger_set::logger_set( std::initializer_list<log_target> lst, auto_register r ):
+ m_loggers{lst}, m_min_level{default_level} {
+ if( lst.size() > 0 ) {
+ m_min_level = std::min_element( lst.begin(), lst.end(),
+ []( const log_target& l, const log_target& r ) {
+ return l.min_level < r.min_level;
+ } )->min_level;
+ }
+
+ if( r == auto_register::on ) {
+ impl::register_logger( *this );
+ }
+ }