@@ -43,19 +43,27 @@ class ClassDescription : public Description {
4343 std::source_location location = std::source_location::current())
4444 : Description(location, description), block(block), subject(T()) {}
4545
46- ClassDescription (T subject, Block block, std::source_location location = std::source_location::current())
46+ ClassDescription (const char * description,
47+ T& subject,
48+ Block block,
49+ std::source_location location = std::source_location::current())
50+ : Description(location, description), block(block), subject(subject) {}
51+
52+ template <Util::not_c_string U>
53+ ClassDescription (U& subject, Block block, std::source_location location = std::source_location::current())
4754 : Description(location, Pretty::to_word(subject)),
4855 block (block),
4956 type(" : " + Util::demangle(typeid (T).name())),
5057 subject(subject) {}
5158
5259 ClassDescription (const char * description,
53- T subject,
60+ T&& subject,
5461 Block block,
5562 std::source_location location = std::source_location::current())
56- : Description(location, description), block(block), subject(subject) {}
63+ : Description(location, description), block(block), subject(std::move( subject) ) {}
5764
58- ClassDescription (T&& subject, Block block, std::source_location location = std::source_location::current())
65+ template <Util::not_c_string U>
66+ ClassDescription (U&& subject, Block block, std::source_location location = std::source_location::current())
5967 : Description(location, Pretty::to_word(subject)),
6068 block(block),
6169 type(" : " + Util::demangle(typeid (T).name())),
@@ -89,53 +97,59 @@ class ClassDescription : public Description {
8997
9098 template <class U , class B >
9199 ClassDescription<U>& context (const char * description,
92- U subject,
100+ U& subject,
93101 B block,
94102 std::source_location location = std::source_location::current());
103+
104+ template <class U , class B >
105+ ClassDescription<U>& context (U& subject, B block, std::source_location location = std::source_location::current()) {
106+ return this ->context (" " , subject, block, location);
107+ }
108+
95109 template <class U , class B >
96110 ClassDescription<U>& context (const char * description,
97- U& subject,
111+ U&& subject,
98112 B block,
99113 std::source_location location = std::source_location::current());
100- template <class U , class B >
101- ClassDescription<U>& context (U subject, B block, std::source_location location = std::source_location::current());
102114
115+ template <class U , class B >
116+ ClassDescription<U>& context (U&& subject, B block, std::source_location location = std::source_location::current()) {
117+ return this ->context (" " , subject, block, location);
118+ }
103119 void run () override ;
104120
105121 [[nodiscard]] std::string get_subject_type () const noexcept override { return type; }
106122};
107123
124+ template <Util::not_c_string U>
125+ ClassDescription (U&, std::function<void (ClassDescription<U>&)>, std::source_location) -> ClassDescription<U>;
126+
127+ template <Util::not_c_string U>
128+ ClassDescription (U&&, std::function<void (ClassDescription<U>&)>, std::source_location) -> ClassDescription<U>;
129+
108130template <class T >
109131using ClassContext = ClassDescription<T>;
110132
111133template <class T >
112134template <class U , class B >
113135ClassContext<U>& ClassDescription<T>::context(const char * description,
114- U subject,
136+ U& subject,
115137 B block,
116138 std::source_location location) {
117- auto * context = new ClassContext<U>(description, subject, block, location);
118- context->set_parent (this );
139+ auto * context = this ->make_child <ClassContext<U>>(description, subject, block, location);
119140 context->ClassContext <U>::before_eaches = this ->before_eaches ;
120141 context->ClassContext <U>::after_eaches = this ->after_eaches ;
121142 context->timed_run ();
122143 return *context;
123144}
124145
125- template <class T >
126- template <class U , class B >
127- ClassContext<U>& ClassDescription<T>::context(U subject, B block, std::source_location location) {
128- return this ->context (" " , std::forward<U>(subject), block, location);
129- }
130-
131146template <class T >
132147template <class U , class B >
133148ClassContext<U>& ClassDescription<T>::context(const char * description,
134- U& subject,
149+ U&& subject,
135150 B block,
136151 std::source_location location) {
137- auto * context = new ClassContext<U>(description, subject, block, location);
138- context->set_parent (this );
152+ auto * context = this ->make_child <ClassContext<U>>(description, subject, block, location);
139153 context->ClassContext <U>::before_eaches = this ->before_eaches ;
140154 context->ClassContext <U>::after_eaches = this ->after_eaches ;
141155 context->timed_run ();
@@ -145,31 +159,43 @@ ClassContext<U>& ClassDescription<T>::context(const char* description,
145159template <class T >
146160template <class U , class B >
147161ClassContext<T>& ClassDescription<T>::context(const char * description, B block, std::source_location location) {
148- auto * context = new ClassContext<T>(description, this ->subject , block, location);
149- context->set_parent (this );
162+ auto * context = this ->make_child <ClassContext<T>>(description, this ->subject , block, location);
163+ context->before_eaches = this ->before_eaches ;
164+ context->after_eaches = this ->after_eaches ;
165+ context->timed_run ();
166+ return *context;
167+ }
168+
169+ template <Util::not_c_string T, class B >
170+ ClassContext<T>& Description::context (T& subject, B block, std::source_location location) {
171+ auto * context = this ->make_child <ClassContext<T>>(subject, block, location);
150172 context->before_eaches = this ->before_eaches ;
151173 context->after_eaches = this ->after_eaches ;
152174 context->timed_run ();
153175 return *context;
154176}
155177
156178template <class T , class B >
157- requires (!std::is_same_v<T, const char *>)
158- ClassContext<T>& Description::context (T subject, B block, std::source_location location) {
159- auto * context = new ClassContext<T>(subject, block, location);
160- context->set_parent (this );
161- context->set_location (location);
179+ ClassContext<T>& Description::context (const char * description, T& subject, B block, std::source_location location) {
180+ auto * context = this ->make_child <ClassContext<T>>(description, subject, block, location);
181+ context->before_eaches = this ->before_eaches ;
182+ context->after_eaches = this ->after_eaches ;
183+ context->timed_run ();
184+ return *context;
185+ }
186+
187+ template <Util::not_c_string T, class B >
188+ ClassContext<T>& Description::context (T&& subject, B block, std::source_location location) {
189+ auto * context = this ->make_child <ClassContext<T>>(subject, block, location);
162190 context->before_eaches = this ->before_eaches ;
163191 context->after_eaches = this ->after_eaches ;
164192 context->timed_run ();
165193 return *context;
166194}
167195
168196template <class T , class B >
169- ClassContext<T>& Description::context (const char * description, T subject, B block, std::source_location location) {
170- auto * context = new ClassContext<T>(description, subject, block, location);
171- context->set_parent (this );
172- context->set_location (location);
197+ ClassContext<T>& Description::context (const char * description, T&& subject, B block, std::source_location location) {
198+ auto * context = this ->make_child <ClassContext<T>>(description, subject, block, location);
173199 context->before_eaches = this ->before_eaches ;
174200 context->after_eaches = this ->after_eaches ;
175201 context->timed_run ();
@@ -180,8 +206,7 @@ template <class T, typename U>
180206ClassContext<T>& Description::context (std::initializer_list<U> init_list,
181207 std::function<void (ClassDescription<T>&)> block,
182208 std::source_location location) {
183- auto * context = new ClassContext<T>(T (init_list), block, location);
184- context->set_parent (this );
209+ auto * context = this ->make_child <ClassContext<T>>(T (init_list), block, location);
185210 context->before_eaches = this ->before_eaches ;
186211 context->after_eaches = this ->after_eaches ;
187212 context->timed_run ();
@@ -211,7 +236,7 @@ ClassContext<T>& Description::context(std::initializer_list<U> init_list,
211236 */
212237template <class T >
213238ItCD<T>& ClassDescription<T>::it(const char * name, std::function<void (ItCD<T>&)> block, std::source_location location) {
214- auto * it = new ItCD<T>(* this , location, this ->subject , name, block);
239+ auto * it = this -> make_child < ItCD<T>>( location, this ->subject , name, block);
215240 it->timed_run ();
216241 exec_after_eaches ();
217242 exec_before_eaches ();
@@ -241,7 +266,7 @@ ItCD<T>& ClassDescription<T>::it(const char* name, std::function<void(ItCD<T>&)>
241266 */
242267template <class T >
243268ItCD<T>& ClassDescription<T>::it(std::function<void (ItCD<T>&)> block, std::source_location location) {
244- auto * it = new ItCD<T>(* this , location, this ->subject , block);
269+ auto * it = this -> make_child < ItCD<T>>( location, this ->subject , block);
245270 it->timed_run ();
246271 exec_after_eaches ();
247272 exec_before_eaches ();
@@ -256,17 +281,10 @@ void ClassDescription<T>::run() {
256281 }
257282}
258283
259- template <class T >
260- ExpectationValue<T> ItCD<T>::is_expected() {
261- auto cd = this ->get_parent_as <ClassDescription<T>>();
262- ExpectationValue<T> expectation (*this , cd->subject , std::source_location::current ());
263- return expectation;
264- }
265-
266284template <class T >
267285void ItCD<T>::run() {
268286 this ->block (*this );
269- auto cd = this ->get_parent_as <ClassDescription<T>>();
287+ auto * cd = this ->get_parent_as <ClassDescription<T>>();
270288 cd->reset_lets ();
271289}
272290
0 commit comments