1//! @file behavioral.hpp
2//! @author ryftchen
3//! @brief The declarations (behavioral) in the design pattern module.
4//! @version 0.1.0
5//! @copyright Copyright (c) 2022-2025 ryftchen. All rights reserved.
6
7#pragma once
8
9#include <map>
10#include <memory>
11#include <sstream>
12#include <vector>
13
14//! @brief The design pattern module.
15namespace design_pattern // NOLINT(modernize-concat-nested-namespaces)
16{
17//! @brief Behavioral-related functions in the design pattern module.
18namespace behavioral
19{
20//! @brief Brief function description.
21//! @return function description (module_function)
22inline static const char* description() noexcept
23{
24 return "DP_BEHAVIORAL";
25}
26extern const char* version() noexcept;
27
28//! @brief The chain of responsibility pattern.
29namespace chain_of_responsibility
30{
31//! @brief Handle requests that they are responsible for. Optionally implement the successor link.
32class Handler
33{
34public:
35 //! @brief Construct a new Handler object.
36 Handler() = default;
37 //! @brief Destroy the Handler object.
38 virtual ~Handler() = default;
39 //! @brief Construct a new Handler object.
40 Handler(const Handler&) = default;
41 //! @brief Construct a new Handler object.
42 Handler(Handler&&) noexcept = default;
43 //! @brief The operator (=) overloading of Handler class.
44 //! @return reference of the Handler object
45 Handler& operator=(const Handler&) = default;
46 //! @brief The operator (=) overloading of Handler class.
47 //! @return reference of the Handler object
48 Handler& operator=(Handler&&) noexcept = default;
49
50 //! @brief Set the handler.
51 //! @param handler - target handler
52 virtual void setHandler(std::shared_ptr<Handler> handler);
53 //! @brief Handle the request.
54 virtual void handleRequest();
55
56private:
57 //! @brief The successor.
58 std::shared_ptr<Handler> successor;
59};
60
61//! @brief The concrete handler.
62class ConcreteHandler1 : public Handler
63{
64public:
65 //! @brief Check whether it can handle the request.
66 //! @return can handle or not
67 static bool canHandle();
68 //! @brief Handle the request.
69 void handleRequest() override;
70};
71
72//! @brief The concrete handler.
73class ConcreteHandler2 : public Handler
74{
75public:
76 //! @brief Check whether it can handle the request.
77 //! @return can handle or not
78 static bool canHandle();
79 //! @brief Handle the request.
80 void handleRequest() override;
81};
82
83extern std::ostringstream& output() noexcept;
84} // namespace chain_of_responsibility
85
86//! @brief The command pattern.
87namespace command
88{
89//! @brief Receiver associated with the command.
90class Receiver
91{
92public:
93 //! @brief Perform the operations associated with carrying out the request.
94 static void action();
95};
96
97//! @brief Implement the execution in command.
98class Command
99{
100public:
101 //! @brief Destroy the Command object.
102 virtual ~Command() = default;
103 //! @brief Construct a new Command object.
104 Command(const Command&) = default;
105 //! @brief Construct a new Command object.
106 Command(Command&&) noexcept = default;
107 //! @brief The operator (=) overloading of Command class.
108 //! @return reference of the Command object
109 Command& operator=(const Command&) = default;
110 //! @brief The operator (=) overloading of Command class.
111 //! @return reference of the Command object
112 Command& operator=(Command&&) noexcept = default;
113
114 //! @brief Execute the command.
115 virtual void execute() = 0;
116
117protected:
118 //! @brief Construct a new Command object.
119 Command() = default;
120};
121
122//! @brief The concrete command.
123class ConcreteCommand : public Command
124{
125public:
126 //! @brief Construct a new ConcreteCommand object.
127 //! @param receiver - receiver associated with the command
128 explicit ConcreteCommand(const std::shared_ptr<Receiver>& receiver) : receiver{receiver} {}
129
130 //! @brief Execute the command.
131 void execute() override;
132
133private:
134 //! @brief The receiver.
135 const std::weak_ptr<Receiver> receiver;
136};
137
138//! @brief Invoke the corresponding operation.
139class Invoker
140{
141public:
142 //! @brief Set the command.
143 //! @param c - command
144 void set(const std::shared_ptr<Command>& c);
145 //! @brief Ask the command to carry out the request.
146 void confirm();
147
148private:
149 //! @brief The command.
150 std::weak_ptr<Command> command;
151};
152
153extern std::ostringstream& output() noexcept;
154} // namespace command
155
156//! @brief The interpreter pattern.
157namespace interpreter
158{
159//! @brief Global context.
160class Context
161{
162public:
163 //! @brief Set the pair of the expression and the value.
164 //! @param expr - expression
165 //! @param val - value
166 void set(const std::string& expr, const bool val);
167 //! @brief Get the value by expression.
168 //! @param expr - expression
169 //! @return value
170 bool get(const std::string& expr);
171
172private:
173 //! @brief The variables.
174 std::map<std::string, bool> vars;
175};
176
177//! @brief The abstract interpret operation.
178class AbstractExpression
179{
180public:
181 //! @brief Construct a new AbstractExpression object.
182 AbstractExpression() = default;
183 //! @brief Destroy the AbstractExpression object.
184 virtual ~AbstractExpression() = default;
185 //! @brief Construct a new AbstractExpression object.
186 AbstractExpression(const AbstractExpression&) = default;
187 //! @brief Construct a new AbstractExpression object.
188 AbstractExpression(AbstractExpression&&) noexcept = default;
189 //! @brief The operator (=) overloading of AbstractExpression class.
190 //! @return reference of the AbstractExpression object
191 AbstractExpression& operator=(const AbstractExpression&) = default;
192 //! @brief The operator (=) overloading of AbstractExpression class.
193 //! @return reference of the AbstractExpression object
194 AbstractExpression& operator=(AbstractExpression&&) noexcept = default;
195
196 //! @brief The interpret that is common to all nodes in the abstract syntax tree.
197 //! @param context - global context
198 //! @return resulting value
199 virtual bool interpret(const std::shared_ptr<Context>& context);
200};
201
202//! @brief The terminal interpret operation. An instance is required for every terminal symbol in a sentence.
203class TerminalExpression : public AbstractExpression
204{
205public:
206 //! @brief Construct a new TerminalExpression object.
207 //! @param value - target value
208 explicit TerminalExpression(const std::string_view value) : value{value} {}
209
210 //! @brief The interpret that associated with terminal symbols in the grammar.
211 //! @param context - global context
212 //! @return resulting value
213 bool interpret(const std::shared_ptr<Context>& context) override;
214
215private:
216 //! @brief The value of the terminal expression.
217 const std::string value;
218};
219
220//! @brief The non-terminal interpret operation. One such class is required for every rule in grammar.
221class NonTerminalExpression : public AbstractExpression
222{
223public:
224 //! @brief Construct a new NonTerminalExpression object.
225 //! @param left - target left operation
226 //! @param right - target right operation
227 NonTerminalExpression(std::shared_ptr<AbstractExpression> left, std::shared_ptr<AbstractExpression> right) :
228 leftOp{std::move(left)}, rightOp{std::move(right)}
229 {
230 }
231
232 //! @brief The interpret that associated with non-terminal symbols in the grammar.
233 //! @param context - global context
234 //! @return resulting value
235 bool interpret(const std::shared_ptr<Context>& context) override;
236
237private:
238 //! @brief The left operation of the non-terminal expression.
239 std::shared_ptr<AbstractExpression> leftOp;
240 //! @brief The right operation of the non-terminal expression.
241 std::shared_ptr<AbstractExpression> rightOp;
242};
243
244extern std::ostringstream& output() noexcept;
245} // namespace interpreter
246
247//! @brief The iterator pattern.
248namespace iterator
249{
250//! @brief Manage the current index of the iterator. A set of methods for traversing over items.
251class Iterator
252{
253public:
254 //! @brief Construct a new Iterator object.
255 Iterator() = default;
256 //! @brief Destroy the Iterator object.
257 virtual ~Iterator() = default;
258 //! @brief Construct a new Iterator object.
259 Iterator(const Iterator&) = default;
260 //! @brief Construct a new Iterator object.
261 Iterator(Iterator&&) noexcept = default;
262 //! @brief The operator (=) overloading of Iterator class.
263 //! @return reference of the Iterator object
264 Iterator& operator=(const Iterator&) = default;
265 //! @brief The operator (=) overloading of Iterator class.
266 //! @return reference of the Iterator object
267 Iterator& operator=(Iterator&&) noexcept = default;
268
269 //! @brief Set the current index to the first.
270 virtual void first() = 0;
271 //! @brief Set the current index to the next.
272 virtual void next() = 0;
273 //! @brief Check whether the traversal is done.
274 //! @return be done or not
275 [[nodiscard]] virtual bool isDone() const = 0;
276 //! @brief Get the item by current index.
277 //! @return current item
278 [[nodiscard]] virtual int currentItem() const = 0;
279};
280
281//! @brief The aggregate decouples the client from the implementation of the collection of items.
282class Aggregate
283{
284public:
285 //! @brief Construct a new Aggregate object.
286 Aggregate() = default;
287 //! @brief Destroy the Aggregate object.
288 virtual ~Aggregate() = default;
289 //! @brief Construct a new Aggregate object.
290 Aggregate(const Aggregate&) = default;
291 //! @brief Construct a new Aggregate object.
292 Aggregate(Aggregate&&) noexcept = default;
293 //! @brief The operator (=) overloading of Aggregate class.
294 //! @return reference of the Aggregate object
295 Aggregate& operator=(const Aggregate&) = default;
296 //! @brief The operator (=) overloading of Aggregate class.
297 //! @return reference of the Aggregate object
298 Aggregate& operator=(Aggregate&&) noexcept = default;
299
300 //! @brief Create an iterator.
301 //! @return iterator
302 virtual std::shared_ptr<Iterator> createIterator() = 0;
303};
304
305//! @brief The concrete aggregate.
306class ConcreteAggregate : public Aggregate, public std::enable_shared_from_this<ConcreteAggregate>
307{
308public:
309 //! @brief Construct a new ConcreteAggregate object.
310 //! @param size - size of items
311 explicit ConcreteAggregate(const std::uint32_t size);
312
313 //! @brief Create an iterator.
314 //! @return iterator
315 std::shared_ptr<Iterator> createIterator() override;
316 //! @brief Get the size of items.
317 //! @return size of items
318 std::uint32_t size() const;
319 //! @brief Get the item by index.
320 //! @param index - index of item
321 //! @return item
322 int at(const std::uint32_t index);
323
324private:
325 //! @brief Collection of items.
326 std::unique_ptr<int[]> list;
327 //! @brief Size of items.
328 const std::uint32_t count{0};
329};
330
331//! @brief The concrete iterator.
332class ConcreteIterator : public Iterator
333{
334public:
335 //! @brief Construct a new ConcreteIterator object.
336 //! @param aggregate - target aggregate
337 explicit ConcreteIterator(std::shared_ptr<ConcreteAggregate> aggregate) : aggregate{std::move(aggregate)} {}
338
339 //! @brief Set the current index to the first.
340 void first() override;
341 //! @brief Set the current index to the next.
342 void next() override;
343 //! @brief Check whether the traversal is done.
344 //! @return be done or not
345 [[nodiscard]] bool isDone() const override;
346 //! @brief Get the item by current index.
347 //! @return current item
348 [[nodiscard]] int currentItem() const override;
349
350private:
351 //! @brief Aggregate to be iterated.
352 const std::shared_ptr<ConcreteAggregate> aggregate;
353 //! @brief Current index.
354 std::uint32_t index{0};
355};
356
357extern std::ostringstream& output() noexcept;
358} // namespace iterator
359
360//! @brief The mediator pattern.
361namespace mediator
362{
363class Colleague;
364
365//! @brief Implement cooperative behavior by coordinating colleagues.
366class Mediator
367{
368public:
369 //! @brief Destroy the Mediator object.
370 virtual ~Mediator() = default;
371 //! @brief Construct a new Mediator object.
372 Mediator(const Mediator&) = default;
373 //! @brief Construct a new Mediator object.
374 Mediator(Mediator&&) noexcept = default;
375 //! @brief The operator (=) overloading of Mediator class.
376 //! @return reference of the Mediator object
377 Mediator& operator=(const Mediator&) = default;
378 //! @brief The operator (=) overloading of Mediator class.
379 //! @return reference of the Mediator object
380 Mediator& operator=(Mediator&&) noexcept = default;
381
382 //! @brief Add colleague.
383 //! @param colleague - target colleague
384 virtual void add(const std::shared_ptr<Colleague>& colleague) = 0;
385 //! @brief Distribute message.
386 //! @param sender - sender in colleagues
387 //! @param msg - message from sender
388 virtual void distribute(const std::shared_ptr<Colleague>& sender, const std::string_view msg) = 0;
389
390protected:
391 //! @brief Construct a new Mediator object.
392 Mediator() = default;
393};
394
395//! @brief The concrete mediator.
396class ConcreteMediator : public Mediator
397{
398public:
399 //! @brief Add colleague.
400 //! @param colleague - target colleague
401 void add(const std::shared_ptr<Colleague>& colleague) override;
402 //! @brief Distribute message.
403 //! @param sender - sender in colleagues
404 //! @param msg - message from sender
405 void distribute(const std::shared_ptr<Colleague>& sender, const std::string_view msg) override;
406
407private:
408 //! @brief Collection of colleagues.
409 std::vector<std::weak_ptr<Colleague>> colleagues;
410};
411
412//! @brief The colleague communicates with its mediator.
413//! Whenever it would have otherwise communicated with another colleague.
414class Colleague
415{
416public:
417 //! @brief Construct a new Colleague object.
418 //! @param mediator - target mediator
419 //! @param id - target id
420 Colleague(const std::shared_ptr<Mediator>& mediator, const std::uint32_t id) : mediator{mediator}, id{id} {}
421 //! @brief Destroy the Colleague object.
422 virtual ~Colleague() = default;
423 //! @brief Construct a new Colleague object.
424 Colleague(const Colleague&) = default;
425 //! @brief Construct a new Colleague object.
426 Colleague(Colleague&&) noexcept = default;
427 //! @brief The operator (=) overloading of Colleague class.
428 //! @return reference of the Colleague object
429 Colleague& operator=(const Colleague&) = delete;
430 //! @brief The operator (=) overloading of Colleague class.
431 //! @return reference of the Colleague object
432 Colleague& operator=(Colleague&&) noexcept = delete;
433
434 //! @brief Get the id of the colleague.
435 //! @return id of the colleague
436 [[nodiscard]] std::uint32_t getId() const;
437 //! @brief Send message.
438 //! @param msg - sending message
439 virtual void send(const std::string_view msg) = 0;
440 //! @brief Receive message.
441 //! @param msg - receiving message
442 virtual void receive(const std::string_view msg) = 0;
443
444protected:
445 //! @brief Mediator of the colleague.
446 const std::weak_ptr<Mediator> mediator;
447 //! @brief Id of the colleague.
448 const std::uint32_t id{0};
449};
450
451//! @brief The concrete colleague.
452class ConcreteColleague : public Colleague, public std::enable_shared_from_this<ConcreteColleague>
453{
454public:
455 //! @brief Construct a new ConcreteColleague object.
456 //! @param mediator - target mediator
457 //! @param id - target id
458 ConcreteColleague(const std::shared_ptr<Mediator>& mediator, const std::uint32_t id) : Colleague(mediator, id) {}
459
460 //! @brief Send message.
461 //! @param msg - sending message
462 void send(const std::string_view msg) override;
463 //! @brief Receive message.
464 //! @param msg - receiving message
465 void receive(const std::string_view msg) override;
466};
467
468extern std::ostringstream& output() noexcept;
469} // namespace mediator
470
471//! @brief The memento pattern.
472namespace memento
473{
474//! @brief Store the internal state of the originator. Protect against access by other than the originator.
475class Memento
476{
477private:
478 friend class Originator;
479 //! @brief Construct a new Memento object.
480 //! @param state - target state
481 explicit Memento(const int state) : state{state} {}
482
483 //! @brief State of memento.
484 int state{0};
485 //! @brief Set the state of memento.
486 //! @param s - target state
487 void setState(const int s);
488 //! @brief Get the state of memento.
489 //! @return state of memento
490 [[nodiscard]] int getState() const;
491};
492
493//! @brief Create the memento containing a snapshot of its current internal state.
494//! Use the memento to restore its internal state.
495class Originator
496{
497public:
498 //! @brief Set the state of originator.
499 //! @param s - target state
500 void setState(const int s);
501 //! @brief Get the state of originator.
502 //! @return state of originator
503 [[nodiscard]] int getState() const;
504 //! @brief Set the state of originator by memento.
505 //! @param memento - target memento
506 void setMemento(const std::shared_ptr<Memento>& memento);
507 //! @brief Create the memento.
508 //! @return memento
509 [[nodiscard]] std::shared_ptr<Memento> createMemento() const;
510
511private:
512 //! @brief State of originator.
513 int state{0};
514};
515
516//! @brief Safeguard memento.
517class CareTaker
518{
519public:
520 //! @brief Construct a new CareTaker object.
521 //! @param originator - target originator
522 explicit CareTaker(const std::shared_ptr<Originator>& originator) : originator{originator} {}
523
524 //! @brief Save the current state to history.
525 void save();
526 //! @brief Undo the last state.
527 void undo();
528
529private:
530 //! @brief Specific originator.
531 const std::shared_ptr<Originator> originator;
532 //! @brief State history.
533 std::vector<std::shared_ptr<Memento>> history;
534};
535
536extern std::ostringstream& output() noexcept;
537} // namespace memento
538
539//! @brief The observer pattern.
540namespace observer
541{
542class Subject;
543
544//! @brief Store state of interest to the observer. Send a notification to its observers when its state changes.
545class Observer
546{
547public:
548 //! @brief Construct a new Observer object.
549 Observer() = default;
550 //! @brief Destroy the Observer object.
551 virtual ~Observer() = default;
552 //! @brief Construct a new Observer object.
553 Observer(const Observer&) = default;
554 //! @brief Construct a new Observer object.
555 Observer(Observer&&) noexcept = default;
556 //! @brief The operator (=) overloading of Observer class.
557 //! @return reference of the Observer object
558 Observer& operator=(const Observer&) = default;
559 //! @brief The operator (=) overloading of Observer class.
560 //! @return reference of the Observer object
561 Observer& operator=(Observer&&) noexcept = default;
562
563 //! @brief Get the state of observer.
564 //! @return state of observer
565 [[nodiscard]] virtual int getState() const = 0;
566 //! @brief Update the state of observer by subject.
567 //! @param subject - target subject
568 virtual void update(const std::weak_ptr<Subject>& subject) = 0;
569};
570
571//! @brief Attach, detach and notify observers.
572class Subject : public std::enable_shared_from_this<Subject>
573{
574public:
575 //! @brief Construct a new Subject object.
576 Subject() = default;
577 //! @brief Destroy the Subject object.
578 virtual ~Subject() = default;
579 //! @brief Construct a new Subject object.
580 Subject(const Subject&) = default;
581 //! @brief Construct a new Subject object.
582 Subject(Subject&&) noexcept = default;
583 //! @brief The operator (=) overloading of Subject class.
584 //! @return reference of the Subject object
585 Subject& operator=(const Subject&) = default;
586 //! @brief The operator (=) overloading of Subject class.
587 //! @return reference of the Subject object
588 Subject& operator=(Subject&&) noexcept = default;
589
590 //! @brief Attach observer.
591 //! @param observer - observer to be attached
592 void attach(const std::shared_ptr<Observer>& observer);
593 //! @brief Detach observer by index.
594 //! @param index - observer index
595 void detach(const int index);
596 //! @brief Notify all observers.
597 void notify();
598 //! @brief Get the state of subject.
599 //! @return state of subject
600 virtual int getState() const = 0;
601 //! @brief Set the state of subject.
602 //! @param s - target state of subject
603 virtual void setState(const int s) = 0;
604
605private:
606 //! @brief Collection of observers.
607 std::vector<std::weak_ptr<Observer>> observers;
608};
609
610//! @brief The concrete observer.
611class ConcreteObserver : public Observer
612{
613public:
614 //! @brief Construct a new ConcreteObserver object.
615 //! @param state - target state of observer
616 explicit ConcreteObserver(const int state) : observerState{state} {}
617
618 //! @brief Get the state of observer.
619 //! @return state of observer
620 [[nodiscard]] int getState() const override;
621 //! @brief Update the state of observer by subject.
622 //! @param subject - target subject
623 void update(const std::weak_ptr<Subject>& subject) override;
624
625private:
626 //! @brief State of observer.
627 int observerState{0};
628};
629
630//! @brief The concrete subject.
631class ConcreteSubject : public Subject
632{
633public:
634 //! @brief Get the state of subject.
635 //! @return state of subject
636 int getState() const override;
637 //! @brief Set the state of subject.
638 //! @param s - target state of subject
639 void setState(const int s) override;
640
641private:
642 //! @brief State of subject.
643 int subjectState{0};
644};
645
646extern std::ostringstream& output() noexcept;
647} // namespace observer
648
649//! @brief The state pattern.
650namespace state
651{
652//! @brief Behaviors associated with a particular state of the context.
653class State
654{
655public:
656 //! @brief Construct a new State object.
657 State() = default;
658 //! @brief Destroy the State object.
659 virtual ~State() = default;
660 //! @brief Construct a new State object.
661 State(const State&) = default;
662 //! @brief Construct a new State object.
663 State(State&&) noexcept = default;
664 //! @brief The operator (=) overloading of State class.
665 //! @return reference of the State object
666 State& operator=(const State&) = default;
667 //! @brief The operator (=) overloading of State class.
668 //! @return reference of the State object
669 State& operator=(State&&) noexcept = default;
670
671 //! @brief Handle in the state.
672 virtual void handle() = 0;
673};
674
675//! @brief The concrete state.
676class ConcreteStateA : public State
677{
678public:
679 //! @brief Handle in the state.
680 void handle() override;
681};
682
683//! @brief The concrete state.
684class ConcreteStateB : public State
685{
686public:
687 //! @brief Handle in the state.
688 void handle() override;
689};
690
691//! @brief Interest in clients.
692class Context
693{
694public:
695 //! @brief Set the state of context.
696 //! @param s - target state
697 void setState(std::unique_ptr<State> s);
698 //! @brief Request handling.
699 void request();
700
701private:
702 //! @brief State of context.
703 std::unique_ptr<State> state;
704};
705
706extern std::ostringstream& output() noexcept;
707} // namespace state
708
709//! @brief The strategy pattern.
710namespace strategy
711{
712//! @brief Implement the algorithm using the strategy interface. Common to all supported algorithms.
713class Strategy
714{
715public:
716 //! @brief Construct a new Strategy object.
717 Strategy() = default;
718 //! @brief Destroy the Strategy object.
719 virtual ~Strategy() = default;
720 //! @brief Construct a new Strategy object.
721 Strategy(const Strategy&) = default;
722 //! @brief Construct a new Strategy object.
723 Strategy(Strategy&&) noexcept = default;
724 //! @brief The operator (=) overloading of Strategy class.
725 //! @return reference of the Strategy object
726 Strategy& operator=(const Strategy&) = default;
727 //! @brief The operator (=) overloading of Strategy class.
728 //! @return reference of the Strategy object
729 Strategy& operator=(Strategy&&) noexcept = default;
730
731 //! @brief The interface of the algorithm.
732 virtual void algorithmInterface() = 0;
733};
734
735//! @brief The concrete strategy.
736class ConcreteStrategyA : public Strategy
737{
738public:
739 //! @brief The interface of the algorithm.
740 void algorithmInterface() override;
741};
742
743//! @brief The concrete strategy.
744class ConcreteStrategyB : public Strategy
745{
746public:
747 //! @brief The interface of the algorithm.
748 void algorithmInterface() override;
749};
750
751//! @brief Maintain reference to the strategy object.
752class Context
753{
754public:
755 //! @brief Construct a new Context object.
756 //! @param strategy - target strategy
757 explicit Context(std::unique_ptr<Strategy> strategy) : strategy{std::move(strategy)} {}
758
759 //! @brief The interface of the context.
760 void contextInterface();
761
762private:
763 //! @brief Strategy of context.
764 std::unique_ptr<Strategy> strategy;
765};
766
767extern std::ostringstream& output() noexcept;
768} // namespace strategy
769
770//! @brief The template method pattern.
771namespace template_method
772{
773//! @brief Implement the template method defining the skeleton of the algorithm.
774class AbstractClass
775{
776public:
777 //! @brief Construct a new AbstractClass object.
778 AbstractClass() = default;
779 //! @brief Destroy the AbstractClass object.
780 virtual ~AbstractClass() = default;
781 //! @brief Construct a new AbstractClass object.
782 AbstractClass(const AbstractClass&) = default;
783 //! @brief Construct a new AbstractClass object.
784 AbstractClass(AbstractClass&&) noexcept = default;
785 //! @brief The operator (=) overloading of AbstractClass class.
786 //! @return reference of the AbstractClass object
787 AbstractClass& operator=(const AbstractClass&) = default;
788 //! @brief The operator (=) overloading of AbstractClass class.
789 //! @return reference of the AbstractClass object
790 AbstractClass& operator=(AbstractClass&&) noexcept = default;
791
792 //! @brief The template method.
793 void templateMethod();
794 //! @brief The primitive operation 1.
795 virtual void primitiveOperation1() = 0;
796 //! @brief The primitive operation 2.
797 virtual void primitiveOperation2() = 0;
798};
799
800//! @brief Implement the primitive operations to carry out specific steps of the algorithm.
801class ConcreteClass : public AbstractClass
802{
803public:
804 //! @brief The primitive operation 1.
805 void primitiveOperation1() override;
806 //! @brief The primitive operation 2.
807 void primitiveOperation2() override;
808};
809
810extern std::ostringstream& output() noexcept;
811} // namespace template_method
812
813//! @brief The visitor pattern.
814namespace visitor
815{
816class ConcreteElementA;
817class ConcreteElementB;
818
819//! @brief Implement the algorithm's fragment defined for the structure's corresponding element.
820class Visitor
821{
822public:
823 //! @brief Construct a new Visitor object.
824 Visitor() = default;
825 //! @brief Destroy the Visitor object.
826 virtual ~Visitor() = default;
827 //! @brief Construct a new Visitor object.
828 Visitor(const Visitor&) = default;
829 //! @brief Construct a new Visitor object.
830 Visitor(Visitor&&) noexcept = default;
831 //! @brief The operator (=) overloading of Visitor class.
832 //! @return reference of the Visitor object
833 Visitor& operator=(const Visitor&) = default;
834 //! @brief The operator (=) overloading of Visitor class.
835 //! @return reference of the Visitor object
836 Visitor& operator=(Visitor&&) noexcept = default;
837
838 //! @brief Visit element A.
839 //! @param element - element to be visited
840 virtual void visitElementA(const std::shared_ptr<ConcreteElementA>& element) = 0;
841 //! @brief Visit element B.
842 //! @param element - element to be visited
843 virtual void visitElementB(const std::shared_ptr<ConcreteElementB>& element) = 0;
844};
845
846//! @brief The concrete visitor.
847class ConcreteVisitor1 : public Visitor
848{
849public:
850 //! @brief Visit element A.
851 //! @param element - element to be visited
852 void visitElementA(const std::shared_ptr<ConcreteElementA>& element) override;
853 //! @brief Visit element B.
854 //! @param element - element to be visited
855 void visitElementB(const std::shared_ptr<ConcreteElementB>& element) override;
856};
857
858//! @brief The concrete visitor.
859class ConcreteVisitor2 : public Visitor
860{
861public:
862 //! @brief Visit element A.
863 //! @param element - element to be visited
864 void visitElementA(const std::shared_ptr<ConcreteElementA>& element) override;
865 //! @brief Visit element B.
866 //! @param element - element to be visited
867 void visitElementB(const std::shared_ptr<ConcreteElementB>& element) override;
868};
869
870//! @brief Implement the accept operation that takes a visitor as an argument.
871class Element
872{
873public:
874 //! @brief Construct a new Element object.
875 Element() = default;
876 //! @brief Destroy the Element object.
877 virtual ~Element() = default;
878 //! @brief Construct a new Element object.
879 Element(const Element&) = default;
880 //! @brief Construct a new Element object.
881 Element(Element&&) noexcept = default;
882 //! @brief The operator (=) overloading of Element class.
883 //! @return reference of the Element object
884 Element& operator=(const Element&) = default;
885 //! @brief The operator (=) overloading of Element class.
886 //! @return reference of the Element object
887 Element& operator=(Element&&) noexcept = default;
888
889 //! @brief Accept visitor.
890 //! @param visitor - visitor to be accepted
891 virtual void accept(Visitor& visitor) = 0;
892};
893
894//! @brief The concrete element.
895class ConcreteElementA : public Element, public std::enable_shared_from_this<ConcreteElementA>
896{
897public:
898 //! @brief Accept visitor.
899 //! @param visitor - visitor to be accepted
900 void accept(Visitor& visitor) override;
901};
902
903//! @brief The concrete element.
904class ConcreteElementB : public Element, public std::enable_shared_from_this<ConcreteElementB>
905{
906public:
907 //! @brief Accept visitor.
908 //! @param visitor - visitor to be accepted
909 void accept(Visitor& visitor) override;
910};
911
912extern std::ostringstream& output() noexcept;
913} // namespace visitor
914} // namespace behavioral
915} // namespace design_pattern
916