cauldron  0.0.0
 All Classes Namespaces Files Functions Variables Typedefs
bases.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <memory>
4 #include <random>
5 
6 #include "sieve.h"
7 #include "facility.h"
8 
9 
10 namespace cauldron {
11 template<typename Value>
12 class Union;
13 
14 
15 template<typename Value>
16 class Filtered;
17 
18 
19 template<typename Value>
20 class Mapped;
21 
22 
31 template<typename Value>
32 class Strategy {
33  public:
37  virtual Value operator()() const = 0;
38 
43  virtual Union<Value> operator||(const Strategy<Value> &strategy) const {
44  return Union<Value>{*this, strategy};
45  }
46 
52  virtual Union<Value> operator||(const Union<Value> &strategy) const {
53  return strategy || static_cast<const Strategy<Value> &>(*this);
54  }
55 
64  virtual Filtered<Value> filter(const Requirement<Value> &requirement) const {
65  Sieve<Value> sieve{requirement};
66  return Filtered<Value>(*this, sieve);
67  }
68 
74  virtual Mapped<Value> map(const Converter<Value> &converter) const {
75  Facility<Value> facility{converter};
76  return Mapped<Value>(*this, facility);
77  }
78 
83  virtual std::unique_ptr<Strategy<Value>> clone() const = 0;
84 };
85 
86 
96 template<typename Value, class Derived>
97 class CloneHelper : public Strategy<Value> {
98  public:
99  std::unique_ptr<Strategy<Value>> clone() const override {
100  return std::make_unique<Derived>(static_cast<const Derived &>(*this));
101  }
102 };
103 
104 
111 template<class Value>
112 class Union : public CloneHelper<Value, Union<Value>> {
113  public:
114  explicit Union(const Strategy<Value> &strategy,
115  const Strategy<Value> &other_strategy) {
116  strategies_.push_back(strategy.clone());
117  strategies_.push_back(other_strategy.clone());
118  }
119 
125  Union(const Union<Value> &strategy) {
126  strategies_.reserve(strategy.strategies_.size());
127  for (const auto &sub_strategy: strategy.strategies_) {
128  strategies_.push_back(sub_strategy->clone());
129  }
130  }
131 
135  Value operator()() const override {
136  static std::random_device random_device;
137  size_t max_index = strategies_.size() - 1;
138  std::uniform_int_distribution<size_t> distribution(0, max_index);
139  size_t index = distribution(random_device);
140  return (*strategies_[index])();
141  }
142 
143  Union<Value> operator||(const Strategy<Value> &strategy) const override {
144  Union<Value> result(*this);
145  result.strategies_.push_back(strategy.clone());
146  return result;
147  }
148 
149  Union<Value> operator||(const Union<Value> &strategy) const override {
150  Union<Value> result(*this);
151  for (const auto &sub_strategy: strategy.strategies_) {
152  result.strategies_.push_back(sub_strategy->clone());
153  }
154  return result;
155  }
156 
157  private:
158  std::vector<std::unique_ptr<Strategy<Value>>> strategies_;
159 };
160 
161 
172 template<typename Value>
173 class Filtered : public CloneHelper<Value, Filtered<Value>> {
174  public:
175  explicit Filtered(const Strategy<Value> &strategy,
176  const Sieve<Value> &sieve) :
177  strategy_(strategy.clone()),
178  sieve_(sieve) {};
179 
185  Filtered(const Filtered<Value> &strategy) :
186  strategy_(strategy.strategy_->clone()),
187  sieve_(strategy.sieve_) {}
188 
190  const Requirement<Value> &requirement
191  ) const override {
192  auto sieve = sieve_.expand(requirement);
193  return Filtered<Value>(*strategy_, sieve);
194  }
195 
201  Value operator()() const override {
202  std::function<Value()> producer([&]() -> Value {
203  return (*strategy_)();
204  });
205  return sieve_.sift(producer);
206  }
207 
208  protected:
209  std::unique_ptr<Strategy<Value>> strategy_;
211 };
212 
213 
224 template<typename Value>
225 class Mapped : public CloneHelper<Value, Mapped<Value>> {
226  public:
227  explicit Mapped(const Strategy<Value> &strategy,
228  const Facility<Value> &facility) :
229  strategy_(strategy.clone()),
230  facility_(facility) {};
231 
237  Mapped(const Mapped<Value> &strategy) :
238  strategy_(strategy.strategy_->clone()),
239  facility_(strategy.facility_) {}
240 
241  Mapped<Value> map(const Converter<Value> &converter) const override {
242  auto facility = facility_.expand(converter);
243  return Mapped(*strategy_, facility);
244  }
245 
250  Value operator()() const override {
251  Value product = (*strategy_)();
252  return facility_.convert(product);
253  }
254 
255  protected:
256  std::unique_ptr<Strategy<Value>> strategy_;
258 };
259 }
std::function< Product(Product)> Converter
Definition: facility.h:10
Union< Value > operator||(const Union< Value > &strategy) const override
Definition: bases.h:149
Facility< Product > expand(const Converter< Product > &converter) const
Definition: facility.h:24
Union< Value > operator||(const Strategy< Value > &strategy) const override
Definition: bases.h:143
Definition: bases.h:32
Facility< Value > facility_
Definition: bases.h:257
Mapped(const Strategy< Value > &strategy, const Facility< Value > &facility)
Definition: bases.h:227
virtual std::unique_ptr< Strategy< Value > > clone() const =0
Filtered(const Filtered< Value > &strategy)
Definition: bases.h:185
virtual Filtered< Value > filter(const Requirement< Value > &requirement) const
Definition: bases.h:64
Union(const Strategy< Value > &strategy, const Strategy< Value > &other_strategy)
Definition: bases.h:114
Mapped< Value > map(const Converter< Value > &converter) const override
Definition: bases.h:241
Definition: bases.h:97
std::unique_ptr< Strategy< Value > > strategy_
Definition: bases.h:209
Sieve< Value > sieve_
Definition: bases.h:210
Value operator()() const override
Definition: bases.h:135
std::function< bool(Product)> Requirement
Definition: sieve.h:12
Definition: bases.h:20
virtual Value operator()() const =0
Product convert(Product product) const
Definition: facility.h:30
virtual Union< Value > operator||(const Union< Value > &strategy) const
Definition: bases.h:52
Value operator()() const override
Definition: bases.h:250
Value operator()() const override
Definition: bases.h:201
Filtered(const Strategy< Value > &strategy, const Sieve< Value > &sieve)
Definition: bases.h:175
virtual Union< Value > operator||(const Strategy< Value > &strategy) const
Definition: bases.h:43
std::unique_ptr< Strategy< Value > > clone() const override
Definition: bases.h:99
virtual Mapped< Value > map(const Converter< Value > &converter) const
Definition: bases.h:74
Filtered< Value > filter(const Requirement< Value > &requirement) const override
Definition: bases.h:189
Sieve< Product > expand(const Requirement< Product > &requirement) const
Definition: sieve.h:57
Definition: bases.h:16
Mapped(const Mapped< Value > &strategy)
Definition: bases.h:237
Definition: bases.h:12
Product sift(std::function< Product()> producer) const
Definition: sieve.h:64
std::unique_ptr< Strategy< Value > > strategy_
Definition: bases.h:256
Union(const Union< Value > &strategy)
Definition: bases.h:125