AsmGrader 0.0.0
Loading...
Searching...
No Matches
global_registrar.hpp
Go to the documentation of this file.
1#pragma once
2
6
7#include <range/v3/algorithm/find.hpp>
8#include <range/v3/algorithm/find_if.hpp>
9#include <range/v3/view/transform.hpp>
10
11#include <cstddef>
12#include <functional>
13#include <memory>
14#include <optional>
15#include <string_view>
16#include <type_traits>
17#include <vector>
18
19namespace asmgrader {
20
30{
31public:
33 static GlobalRegistrar& get() noexcept;
34
36 void add_test(std::unique_ptr<TestBase> test) noexcept;
37
38 template <typename Func>
39 requires(std::is_void_v<std::invoke_result_t<Func, Assignment>>)
40 void for_each_assignment(Func&& fun);
41
42 template <typename Func>
43 requires(!std::is_void_v<std::invoke_result_t<Func, Assignment>>)
44 std::vector<std::invoke_result_t<Func, Assignment>> for_each_assignment(Func&& fun);
45
46 auto get_assignments() noexcept {
47 return registered_assignments_ |
48 ranges::views::transform(
49 [](std::unique_ptr<Assignment>& assignment) -> Assignment& { return *assignment; });
50 }
51
52 std::optional<std::reference_wrapper<Assignment>> get_assignment(std::string_view name) {
53 auto name_matcher = [name](const std::unique_ptr<Assignment>& assignment) {
54 return assignment->get_name() == name;
55 };
56
57 if (auto iter = ranges::find_if(registered_assignments_, name_matcher); iter != registered_assignments_.end()) {
58 return **iter;
59 }
60
61 return std::nullopt;
62 }
63
66 template <typename... MetadataAttrs>
68
70 std::vector<std::string_view> get_assignment_names();
71
72 std::size_t get_num_registered() const;
73
74private:
75 GlobalRegistrar() = default;
76
78 Assignment& get_assignment_for_test(const TestBase& base);
79
80 std::vector<std::unique_ptr<Assignment>> registered_assignments_;
81};
82
83template <typename... MetadataAttrs>
85 static_assert(metadata.template has<metadata::Assignment>(), "metadata::Assignment attribute missing");
86
87 metadata::Assignment meta_assignment = *metadata.template get<metadata::Assignment>();
88
89 auto assignment_matcher = [meta_assignment](const std::unique_ptr<Assignment>& assignment) {
90 return assignment->get_name() == meta_assignment.name &&
91 assignment->get_exec_path() == meta_assignment.exec_name;
92 };
93
94 if (auto iter = ranges::find_if(registered_assignments_, assignment_matcher);
95 iter != registered_assignments_.end()) {
96 return **iter;
97 }
98
99 registered_assignments_.push_back(std::make_unique<Assignment>(meta_assignment.name, meta_assignment.exec_name));
100
101 return *registered_assignments_.back();
102}
103
104template <typename Func>
105 requires(std::is_void_v<std::invoke_result_t<Func, Assignment>>)
107 for (auto& assignement : get_assignments()) {
108 std::forward<Func>(fun)(assignement);
109 }
110}
111
112template <typename Func>
113 requires(!std::is_void_v<std::invoke_result_t<Func, Assignment>>)
114std::vector<std::invoke_result_t<Func, Assignment>> GlobalRegistrar::for_each_assignment(Func&& fun) {
115 std::vector<std::invoke_result_t<Func, Assignment>> result;
116 result.reserve(registered_assignments_.size());
117
118 for (auto& assignement : get_assignments()) {
119 result.push_back(std::forward<Func>(fun)(assignement));
120 }
121
122 return result;
123}
124
125} // namespace asmgrader
Declaration for the logic and data encapsulating a class assignment.
Definition assignment.hpp:23
A global singleton registrar. Used with Assignments for now.
Definition global_registrar.hpp:30
void for_each_assignment(Func &&fun)
Definition global_registrar.hpp:106
auto get_assignments() noexcept
Definition global_registrar.hpp:46
Assignment & find_or_create_assignment(metadata::Metadata< MetadataAttrs... > metadata)
Find the assignment corresponding to the Assignment attribute of metadata, or create a new assignment...
Definition global_registrar.hpp:84
std::size_t get_num_registered() const
Definition global_registrar.cpp:28
std::vector< std::string_view > get_assignment_names()
Obtain a list of all assignment names.
Definition global_registrar.cpp:24
void add_test(std::unique_ptr< TestBase > test) noexcept
Registers the test to be made accessible.
std::optional< std::reference_wrapper< Assignment > > get_assignment(std::string_view name)
Definition global_registrar.hpp:52
static GlobalRegistrar & get() noexcept
Safe global singleton pattern (first intro. by Scott Meyers for C++, I think)
Definition global_registrar.cpp:11
Base class primarily for a user-written test.
Definition test_base.hpp:17
Definition metadata.hpp:117
Definition asm_buffer.hpp:19
Definition metadata.hpp:23
std::string_view name
Definition metadata.hpp:24
std::string_view exec_name
Definition metadata.hpp:25