result_type
 operator () (lhs_op_rhs const & _top) const
 {
     return dispatcher_(output_.at(_top.lhs_),
                        _top.operator_,
                        output_.at(_top.rhs_));
 }
 result_type
 traverse(std::conditional_t< reassmble, ast::expression &&, ast::expression const & > _input)
 { // if reassmble is true, then input is taken apart, then reassembled
     assert(output_.empty());
     if (_input.rest_.empty()) {
         return dispatcher_(std::move(_input.first_));
     } else if (_input.rest_.size() == 1) {
         auto & operation_ = _input.rest_.back();
         return dispatcher_(std::move(_input.first_),
                            operation_.operator_,
                            std::move(operation_.operand_));
     } else {
         //output_.reserve(_input.rest_.size() * 2 + 1); // total number of operators and operands
         std::stack< aggregate_wrapper< lhs_op > > lhs_op_;
         for (auto & operation_ : _input.rest_) {
             size_type const precedence_ = ast::precedence(operation_.operator_);
             while (!lhs_op_.empty()) {
                 lhs_op const & top_ = lhs_op_.top();
                 if (ast::precedence(top_.operator_) < precedence_) {
                     break;
                 }
                 output_.emplace_back(top_.lhs_, top_.operator_, output_.size());
                 lhs_op_.pop();
             }
             lhs_op_.emplace(output_.size(), operation_.operator_);
             output_.emplace_back(&operation_.operand_);
         }
         while (!lhs_op_.empty()) {
             lhs_op const & top_ = lhs_op_.top();
             output_.emplace_back(top_.lhs_, top_.operator_, output_.size());
             lhs_op_.pop();
         }
         output_.emplace_front(&_input.first_);
         return operator () (output_.back());
     }
 }
 result_type
 operator () (operand_ptr const _top) const
 {
     return dispatcher_(std::move(*_top));
 }
 void operator()(std::string const& msg)
 {
     std::lock_guard<mutex_type> l(mtx_);
     dispatcher_(msg);
 }