115            template<
class... Args>
 
  116            Pipeline(Args&&... args) : _default_response(std::forward<Args>(args)...)
 
 
  127            template <
typename T, 
typename ...Args>
 
  130                std::unique_ptr<T> handler = std::make_unique<T>(std::forward<Args>(args)...);
 
  132                handler->_pipeline = 
this;
 
  134                _pipes.push_back(std::move(handler));
 
  137                    _pipes_by_name[name] = _pipes.back().get();
 
 
  150                for (
auto& it : _pipes)
 
 
  161                for (
auto it = _pipes.rbegin(); it != _pipes.rend(); ++it)
 
 
  168            Response 
run(
const Request& request)
 
  171                assert(!_last_step_pipe);
 
  173                if (_pipes.size() > 0)
 
  175                #ifdef OE_UTIL_PIPELINE_RUN_BOTTOM_TO_TOP 
  176                    return _pipes.back()->handle(request);
 
  178                    return _pipes.front()->handle(request);
 
  184                return _default_response;
 
 
  187            Response getDefaultResponse() { 
return _default_response; }
 
  194            template<
class... Types>
 
  197                _default_response = {args...};
 
 
  200            template <
typename T>
 
  201            T* getPipeByName(
const std::string& name)
 
  203                return static_cast<T*
>(_pipes_by_name[name]);
 
  206            void enableStepByStepMode()
 
  208                _last_step_pipe.emplace(0);
 
  210                for (
auto it = _pipes.begin(); it != _pipes.end(); ++it)
 
  212                    (*it)->_next_handler = 
nullptr;
 
  216            void disableStepByStepMode()
 
  218                _last_step_pipe.reset();
 
  222            bool isStepByStepMode()
 
  224                return (
bool)_last_step_pipe;
 
  227            std::pair<Response, bool> step(
const Request& request)
 
  230                assert(_last_step_pipe);
 
  232                PipeHandler* pipe = _pipes[*_last_step_pipe].get();
 
  234                ++(*_last_step_pipe);
 
  236                bool has_more_pipes = _last_step_pipe < _pipes.size();
 
  239                    *_last_step_pipe = 0;
 
  241                return {pipe->handle(request), has_more_pipes};
 
  245            std::vector<std::unique_ptr<PipeHandler>> _pipes;
 
  246            Response _default_response;
 
  248            std::map<std::string, PipeHandler*> _pipes_by_name;
 
  250            std::optional<int32_t> _last_step_pipe = std::nullopt;
 
  252            void _rebuildPipeOrder()
 
  254            #ifdef OE_UTIL_PIPELINE_RUN_BOTTOM_TO_TOP 
  255                PipeHandler* last_handler = _pipes.front();
 
  256                last_handler->_next_handler = _pipes.size() > 1
 
  257                    ? *(*(_pipes.begin()+1))
 
  261                for (
auto it = _pipes.begin()+1; it != _pipes.end(); ++it)
 
  263                PipeHandler* last_handler = _pipes.back().get();
 
  264                last_handler->_next_handler = 
nullptr;
 
  266                for (
auto it = _pipes.rbegin()+1; it != _pipes.rend(); ++it)
 
  269                    (*it)->_next_handler = last_handler;
 
  270                    last_handler = it->get();