1#ifndef BANDIT_RUN_POLICY_H
2#define BANDIT_RUN_POLICY_H
3
4#include <memory>
5#include <stdexcept>
6#include <bandit/context.h>
7
8namespace bandit {
9 namespace detail {
10 struct run_policy {
11 run_policy()
12 : encountered_failure_(false) {}
13 run_policy(const run_policy& other) = default;
14
15#ifndef _MSC_VER
16 run_policy(run_policy&&) = default;
17#else
18 run_policy(run_policy&& other)
19 : encountered_failure_(other.encountered_failure_) {}
20#endif
21
22 virtual ~run_policy() {}
23
24 virtual bool should_run(const std::string& it_name, const contextstack_t& contexts) const = 0;
25
26 virtual void encountered_failure() {
27 encountered_failure_ = true;
28 }
29
30 virtual bool has_encountered_failure() const {
31 return encountered_failure_;
32 }
33
34 private:
35 bool encountered_failure_;
36 };
37
38 typedef std::unique_ptr<run_policy> run_policy_ptr;
39
40 struct policy_runner {
41 // A function is required to initialize a static run_policy variable in a header file
42 // and this struct aims at encapsulating this function
43 static void register_run_policy(run_policy* policy) {
44 if (policy == nullptr) {
45 throw std::runtime_error("Invalid null policy passed to "
46 "bandit::detail::register_run_policy");
47 }
48 get_run_policy_address() = policy;
49 }
50
51 static run_policy& registered_run_policy() {
52 auto policy = get_run_policy_address();
53 if (policy == nullptr) {
54 throw std::runtime_error("No policy set. Please call "
55 "bandit::detail::register_run_policy with a non-null reporter");
56 }
57 return *policy;
58 }
59
60 private:
61 static run_policy*& get_run_policy_address() {
62 static run_policy* policy = nullptr;
63 return policy;
64 }
65 };
66
67 inline void register_run_policy(run_policy* policy) {
68 policy_runner::register_run_policy(policy);
69 }
70
71 inline run_policy& registered_run_policy() {
72 return policy_runner::registered_run_policy();
73 }
74 }
75}
76#endif
77