33
44#include " cucumber_cpp/library/Body.hpp"
55#include " cucumber_cpp/library/Context.hpp"
6- #include " cucumber_cpp/library/cucumber_expression/Expression.hpp"
76#include " cucumber_cpp/library/cucumber_expression/Matcher.hpp"
87#include " cucumber_cpp/library/cucumber_expression/ParameterRegistry.hpp"
9- #include " cucumber_cpp/library/cucumber_expression/RegularExpression.hpp"
108#include " cucumber_cpp/library/engine/StepType.hpp"
119#include " cucumber_cpp/library/engine/Table.hpp"
1210#include < any>
1311#include < cstddef>
1412#include < cstdint>
1513#include < exception>
1614#include < memory>
15+ #include < span>
1716#include < string>
1817#include < string_view>
1918#include < utility>
2221
2322namespace cucumber_cpp ::library
2423{
24+ template <class T >
25+ std::unique_ptr<Body> StepBodyFactory (Context& context, const engine::Table& table)
26+ {
27+ return std::make_unique<T>(context, table);
28+ }
29+
2530 struct StepMatch
2631 {
2732 StepMatch (std::unique_ptr<Body> (&factory)(Context& context, const engine::Table& table), std::variant<std::vector<std::string>, std::vector<std::any>> matches, std::string_view stepRegexStr)
@@ -35,7 +40,7 @@ namespace cucumber_cpp::library
3540 std::string_view stepRegexStr{};
3641 };
3742
38- struct StepRegistryBase
43+ struct StepRegistry
3944 {
4045 struct StepNotFoundError : std::exception
4146 {
@@ -77,62 +82,63 @@ namespace cucumber_cpp::library
7782 const std::uint32_t & used;
7883 };
7984
85+ explicit StepRegistry (cucumber_expression::ParameterRegistry& parameterRegistry);
86+
8087 [[nodiscard]] StepMatch Query (engine::StepType stepType, const std::string& expression);
8188
8289 [[nodiscard]] std::size_t Size () const ;
8390 [[nodiscard]] std::size_t Size (engine::StepType stepType) const ;
8491
8592 [[nodiscard]] std::vector<EntryView> List () const ;
8693
87- protected:
88- template <class T >
89- std::size_t
90- Register (const std::string& matcher, engine::StepType stepType);
91-
9294 private:
93- template <class T >
94- static std::unique_ptr<Body> Construct (Context& context, const engine::Table& table);
95+ void Register (const std::string& matcher, engine::StepType stepType, std::unique_ptr<Body> (&factory)(Context& context, const engine::Table& table));
9596
9697 std::vector<Entry> registry;
97- cucumber_expression::ParameterRegistry parameterRegistry;
98+ cucumber_expression::ParameterRegistry& parameterRegistry;
9899 };
99100
100- struct StepRegistry : StepRegistryBase
101+ struct StepStringRegistration
101102 {
102103 private:
103- StepRegistry () = default ;
104+ StepStringRegistration () = default ;
104105
105106 public:
106- static StepRegistry& Instance ();
107+ static StepStringRegistration& Instance ();
108+
109+ struct Entry
110+ {
111+ Entry (engine::StepType type, std::string regex, std::unique_ptr<Body> (&factory)(Context& context, const engine::Table& table))
112+ : type(type)
113+ , regex(std::move(regex))
114+ , factory(factory)
115+ {}
116+
117+ engine::StepType type{};
118+ std::string regex;
119+ std::unique_ptr<Body> (&factory)(Context& context, const engine::Table& table);
120+ };
107121
108122 template <class T >
109123 static std::size_t Register (const std::string& matcher, engine::StepType stepType);
124+
125+ std::span<Entry> GetEntries ();
126+ [[nodiscard]] std::span<const Entry> GetEntries () const ;
127+
128+ private:
129+ std::vector<Entry> registry;
110130 };
111131
112132 // ////////////////////////
113133 // implementation //
114134 // ////////////////////////
115135
116136 template <class T >
117- std::size_t StepRegistryBase ::Register (const std::string& matcher, engine::StepType stepType)
137+ std::size_t StepStringRegistration ::Register (const std::string& matcher, engine::StepType stepType)
118138 {
119- if (matcher.starts_with (' ^' ) || matcher.ends_with (' $' ))
120- registry.emplace_back (stepType, cucumber_expression::Matcher{ std::in_place_type<cucumber_expression::RegularExpression>, matcher }, Construct<T>);
121- else
122- registry.emplace_back (stepType, cucumber_expression::Matcher{ std::in_place_type<cucumber_expression::Expression>, matcher, parameterRegistry }, Construct<T>);
123- return registry.size ();
124- }
125-
126- template <class T >
127- std::unique_ptr<Body> StepRegistryBase::Construct (Context& context, const engine::Table& table)
128- {
129- return std::make_unique<T>(context, table);
130- }
139+ Instance ().registry .emplace_back (stepType, matcher, StepBodyFactory<T>);
131140
132- template <class T >
133- std::size_t StepRegistry::Register (const std::string& matcher, engine::StepType stepType)
134- {
135- return Instance ().StepRegistryBase ::Register<T>(matcher, stepType);
141+ return Instance ().registry .size ();
136142 }
137143}
138144
0 commit comments