My Project
Loading...
Searching...
No Matches
pipeline.hpp
1#ifndef PIPELINE_H_
2#define PIPELINE_H_
3
4#include <vector>
5#include <functional>
6#include <stdexcept>
7#include <utility>
8#include <iostream>
9
10namespace found {
11
16class Action {
17 public:
21 virtual void DoAction() = 0;
22};
23
32template<typename Input, typename Output>
33class Stage : public Action {
34 public:
38 Stage() = default;
39
43 virtual ~Stage() = default;
44
52 virtual Output Run(const Input &input) = 0;
53
57 void DoAction() override { // GCOVR_EXCL_START
58 *this->product = this->Run(this->resource);
59 }; // GCOVR_EXCL_STOP
60
66 Input &GetResource() {return resource;} // GCOVR_EXCL_LINE
67
74 Output *&GetProduct() {return product;} // GCOVR_EXCL_LINE
75
76 protected:
78 Input resource;
80 Output *product;
81};
82
99template<typename Input, typename Output>
100class Pipeline : public Stage<Input, Output> {
101 public:
107 explicit Pipeline(std::vector<std::reference_wrapper<Action>> &stages)
108 : stages(stages), firstResource(nullptr), ready(false) {}
109
124 template<typename I, typename O> Pipeline &AddStage(Stage<I, O> &stage) {
125 // Check the input
126 if (this->ready) throw std::invalid_argument("Pipeline is already ready");
127 if (this->stages.empty()) {
128 if (!std::is_same<Input, I>::value) throw std::invalid_argument("The initial input type is not correct");
129 this->firstResource = reinterpret_cast<Input *>(&stage.GetResource());
130 } else {
131 // Chain here, and blindly trust the user
132 *this->lastProduct = static_cast<void *>(&stage.GetResource());
133 }
134 // Add to our list
135 this->stages.push_back(stage);
136 // Now, reset the lastProduct to be of this stage
137 this->lastProduct = reinterpret_cast<void **>(&stage.GetProduct());
138 // Return the pipeline for chaining
139 return *this;
140 }
141
154 template<typename I> Pipeline &Complete(Stage<I, Output> &stage) {
155 this->AddStage(stage);
156 this->ready = true;
157 stage.GetProduct() = &this->finalProduct;
158 return *this;
159 }
160
177 Output Run(const Input &input) override {
178 if (!this->ready) throw std::runtime_error("This is an illegal action: the pipeline is not ready yet");
179 this->resource = input;
180 *this->firstResource = input;
181 for (Action &stage : this->stages) {
182 stage.DoAction();
183 }
184 return this->finalProduct;
185 }
186
187 private:
189 std::vector<std::reference_wrapper<Action>> stages;
191 Input *firstResource;
193 Output finalProduct;
195 void **lastProduct = nullptr;
197 bool ready;
198};
199
200} // namespace found
201
202#endif
Definition pipeline.hpp:16
virtual void DoAction()=0
Definition pipeline.hpp:100
Output Run(const Input &input) override
Definition pipeline.hpp:177
Pipeline & Complete(Stage< I, Output > &stage)
Definition pipeline.hpp:154
Pipeline & AddStage(Stage< I, O > &stage)
Definition pipeline.hpp:124
Pipeline(std::vector< std::reference_wrapper< Action > > &stages)
Definition pipeline.hpp:107
Definition pipeline.hpp:33
Input & GetResource()
Definition pipeline.hpp:66
Output * product
The pointer to the stored output for this.
Definition pipeline.hpp:80
Output *& GetProduct()
Definition pipeline.hpp:74
void DoAction() override
Definition pipeline.hpp:57
virtual ~Stage()=default
virtual Output Run(const Input &input)=0
Stage()=default
Input resource
The stored input for this.
Definition pipeline.hpp:78
Definition converters.hpp:10